From f5e248b5d3250f72e3665ba93e5dfbe7c8eb104b Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 22 Jun 2023 19:17:59 +0200 Subject: [PATCH 01/16] build: Construct recv object list in Makefile. para_recv is always built, which makes the patch comparably small. --- Makefile.in | 1 - Makefile.real | 23 +++++++++++++++++++++++ configure.ac | 33 --------------------------------- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/Makefile.in b/Makefile.in index 75996d9a..d46bbbdb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,7 +35,6 @@ HAVE_CURSES := @HAVE_CURSES@ executables := @executables@ -recv_objs := @recv_objs@ filter_objs := @filter_objs@ audioc_objs := @audioc_objs@ write_objs := @write_objs@ diff --git a/Makefile.real b/Makefile.real index 8f00f27c..5d715d0c 100644 --- a/Makefile.real +++ b/Makefile.real @@ -142,6 +142,29 @@ ifeq ($(HAVE_CURSES),yes) gui_objs := $(addsuffix .o, exec signal string stat ringbuffer fd \ gui gui_theme lsu time sched version) endif +recv_objs := $(addsuffix .o, \ + http_recv recv_common recv time string net dccp_recv fd sched stdout \ + udp_recv buffer_tree afh_recv afh_common wma_afh wma_common mp3_afh \ + version \ +) +ifeq ($(NEED_OGG_OBJECTS),yes) + recv_objs += ogg_afh_common.o +endif +ifeq ($(NEED_VORBIS_OBJECTS),yes) + recv_objs += ogg_afh.o +endif +ifeq ($(NEED_SPEEX_OBJECTS),yes) + recv_objs += spx_afh.o spx_common.o +endif +ifeq ($(NEED_OPUS_OBJECTS),yes) + recv_objs += opus_afh.o opus_common.o +endif +ifeq ($(NEED_FLAC_OBJECTS),yes) + recv_objs += flac_afh.o +endif +ifeq ($(HAVE_FAAD),yes) + recv_objs += aac_afh.o mp4.o +endif # sort removes duplicate words, which is all we need here all_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ diff --git a/configure.ac b/configure.ac index 64440600..135ef983 100644 --- a/configure.ac +++ b/configure.ac @@ -459,39 +459,6 @@ if test $HAVE_SAMPLERATE = yes; then filter_objs="$filter_objs resample_filter check_wav" fi AC_SUBST(filter_objs, add_dot_o($filter_objs)) -########################################################################## recv -recv_objs=" - http_recv - recv_common - recv - time - string - net - dccp_recv - fd - sched - stdout - udp_recv - buffer_tree - afh_recv - afh_common - wma_afh - wma_common - mp3_afh - version -" -AS_IF([test $NEED_OGG_OBJECTS = yes], [recv_objs="$recv_objs ogg_afh_common"]) -AS_IF([test $NEED_VORBIS_OBJECTS = yes], [recv_objs="$recv_objs ogg_afh"]) -AS_IF([test $NEED_SPEEX_OBJECTS = yes], - [recv_objs="$recv_objs spx_afh spx_common"]) -AS_IF([test $NEED_OPUS_OBJECTS = yes], - [recv_objs="$recv_objs opus_afh opus_common"]) -AS_IF([test $NEED_FLAC_OBJECTS = yes], [recv_objs="$recv_objs flac_afh"]) - -if test $HAVE_FAAD = yes; then - recv_objs="$recv_objs aac_afh mp4" -fi -AC_SUBST(recv_objs, add_dot_o($recv_objs)) ########################################################################### afh audio_format_handlers="mp3 wma" afh_objs=" -- 2.39.2 From ba8727c5857363c70f190ea98f92c41cd041e375 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 22 Jun 2023 19:26:10 +0200 Subject: [PATCH 02/16] build: Construct filter object list in Makefile. --- Makefile.in | 1 - Makefile.real | 28 ++++++++++++++++++++++++++++ configure.ac | 44 -------------------------------------------- 3 files changed, 28 insertions(+), 45 deletions(-) diff --git a/Makefile.in b/Makefile.in index d46bbbdb..9f6393b4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,7 +35,6 @@ HAVE_CURSES := @HAVE_CURSES@ executables := @executables@ -filter_objs := @filter_objs@ audioc_objs := @audioc_objs@ write_objs := @write_objs@ afh_objs := @afh_objs@ diff --git a/Makefile.real b/Makefile.real index 5d715d0c..2c7cff78 100644 --- a/Makefile.real +++ b/Makefile.real @@ -142,6 +142,34 @@ ifeq ($(HAVE_CURSES),yes) gui_objs := $(addsuffix .o, exec signal string stat ringbuffer fd \ gui gui_theme lsu time sched version) endif +filter_objs := $(addsuffix .o, \ + filter_common wav_filter compress_filter filter string stdin stdout \ + sched fd amp_filter fecdec_filter fec lsu version prebuffer_filter \ + time bitstream imdct wma_common wmadec_filter buffer_tree net \ + sync_filter \ +) +ifeq ($(NEED_VORBIS_OBJECTS),yes) + filter_objs += oggdec_filter.o +endif +ifeq ($(NEED_SPEEX_OBJECTS),yes) + filter_objs += spxdec_filter.o spx_common.o +endif +ifeq ($(NEED_OPUS_OBJECTS),yes) + filter_objs += opusdec_filter.o opus_common.o +endif +ifeq ($(NEED_FLAC_OBJECTS),yes) + filter_objs += flacdec_filter.o +endif +ifeq ($(HAVE_FAAD),yes) + filter_objs += aacdec_filter.o +endif +ifeq ($(HAVE_MAD),yes) + filter_objs += mp3dec_filter.o +endif +ifeq ($(HAVE_SAMPLERATE),yes) + filter_objs += resample_filter.o check_wav.o +endif + recv_objs := $(addsuffix .o, \ http_recv recv_common recv time string net dccp_recv fd sched stdout \ udp_recv buffer_tree afh_recv afh_common wma_afh wma_common mp3_afh \ diff --git a/configure.ac b/configure.ac index 135ef983..8ea488c2 100644 --- a/configure.ac +++ b/configure.ac @@ -415,50 +415,6 @@ if test $HAVE_CURSES = yes; then build_gui="yes" executables="$executables gui" fi -######################################################################## filter -filter_objs=" - filter_common - wav_filter - compress_filter - filter - string - stdin - stdout - sched - fd - amp_filter - fecdec_filter - fec - lsu - version - prebuffer_filter - time - bitstream - imdct - wma_common - wmadec_filter - buffer_tree - net - sync_filter -" -AS_IF([test $NEED_VORBIS_OBJECTS = yes], - [filter_objs="$filter_objs oggdec_filter"]) -AS_IF([test $NEED_SPEEX_OBJECTS = yes], - [filter_objs="$filter_objs spxdec_filter spx_common"]) -AS_IF([test $NEED_OPUS_OBJECTS = yes], - [filter_objs="$filter_objs opusdec_filter opus_common"]) -AS_IF([test $NEED_FLAC_OBJECTS = yes], - [filter_objs="$filter_objs flacdec_filter"]) -if test $HAVE_FAAD = yes; then - filter_objs="$filter_objs aacdec_filter" -fi -if test $HAVE_MAD = yes; then - filter_objs="$filter_objs mp3dec_filter" -fi -if test $HAVE_SAMPLERATE = yes; then - filter_objs="$filter_objs resample_filter check_wav" -fi -AC_SUBST(filter_objs, add_dot_o($filter_objs)) ########################################################################### afh audio_format_handlers="mp3 wma" afh_objs=" -- 2.39.2 From 5fd6c1a5acae2a52545e081ac4b38717c7295d80 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Jun 2023 11:02:38 +0200 Subject: [PATCH 03/16] build: Construct afh object list in Makefile. --- Makefile.in | 1 - Makefile.real | 29 +++++++++++++++++++++++++++++ configure.ac | 38 -------------------------------------- 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9f6393b4..4529779b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -37,7 +37,6 @@ executables := @executables@ audioc_objs := @audioc_objs@ write_objs := @write_objs@ -afh_objs := @afh_objs@ play_objs := @play_objs@ speex_cppflags := @speex_cppflags@ diff --git a/Makefile.real b/Makefile.real index 2c7cff78..6ab2065c 100644 --- a/Makefile.real +++ b/Makefile.real @@ -194,6 +194,33 @@ ifeq ($(HAVE_FAAD),yes) recv_objs += aac_afh.o mp4.o endif +audio_format_handlers := mp3 wma +afh_objs := $(addsuffix .o, afh string fd mp3_afh afh_common time wma_afh \ + wma_common version) +ifeq ($(NEED_OGG_OBJECTS),yes) + afh_objs += ogg_afh_common.o +endif +ifeq ($(NEED_VORBIS_OBJECTS),yes) + afh_objs += ogg_afh.o + audio_format_handlers += ogg +endif +ifeq ($(NEED_SPEEX_OBJECTS),yes) + afh_objs += spx_common.o + audio_format_handlers += spx +endif +ifeq ($(NEED_OPUS_OBJECTS),yes) + afh_objs += opus_afh.o opus_common.o + audio_format_handlers += opus +endif +ifeq ($(NEED_FLAC_OBJECTS),yes) + afh_objs += flac_afh.o + audio_format_handlers += flac +endif +ifeq ($(HAVE_FAAD),yes) + afh_objs += aac_afh.o mp4.o + audio_format_handlers += aac +endif + # sort removes duplicate words, which is all we need here all_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ $(audiod_objs) $(audioc_objs) $(mixer_objs) $(server_objs) \ @@ -358,6 +385,8 @@ OD = $(addsuffix .d, $(addprefix $(dep_dir)/, $(1))) \ $(call OD, audiod): \ CPPFLAGS += -DAUDIOD_AUDIO_FORMAT_ARRAY='$(audiod_audio_formats)' +$(call OD, afh command): \ + CPPFLAGS += -DAUDIO_FORMAT_HANDLERS='"$(audio_format_handlers)"' $(call OD, opus%): CPPFLAGS += $(opus_cppflags) $(call OD, gui gui%): CPPFLAGS += $(curses_cppflags) $(call OD, spx%): CPPFLAGS += $(speex_cppflags) diff --git a/configure.ac b/configure.ac index 8ea488c2..6d42f87b 100644 --- a/configure.ac +++ b/configure.ac @@ -415,41 +415,6 @@ if test $HAVE_CURSES = yes; then build_gui="yes" executables="$executables gui" fi -########################################################################### afh -audio_format_handlers="mp3 wma" -afh_objs=" - afh - string - fd - mp3_afh - afh_common - time - wma_afh - wma_common - version -" -AS_IF([test $NEED_OGG_OBJECTS = yes], [afh_objs="$afh_objs ogg_afh_common"]) -AS_IF([test $NEED_VORBIS_OBJECTS = yes], [ - afh_objs="$afh_objs ogg_afh" - audio_format_handlers="$audio_format_handlers ogg" -]) -AS_IF([test $NEED_SPEEX_OBJECTS = yes], [ - afh_objs="$afh_objs spx_afh spx_common" - audio_format_handlers="$audio_format_handlers spx" -]) -AS_IF([test $NEED_OPUS_OBJECTS = yes], [ - afh_objs="$afh_objs opus_afh opus_common" - audio_format_handlers="$audio_format_handlers opus" -]) -AS_IF([test $NEED_FLAC_OBJECTS = yes], [ - afh_objs="$afh_objs flac_afh" - audio_format_handlers="$audio_format_handlers flac" -]) -if test $HAVE_FAAD = yes; then - afh_objs="$afh_objs aac_afh mp4" - audio_format_handlers="$audio_format_handlers aac" -fi -AC_SUBST(afh_objs, add_dot_o($afh_objs)) ########################################################################## play play_objs=" play @@ -559,8 +524,6 @@ if test $HAVE_READLINE = yes; then fi AC_SUBST(audioc_objs, add_dot_o($audioc_objs)) -AC_DEFINE_UNQUOTED(AUDIO_FORMAT_HANDLERS, "$audio_format_handlers", - [formats supported by para_server and para_afh]) AC_SUBST(executables) AC_OUTPUT @@ -571,7 +534,6 @@ crypto lib: ${CRYPTOLIB:-[none]} readline (interactive CLIs): $HAVE_READLINE id3 version 2 support: $HAVE_ID3TAG faad: $HAVE_FAAD -audio format handlers: $audio_format_handlers exe: $executables para_server: $build_server -- 2.39.2 From cb1c4447e53a71a7fd5ece3d3ad416e3a6951566 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Jun 2023 14:35:25 +0200 Subject: [PATCH 04/16] build: Construct play object list in Makefile. --- Makefile.in | 1 - Makefile.real | 44 ++++++++++++++++++++++++++++++++++ configure.ac | 65 --------------------------------------------------- 3 files changed, 44 insertions(+), 66 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4529779b..a01e8cf1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -37,7 +37,6 @@ executables := @executables@ audioc_objs := @audioc_objs@ write_objs := @write_objs@ -play_objs := @play_objs@ speex_cppflags := @speex_cppflags@ opus_cppflags := @opus_cppflags@ diff --git a/Makefile.real b/Makefile.real index 6ab2065c..50b9ee5b 100644 --- a/Makefile.real +++ b/Makefile.real @@ -221,6 +221,50 @@ ifeq ($(HAVE_FAAD),yes) audio_format_handlers += aac endif +play_objs := $(addsuffix .o, \ + play fd sched 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 version sync_filter lsu \ +) +ifeq ($(NEED_OGG_OBJECTS),yes) + play_objs += ogg_afh_common.o +endif +ifeq ($(NEED_VORBIS_OBJECTS),yes) + play_objs += oggdec_filter.o ogg_afh.o +endif +ifeq ($(NEED_SPEEX_OBJECTS),yes) + play_objs += spxdec_filter.o spx_afh.o spx_common.o +endif +ifeq ($(NEED_OPUS_OBJECTS),yes) + play_objs += opusdec_filter.o opus_afh.o opus_common.o +endif +ifeq ($(NEED_FLAC_OBJECTS),yes) + play_objs += flacdec_filter.o flac_afh.o +endif +ifeq ($(HAVE_FAAD),yes) + play_objs += aac_afh.o aacdec_filter.o mp4.o +endif +ifeq ($(HAVE_MAD),yes) + play_objs += mp3dec_filter.o +endif +ifeq ($(HAVE_OSS),yes) + play_objs += oss_write.o +endif +ifeq ($(HAVE_ALSA),yes) + play_objs += alsa_write.o +endif +ifeq ($(NEED_AO_OBJECTS),yes) + play_objs += ao_write.o +endif +ifeq ($(HAVE_READLINE),yes) + play_objs += interactive.o +endif +ifeq ($(HAVE_SAMPLERATE),yes) + play_objs += resample_filter.o check_wav.o +endif + # sort removes duplicate words, which is all we need here all_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ $(audiod_objs) $(audioc_objs) $(mixer_objs) $(server_objs) \ diff --git a/configure.ac b/configure.ac index 6d42f87b..124dda7d 100644 --- a/configure.ac +++ b/configure.ac @@ -415,71 +415,6 @@ if test $HAVE_CURSES = yes; then build_gui="yes" executables="$executables gui" fi -########################################################################## play -play_objs=" - play - fd - sched - 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 - version - sync_filter - lsu -" -AS_IF([test $NEED_OGG_OBJECTS = yes], [play_objs="$play_objs ogg_afh_common"]) -AS_IF([test $NEED_VORBIS_OBJECTS = yes], - [play_objs="$play_objs oggdec_filter ogg_afh"]) -AS_IF([test $NEED_SPEEX_OBJECTS = yes], - [play_objs="$play_objs spxdec_filter spx_afh spx_common"]) -AS_IF([test $NEED_OPUS_OBJECTS = yes], - [play_objs="$play_objs opusdec_filter opus_afh opus_common"]) -AS_IF([test $NEED_FLAC_OBJECTS = yes], - [play_objs="$play_objs flacdec_filter flac_afh"]) -if test $HAVE_FAAD = yes; then - play_objs="$play_objs aac_afh aacdec_filter mp4" -fi -if test $HAVE_MAD = yes; then - play_objs="$play_objs mp3dec_filter" -fi -if test $HAVE_OSS = yes; then - play_objs="$play_objs oss_write" -fi -if test $HAVE_ALSA = yes; then - play_objs="$play_objs alsa_write" -fi -if test $NEED_AO_OBJECTS = yes; then - play_objs="$play_objs ao_write" -fi -if test $HAVE_READLINE = yes; then - play_objs="$play_objs interactive" -fi -if test $HAVE_SAMPLERATE = yes; then - play_objs="$play_objs resample_filter check_wav" -fi -AC_SUBST(play_objs, add_dot_o($play_objs)) ######################################################################### write write_objs=" write -- 2.39.2 From 195357a1ff778e24feb88ce4cf6c130a9200ebe3 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Jun 2023 19:34:21 +0200 Subject: [PATCH 05/16] build: Construct write object list in Makefile. --- Makefile.in | 1 - Makefile.real | 13 +++++++++++++ configure.ac | 25 ------------------------- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/Makefile.in b/Makefile.in index a01e8cf1..5ee52deb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -36,7 +36,6 @@ HAVE_CURSES := @HAVE_CURSES@ executables := @executables@ audioc_objs := @audioc_objs@ -write_objs := @write_objs@ speex_cppflags := @speex_cppflags@ opus_cppflags := @opus_cppflags@ diff --git a/Makefile.real b/Makefile.real index 50b9ee5b..67107744 100644 --- a/Makefile.real +++ b/Makefile.real @@ -265,6 +265,19 @@ ifeq ($(HAVE_SAMPLERATE),yes) play_objs += resample_filter.o check_wav.o endif +write_objs := $(addsuffix .o, write write_common file_write time fd \ + string sched stdin buffer_tree check_wav version) +ifeq ($(NEED_AO_OBJECTS),yes) + write_objs += ao_write.o +endif +ifeq ($(HAVE_OSS),yes) + write_objs += oss_write.o +endif +ifeq ($(HAVE_ALSA),yes) + write_objs += alsa_write.o +endif + + # sort removes duplicate words, which is all we need here all_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ $(audiod_objs) $(audioc_objs) $(mixer_objs) $(server_objs) \ diff --git a/configure.ac b/configure.ac index 124dda7d..5906f69e 100644 --- a/configure.ac +++ b/configure.ac @@ -415,31 +415,6 @@ if test $HAVE_CURSES = yes; then build_gui="yes" executables="$executables gui" fi -######################################################################### write -write_objs=" - write - write_common - file_write - time - fd - string - sched - stdin - buffer_tree - check_wav - version -" - -if test $NEED_AO_OBJECTS = yes; then - write_objs="$write_objs ao_write" -fi -if test $HAVE_OSS = yes; then - write_objs="$write_objs oss_write" -fi -if test $HAVE_ALSA = yes; then - write_objs="$write_objs alsa_write" -fi -AC_SUBST(write_objs, add_dot_o($write_objs)) ######################################################################## audioc audioc_objs=" audioc -- 2.39.2 From 142ee7011b66ad76e7a3be47ccd9e9ab24d7f174 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Jun 2023 19:34:56 +0200 Subject: [PATCH 06/16] build: Construct audioc object list in Makefile. This removes the last caller of add_dot_o() in configure.ac, so remove this function. --- Makefile.in | 2 -- Makefile.real | 4 ++++ configure.ac | 19 ------------------- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/Makefile.in b/Makefile.in index 5ee52deb..6e732500 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,8 +35,6 @@ HAVE_CURSES := @HAVE_CURSES@ executables := @executables@ -audioc_objs := @audioc_objs@ - speex_cppflags := @speex_cppflags@ opus_cppflags := @opus_cppflags@ vorbis_cppflags := @vorbis_cppflags@ diff --git a/Makefile.real b/Makefile.real index 67107744..1d671dbe 100644 --- a/Makefile.real +++ b/Makefile.real @@ -277,6 +277,10 @@ ifeq ($(HAVE_ALSA),yes) write_objs += alsa_write.o endif +audioc_objs := $(addsuffix .o, audioc string lsu net fd time version) +ifeq ($(HAVE_READLINE),yes) + audioc_objs += buffer_tree.o interactive.o sched.o +endif # sort removes duplicate words, which is all we need here all_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ diff --git a/configure.ac b/configure.ac index 5906f69e..97fcafc6 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,6 @@ AC_INIT([paraslash], [m4_esyscmd_s(./GIT-VERSION-GEN)], AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) -AC_DEFUN([add_dot_o],[$(for i in $@; do printf "$i.o "; done)]) AC_DEFUN([LIB_ARG_WITH], [ AC_ARG_WITH($1-headers, [AS_HELP_STRING(--with-$1-headers=dir, [look for $1 headers in dir])]) @@ -416,24 +415,6 @@ if test $HAVE_CURSES = yes; then executables="$executables gui" fi ######################################################################## audioc -audioc_objs=" - audioc - string - lsu - net - fd - time - version -" -if test $HAVE_READLINE = yes; then - audioc_objs="$audioc_objs - buffer_tree - interactive - sched - " -fi -AC_SUBST(audioc_objs, add_dot_o($audioc_objs)) - AC_SUBST(executables) AC_OUTPUT -- 2.39.2 From b1684c15322f08a51bb81fb1b7268887225751f8 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Jun 2023 21:36:17 +0200 Subject: [PATCH 07/16] build: Construct list of executables in Makefile. This is actually easier and removes some duplication as we currently have two copies of the logic which decides whether or not to build each executable. We lose the summary output at the end of the configure output, but that was incomplete anyway. --- Makefile.in | 2 -- Makefile.real | 7 ++++++- configure.ac | 49 ------------------------------------------------- 3 files changed, 6 insertions(+), 52 deletions(-) diff --git a/Makefile.in b/Makefile.in index 6e732500..396c8de6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -33,8 +33,6 @@ HAVE_OSS := @HAVE_OSS@ HAVE_ALSA := @HAVE_ALSA@ HAVE_CURSES := @HAVE_CURSES@ -executables := @executables@ - speex_cppflags := @speex_cppflags@ opus_cppflags := @opus_cppflags@ vorbis_cppflags := @vorbis_cppflags@ diff --git a/Makefile.real b/Makefile.real index 1d671dbe..117d72fa 100644 --- a/Makefile.real +++ b/Makefile.real @@ -14,7 +14,6 @@ SEVERITIES := \"debug\",\"info\",\"notice\",\"warning\",\"error\",\"crit\",\"eme vardir := /var/paraslash mandir := $(datarootdir)/man/man1 MKDIR_P := mkdir -p -prefixed_executables := $(addprefix para_, $(executables)) build_date := $(shell date) uname_s := $(shell uname -s 2>/dev/null || echo "UNKNOWN_OS") @@ -38,8 +37,10 @@ test_dir := t yy_src_dir := yy yy_build_dir := $(build_dir)/yy +executables := recv filter audioc write afh play ifneq ($(CRYPTOLIB),) ifeq ($(HAVE_OSL),yes) + executables += server upgrade_db server_objs := $(addsuffix .o, \ server afh_common mp3_afh vss command net string \ signal time daemon http_send close_on_fork \ @@ -76,6 +77,7 @@ ifneq ($(CRYPTOLIB),) endif endif ifneq ($(CRYPTOLIB),) + executables += client audiod client_objs := $(addsuffix .o, \ client net string fd lsu sched stdin stdout time sideband client_common \ buffer_tree crypt_common base64 version $(CRYPTOLIB) \ @@ -130,6 +132,7 @@ ifneq ($(CRYPTOLIB),) endif endif ifneq ($(HAVE_OSS)-$(HAVE_ALSA),no-no) + executables += mixer mixer_objs := $(addsuffix .o, mixer exec string fd time lsu version) ifeq ($(HAVE_OSS),yes) mixer_objs += oss_mix.o @@ -139,6 +142,7 @@ ifneq ($(HAVE_OSS)-$(HAVE_ALSA),no-no) endif endif ifeq ($(HAVE_CURSES),yes) + executables += gui gui_objs := $(addsuffix .o, exec signal string stat ringbuffer fd \ gui gui_theme lsu time sched version) endif @@ -328,6 +332,7 @@ write_objs := $(addprefix $(object_dir)/, $(write_objs)) afh_objs := $(addprefix $(object_dir)/, $(afh_objs)) play_objs := $(addprefix $(object_dir)/, $(play_objs)) +prefixed_executables := $(addprefix para_, $(executables)) man_pages := $(patsubst %, $(man_dir)/%.1, $(prefixed_executables)) autocrap := config.h.in configure diff --git a/configure.ac b/configure.ac index 97fcafc6..4f9f4b54 100644 --- a/configure.ac +++ b/configure.ac @@ -61,7 +61,6 @@ REQUIRE_EXECUTABLE([bison]) REQUIRE_EXECUTABLE([flex]) REQUIRE_EXECUTABLE([m4]) -executables="recv filter audioc write afh play" ########################################################################### osl STASH_FLAGS LIB_ARG_WITH([osl], [-losl]) @@ -383,53 +382,5 @@ AC_ARG_ENABLE([ubsan], [AS_HELP_STRING(--enable-ubsan, [Detect and report undefined behaviour.])], [ENABLE_UBSAN=yes], [ENABLE_UBSAN=no]) AC_SUBST(ENABLE_UBSAN) -######################################################### server and upgrade_db -if test -n "$CRYPTOLIB" && test $HAVE_OSL = yes; then - build_server="yes" - executables="$executables server upgrade_db" -else - build_server="no" -fi -############################################################# client -if test -n "$CRYPTOLIB"; then - build_client="yes" - executables="$executables client" -else - build_client="no" -fi -############################################################# audiod -if test -n "$CRYPTOLIB"; then - build_audiod="yes" - executables="$executables audiod" -else - build_audiod="no" -fi -########################################################################### mixer -if test $HAVE_OSS = yes -o $HAVE_ALSA = yes; then - build_mixer="yes" - executables="$executables mixer" -fi -########################################################################### gui -if test $HAVE_CURSES = yes; then - build_gui="yes" - executables="$executables gui" -fi -######################################################################## audioc -AC_SUBST(executables) AC_OUTPUT -AC_MSG_NOTICE([ -paraslash configuration: -~~~~~~~~~~~~~~~~~~~~~~~~ -crypto lib: ${CRYPTOLIB:-[none]} -readline (interactive CLIs): $HAVE_READLINE -id3 version 2 support: $HAVE_ID3TAG -faad: $HAVE_FAAD - -exe: $executables -para_server: $build_server -para_gui: $build_gui -para_mixer: $build_mixer -para_client: $build_client -para_audiod: $build_audiod -]) -- 2.39.2 From a18458cff51c55e3b7f502042a6483410d1c452d Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Jun 2023 22:53:32 +0200 Subject: [PATCH 08/16] build: No longer check for CRYPTO_cleanup_all_ex_data(). Recent openssl versions no longer declare this unless the openssl API compatibility version is set explicitly, in which case it gets defined as a macro which does nothing. Either way, the check in configure.ac and the call in openssl.c can go away. --- configure.ac | 9 --------- openssl.c | 3 --- 2 files changed, 12 deletions(-) diff --git a/configure.ac b/configure.ac index 4f9f4b54..34dcd060 100644 --- a/configure.ac +++ b/configure.ac @@ -109,15 +109,6 @@ if test $HAVE_OPENSSL = yes; then will be removed in the next major paraslash release. Please upgrade your openssl installation.]) fi - HAVE_CRYPTO_CLEANUP_ALL_EX_DATA=yes - AC_CHECK_DECL([CRYPTO_cleanup_all_ex_data], [], - [HAVE_CRYPTO_CLEANUP_ALL_EX_DATA=no], - [#include ]) - AC_CHECK_LIB([crypto], [CRYPTO_cleanup_all_ex_data], [], - [HAVE_CRYPTO_CLEANUP_ALL_EX_DATA=no]) - test $HAVE_CRYPTO_CLEANUP_ALL_EX_DATA = yes && - AC_DEFINE([HAVE_CRYPTO_CLEANUP_ALL_EX_DATA], [1], - [not available on FreeBSD 12]) HAVE_OPENSSL_THREAD_STOP=yes AC_CHECK_DECL([OPENSSL_thread_stop], [], [HAVE_OPENSSL_THREAD_STOP=no], diff --git a/openssl.c b/openssl.c index f696cd9e..13550e7a 100644 --- a/openssl.c +++ b/openssl.c @@ -54,9 +54,6 @@ void crypt_init(void) void crypt_shutdown(void) { -#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA - CRYPTO_cleanup_all_ex_data(); -#endif #ifdef HAVE_OPENSSL_THREAD_STOP /* openssl-1.1 or later */ OPENSSL_thread_stop(); #else /* openssl-1.0 */ -- 2.39.2 From 479aa2726ef127a1d6c492d49f7a4cddf279be0a Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Jun 2023 23:10:09 +0200 Subject: [PATCH 09/16] build: Rename all_objs -> dep_objs. The old name is misleading since there are additional objects which correspond to the C files generated by lopsub. Those use different dependency tracking. Simplify the code a bit by creating the list in one step. --- Makefile.real | 7 +++---- t/makefile.test | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Makefile.real b/Makefile.real index 117d72fa..92a5724b 100644 --- a/Makefile.real +++ b/Makefile.real @@ -287,11 +287,10 @@ ifeq ($(HAVE_READLINE),yes) endif # sort removes duplicate words, which is all we need here -all_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ +dep_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \ $(audiod_objs) $(audioc_objs) $(mixer_objs) $(server_objs) \ - $(write_objs) $(afh_objs) $(play_objs)) -deps := $(addprefix $(dep_dir)/, $(all_objs:.o=.d)) -deps += $(addprefix $(dep_dir)/, mp.bison.d mp.flex.d) + $(write_objs) $(afh_objs) $(play_objs) mp.bison mp.flex) +deps := $(addprefix $(dep_dir)/, $(dep_objs:.o=.d)) afh_objs += afh.lsg.o audioc_objs += audioc.lsg.o diff --git a/t/makefile.test b/t/makefile.test index 904c7793..1ef3ac69 100644 --- a/t/makefile.test +++ b/t/makefile.test @@ -7,7 +7,7 @@ test_options := --executables-dir $(shell pwd) test_options += --results-dir $(results_dir) test_options += --trash-dir $(trash_dir) test_options += --executables "$(prefixed_executables)" -test_options += --objects "$(basename $(all_objs))" +test_options += --objects "$(basename $(dep_objs))" test_options += --man-dir $(man_dir) ifdef V -- 2.39.2 From 0f8a8423c94cf0edba1e077a3b0e90f2b0b99edc Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 20 Mar 2024 23:32:24 +0100 Subject: [PATCH 10/16] ipc: Remove pointless initialization in shm_get_shmmax(). The subsequent read() call overwrites the buffer. --- ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc.c b/ipc.c index 8e9dd51a..c245f690 100644 --- a/ipc.c +++ b/ipc.c @@ -218,7 +218,7 @@ size_t shm_get_shmmax(void) { int fd = open("/proc/sys/kernel/shmmax", O_RDONLY); if (fd >= 0) { - char buf[100] = ""; + char buf[100]; int ret = read(fd, buf, sizeof(buf) - 1); if (ret > 0) { buf[ret] = '\0'; -- 2.39.2 From 824809dcdf32f93aa841fadbd62e8b2475768d40 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 21 Mar 2024 12:39:06 +0100 Subject: [PATCH 11/16] client: Fix memory leak on exit. This triggers only if para_client is run interactively. The leak is harmless, but still.. --- client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client.c b/client.c index 84b7580c..d2d11fd3 100644 --- a/client.c +++ b/client.c @@ -549,6 +549,7 @@ __noreturn static void interactive_session(void) i9e_close(); para_log = stderr_log; out: + free(ici.history_file); if (ret < 0) PARA_ERROR_LOG("%s\n", para_strerror(-ret)); exit(ret < 0? EXIT_FAILURE : EXIT_SUCCESS); -- 2.39.2 From 76f5f13b1216c4579eae6c9e1d142a6c929ee196 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Fri, 30 Dec 2022 14:08:00 +0100 Subject: [PATCH 12/16] Speed up mp3dec filter. Avoid calling btr_get_input_queue_size() as this is potentially expensive (depending on the number of chunks in the input queue) and unnecessary. The user time of para_play for a ~4m long mp3 file on a very slow machine went down from 168s to 150s. Speedup: 11% --- mp3dec_filter.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mp3dec_filter.c b/mp3dec_filter.c index d40df85e..cf3e5d4b 100644 --- a/mp3dec_filter.c +++ b/mp3dec_filter.c @@ -79,12 +79,11 @@ static int mp3dec_post_monitor(__a_unused struct sched *s, void *context) int i, ret; struct private_mp3dec_data *pmd = fn->private_data; struct btr_node *btrn = fn->btrn; - size_t loaded = 0, len, iqs; + size_t loaded = 0, len; char *inbuffer, *outbuffer; next_buffer: pmd->stream.error = 0; - iqs = btr_get_input_queue_size(btrn); ret = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL); if (ret < 0) goto err; @@ -104,7 +103,7 @@ next_frame: if (ret < 0) { mp3dec_consume(btrn, &pmd->stream, len); if (pmd->stream.error == MAD_ERROR_BUFLEN) { - if (len == iqs && btr_no_parent(btrn)) { + if (fn->min_iqs > 0 && btr_no_parent(btrn)) { ret = -E_EOF; goto err; } @@ -128,7 +127,7 @@ decode: mad_stream_sync(&pmd->stream); if (pmd->stream.error == MAD_ERROR_BUFLEN) { ret = -E_EOF; - if (len == iqs && btr_no_parent(btrn)) + if (btr_no_parent(btrn)) goto err; fn->min_iqs += 100; ret = -E_MP3DEC_CORRUPT; -- 2.39.2 From db654ceb7ced70cdd133c547196b3de4207e3112 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Fri, 30 Dec 2022 14:09:06 +0100 Subject: [PATCH 13/16] btr: Speed up btr_node_status(). Currently we sum up the sizes of all buffers in the input queue just to determine if the total size exceeds a small threshold. That's silly and expensive if there are many buffers. Fix that by introducing a helper which breaks out of the loop as soon as know the answer because the threshold is exceeded. User time: 150s -> 147s, speedup: 2% --- buffer_tree.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/buffer_tree.c b/buffer_tree.c index 35353f56..5d97f86f 100644 --- a/buffer_tree.c +++ b/buffer_tree.c @@ -833,6 +833,22 @@ size_t btr_get_input_queue_size(struct btr_node *btrn) return size; } +static bool min_iqs_available(size_t min_iqs, struct btr_node *btrn) +{ + struct btr_buffer_reference *br; + size_t have = 0, wrap_consumed = 0; + + FOR_EACH_BUFFER_REF(br, btrn) { + if (br->wrap_count != 0) { + wrap_consumed = br->consumed; + continue; + } + have += br_available_bytes(br); + if (have > wrap_consumed + min_iqs) + return true; + } + return false; +} /** * Remove a node from the buffer tree, reconnecting parent and children. * @@ -1202,9 +1218,6 @@ struct btr_node *btr_search_node(const char *name, struct btr_node *root) int btr_node_status(struct btr_node *btrn, size_t min_iqs, enum btr_node_type type) { - size_t iqs; - - assert(btrn); if (type != BTR_NT_LEAF && btr_no_children(btrn)) return -E_BTR_NO_CHILD; if (type != BTR_NT_ROOT && btr_eof(btrn)) @@ -1214,12 +1227,9 @@ int btr_node_status(struct btr_node *btrn, size_t min_iqs, return 0; if (type == BTR_NT_ROOT) return 1; - iqs = btr_get_input_queue_size(btrn); - if (iqs == 0) /* we have a parent, because not eof */ - return 0; - if (iqs < min_iqs && !btr_no_parent(btrn)) - return 0; - return 1; + if (min_iqs_available(min_iqs, btrn)) + return 1; + return btr_no_parent(btrn); } /** -- 2.39.2 From f64cbcc034844628b7e7817e27205cc6b48e9a18 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Fri, 30 Dec 2022 14:09:51 +0100 Subject: [PATCH 14/16] btr: Merge buffers on insertion. Currently add_btrb_to_children() simply adds the given buffer reference to the input queue of all children of the given node even if the newly added buffer reference points memory adjacent to the previously added buffer. Since several helpers iterate over all buffer references, performance suffers, given enough buffer references. So merge buffers when possible. User time: 147s -> 83s, speedup: 44%. --- buffer_tree.c | 38 +++++++++++++++++++++++++++++++++----- list.h | 2 ++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/buffer_tree.c b/buffer_tree.c index 5d97f86f..36a7e6e1 100644 --- a/buffer_tree.c +++ b/buffer_tree.c @@ -330,6 +330,14 @@ static struct btr_buffer_reference *get_first_input_br(struct btr_node *btrn) struct btr_buffer_reference, node); } +static struct btr_buffer_reference *get_last_input_br(struct btr_node *btrn) +{ + if (list_empty(&btrn->input_queue)) + return NULL; + return list_last_entry(&btrn->input_queue, + struct btr_buffer_reference, node); +} + /* * Deallocate the reference, release the resources if refcount drops to zero. */ @@ -346,6 +354,20 @@ static void btr_drop_buffer_reference(struct btr_buffer_reference *br) } } +static bool may_merge_btrb(const struct btr_buffer *btrb, + const struct btr_buffer_reference *br) +{ + if (!br) + return false; + if (br->consumed > 0) + return false; + if (br->btrb->buf + br->btrb->size != btrb->buf) + return false; + if (!br->btrb->pool) + return true; + return br->btrb->size + btrb->size < btr_pool_size(br->btrb->pool) / 3; +} + static void add_btrb_to_children(struct btr_buffer *btrb, struct btr_node *btrn, size_t consumed) { @@ -354,11 +376,17 @@ static void add_btrb_to_children(struct btr_buffer *btrb, if (btrn->start.tv_sec == 0) btrn->start = *now; FOR_EACH_CHILD(ch, btrn) { - struct btr_buffer_reference *br = zalloc(sizeof(*br)); - br->btrb = btrb; - br->consumed = consumed; - list_add_tail(&br->node, &ch->input_queue); - btrb->refcount++; + struct btr_buffer_reference *br = get_last_input_br(ch); + if (may_merge_btrb(btrb, br)) { + br->btrb->size += btrb->size; + free(btrb); + } else { + br = zalloc(sizeof(*br)); + br->btrb = btrb; + br->consumed = consumed; + list_add_tail(&br->node, &ch->input_queue); + btrb->refcount++; + } if (ch->start.tv_sec == 0) ch->start = *now; } diff --git a/list.h b/list.h index 78c302fa..82f5b36d 100644 --- a/list.h +++ b/list.h @@ -161,3 +161,5 @@ static inline int list_is_singular(const struct list_head *head) */ #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) -- 2.39.2 From 4dfa81fee689335545bd16322cad6dbf84faa748 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 2 Jan 2023 14:43:42 +0100 Subject: [PATCH 15/16] Constify buffer tree API. A lot of functions of the buffer tree API don't modify the memory referenced by the pointers passed. This patch marks these pointer arguments as constant. --- aacdec_filter.c | 3 ++- afh_recv.c | 2 +- buffer_tree.c | 56 ++++++++++++++++++++++++----------------------- buffer_tree.h | 36 +++++++++++++++--------------- check_wav.c | 2 +- flacdec_filter.c | 2 +- mp3dec_filter.c | 3 ++- oggdec_filter.c | 3 ++- opusdec_filter.c | 2 +- resample_filter.c | 3 ++- spxdec_filter.c | 2 +- wmadec_filter.c | 3 ++- 12 files changed, 62 insertions(+), 55 deletions(-) diff --git a/aacdec_filter.c b/aacdec_filter.c index 87a7900a..ab07be8f 100644 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@ -41,7 +41,8 @@ struct private_aacdec_data { unsigned int sample_rate; }; -static int aacdec_execute(struct btr_node *btrn, const char *cmd, char **result) +static int aacdec_execute(const struct btr_node *btrn, const char *cmd, + char **result) { struct filter_node *fn = btr_context(btrn); struct private_aacdec_data *padd = fn->private_data; diff --git a/afh_recv.c b/afh_recv.c index 8449e787..687b77d9 100644 --- a/afh_recv.c +++ b/afh_recv.c @@ -30,7 +30,7 @@ struct private_afh_recv_data { void *afh_context; }; -static int afh_execute(struct btr_node *btrn, const char *cmd, char **result) +static int afh_execute(const struct btr_node *btrn, const char *cmd, char **result) { struct receiver_node *rn = btr_context(btrn); struct private_afh_recv_data *pard = rn->private_data; diff --git a/buffer_tree.c b/buffer_tree.c index 36a7e6e1..255dc475 100644 --- a/buffer_tree.c +++ b/buffer_tree.c @@ -103,12 +103,12 @@ void btr_pool_free(struct btr_pool *btrp) * \return The same value which was passed during creation time to * btr_pool_new(). */ -size_t btr_pool_size(struct btr_pool *btrp) +size_t btr_pool_size(const struct btr_pool *btrp) { return btrp->area_end - btrp->area_start; } -static size_t btr_pool_filled(struct btr_pool *btrp) +static size_t btr_pool_filled(const struct btr_pool *btrp) { if (!btrp->whead) return btr_pool_size(btrp); @@ -129,7 +129,7 @@ static size_t btr_pool_filled(struct btr_pool *btrp) * the largest contiguous buffer that can currently be allocated from the * buffer pool. */ -size_t btr_pool_unused(struct btr_pool *btrp) +size_t btr_pool_unused(const struct btr_pool *btrp) { return btr_pool_size(btrp) - btr_pool_filled(btrp); } @@ -138,7 +138,7 @@ size_t btr_pool_unused(struct btr_pool *btrp) * Return maximal size available for one read. This is * smaller than the value returned by btr_pool_unused(). */ -static size_t btr_pool_available(struct btr_pool *btrp) +static size_t btr_pool_available(const struct btr_pool *btrp) { if (!btrp->whead) return 0; @@ -156,7 +156,7 @@ static size_t btr_pool_available(struct btr_pool *btrp) * \return The maximal amount of bytes that may be written to the returned * buffer. */ -size_t btr_pool_get_buffer(struct btr_pool *btrp, char **result) +size_t btr_pool_get_buffer(const struct btr_pool *btrp, char **result) { if (result) *result = btrp->whead; @@ -174,7 +174,7 @@ size_t btr_pool_get_buffer(struct btr_pool *btrp, char **result) * consists of two buffers. If this function returns the value n, then n * elements of \a iov are initialized. */ -int btr_pool_get_buffers(struct btr_pool *btrp, struct iovec iov[2]) +int btr_pool_get_buffers(const struct btr_pool *btrp, struct iovec iov[2]) { size_t sz, unused; char *buf; @@ -322,7 +322,7 @@ static void dealloc_buffer(struct btr_buffer *btrb) free(btrb->buf); } -static struct btr_buffer_reference *get_first_input_br(struct btr_node *btrn) +static struct btr_buffer_reference *get_first_input_br(const struct btr_node *btrn) { if (list_empty(&btrn->input_queue)) return NULL; @@ -330,7 +330,7 @@ static struct btr_buffer_reference *get_first_input_br(struct btr_node *btrn) struct btr_buffer_reference, node); } -static struct btr_buffer_reference *get_last_input_br(struct btr_node *btrn) +static struct btr_buffer_reference *get_last_input_br(const struct btr_node *btrn) { if (list_empty(&btrn->input_queue)) return NULL; @@ -562,7 +562,7 @@ void btr_pushdown_one(struct btr_node *btrn) * * \return True if this node has no children. False otherwise. */ -static bool btr_no_children(struct btr_node *btrn) +static bool btr_no_children(const struct btr_node *btrn) { return list_empty(&btrn->children); } @@ -579,7 +579,7 @@ static bool btr_no_children(struct btr_node *btrn) * After a (non-leaf) node was removed removed from the tree, the function * returns true for all child nodes. */ -bool btr_no_parent(struct btr_node *btrn) +bool btr_no_parent(const struct btr_node *btrn) { return !btrn->parent; } @@ -602,7 +602,7 @@ bool btr_no_parent(struct btr_node *btrn) * * \return True if \a btrn has no siblings. */ -bool btr_inplace_ok(struct btr_node *btrn) +bool btr_inplace_ok(const struct btr_node *btrn) { struct btr_buffer_reference *br; FOR_EACH_BUFFER_REF(br, btrn) { @@ -615,12 +615,13 @@ bool btr_inplace_ok(struct btr_node *btrn) return true; } -static inline size_t br_available_bytes(struct btr_buffer_reference *br) +static inline size_t br_available_bytes(const struct btr_buffer_reference *br) { return br->btrb->size - br->consumed; } -static size_t btr_get_buffer_by_reference(struct btr_buffer_reference *br, char **buf) +static size_t btr_get_buffer_by_reference(const struct btr_buffer_reference *br, + char **buf) { if (buf) *buf = br->btrb->buf + br->consumed; @@ -647,7 +648,8 @@ static size_t btr_get_buffer_by_reference(struct btr_buffer_reference *br, char * to by \a btrn, the function returns zero and the value of \a bufp is * undefined. */ -size_t btr_next_buffer_omit(struct btr_node *btrn, size_t omit, char **bufp) +size_t btr_next_buffer_omit(const struct btr_node *btrn, size_t omit, + char **bufp) { struct btr_buffer_reference *br; size_t wrap_count, sz, rv = 0; @@ -712,7 +714,7 @@ out: * The call of this function is is equivalent to calling \ref * btr_next_buffer_omit() with an \a omit value of zero. */ -size_t btr_next_buffer(struct btr_node *btrn, char **bufp) +size_t btr_next_buffer(const struct btr_node *btrn, char **bufp) { return btr_next_buffer_omit(btrn, 0, bufp); } @@ -844,7 +846,7 @@ out: * This simply iterates over all buffer references in the input queue and * returns the sum of the sizes of all references. */ -size_t btr_get_input_queue_size(struct btr_node *btrn) +size_t btr_get_input_queue_size(const struct btr_node *btrn) { struct btr_buffer_reference *br; size_t size = 0, wrap_consumed = 0; @@ -861,7 +863,7 @@ size_t btr_get_input_queue_size(struct btr_node *btrn) return size; } -static bool min_iqs_available(size_t min_iqs, struct btr_node *btrn) +static bool min_iqs_available(size_t min_iqs, const struct btr_node *btrn) { struct btr_buffer_reference *br; size_t have = 0, wrap_consumed = 0; @@ -919,7 +921,7 @@ void btr_splice_out_node(struct btr_node **btrnp) * \return This function iterates over all children of the given node and * returns the size of the largest input queue. */ -size_t btr_get_output_queue_size(struct btr_node *btrn) +size_t btr_get_output_queue_size(const struct btr_node *btrn) { size_t max_size = 0; struct btr_node *ch; @@ -947,7 +949,7 @@ size_t btr_get_output_queue_size(struct btr_node *btrn) * * \sa \ref receiver::execute, \ref filter::execute, \ref writer::execute. */ -int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result) +int btr_exec_up(const struct btr_node *btrn, const char *command, char **value_result) { int ret; @@ -977,12 +979,12 @@ int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result) * * \sa \ref btr_new_node(), struct \ref btr_node_description. */ -void *btr_context(struct btr_node *btrn) +void *btr_context(const struct btr_node *btrn) { return btrn->context; } -static bool need_buffer_pool_merge(struct btr_node *btrn) +static bool need_buffer_pool_merge(const struct btr_node *btrn) { struct btr_buffer_reference *br = get_first_input_br(btrn); @@ -1157,7 +1159,7 @@ void btr_merge(struct btr_node *btrn, size_t dest_size) } } -static bool btr_eof(struct btr_node *btrn) +static bool btr_eof(const struct btr_node *btrn) { char *buf; size_t len = btr_next_buffer(btrn, &buf); @@ -1165,7 +1167,7 @@ static bool btr_eof(struct btr_node *btrn) return (len == 0 && btr_no_parent(btrn)); } -static void log_tree_recursively(struct btr_node *btrn, int loglevel, int depth) +static void log_tree_recursively(const struct btr_node *btrn, int loglevel, int depth) { struct btr_node *ch; const char spaces[] = " ", *space = spaces + 16 - depth; @@ -1183,7 +1185,7 @@ static void log_tree_recursively(struct btr_node *btrn, int loglevel, int depth) * \param btrn Start logging at this node. * \param loglevel Set severity with which the tree should be logged. */ -void btr_log_tree(struct btr_node *btrn, int loglevel) +void btr_log_tree(const struct btr_node *btrn, int loglevel) { return log_tree_recursively(btrn, loglevel, 0); } @@ -1243,7 +1245,7 @@ struct btr_node *btr_search_node(const char *name, struct btr_node *root) * btrn, the function also returns zero in order to bound the memory usage of * the buffer tree. */ -int btr_node_status(struct btr_node *btrn, size_t min_iqs, +int btr_node_status(const struct btr_node *btrn, size_t min_iqs, enum btr_node_type type) { if (type != BTR_NT_LEAF && btr_no_children(btrn)) @@ -1268,7 +1270,7 @@ int btr_node_status(struct btr_node *btrn, size_t min_iqs, * * Mainly useful for the time display of para_audiod. */ -void btr_get_node_start(struct btr_node *btrn, struct timeval *tv) +void btr_get_node_start(const struct btr_node *btrn, struct timeval *tv) { *tv = btrn->start; } @@ -1283,7 +1285,7 @@ void btr_get_node_start(struct btr_node *btrn, struct timeval *tv) * \return The parent of \a btrn, or \p NULL if \a btrn is the * root node of the buffer tree. */ -struct btr_node *btr_parent(struct btr_node *btrn) +struct btr_node *btr_parent(const struct btr_node *btrn) { return btrn->parent; } diff --git a/buffer_tree.h b/buffer_tree.h index 34535219..5eb3d6e5 100644 --- a/buffer_tree.h +++ b/buffer_tree.h @@ -131,7 +131,7 @@ enum btr_node_type { * know the sample rate of its input known to e.g. the mp3dec node further up * in the buffer tree. */ -typedef int (*btr_command_handler)(struct btr_node *btrn, +typedef int (*btr_command_handler)(const struct btr_node *btrn, const char *command, char **result); /** @@ -166,38 +166,38 @@ struct btr_node_description { void *context; }; -size_t btr_pool_size(struct btr_pool *btrp); +size_t btr_pool_size(const struct btr_pool *btrp); struct btr_pool *btr_pool_new(const char *name, size_t area_size); void btr_pool_free(struct btr_pool *btrp); -size_t btr_pool_get_buffer(struct btr_pool *btrp, char **result); -int btr_pool_get_buffers(struct btr_pool *btrp, struct iovec iov[2]); +size_t btr_pool_get_buffer(const struct btr_pool *btrp, char **result); +int btr_pool_get_buffers(const struct btr_pool *btrp, struct iovec iov[2]); void btr_add_output_pool(struct btr_pool *btrp, size_t size, struct btr_node *btrn); -size_t btr_pool_unused(struct btr_pool *btrp); +size_t btr_pool_unused(const struct btr_pool *btrp); void btr_copy(const void *src, size_t n, struct btr_pool *btrp, struct btr_node *btrn); - struct btr_node *btr_new_node(struct btr_node_description *bnd); void btr_remove_node(struct btr_node **btrnp); void btr_add_output(char *buf, size_t size, struct btr_node *btrn); void btr_add_output_dont_free(const char *buf, size_t size, struct btr_node *btrn); -size_t btr_get_input_queue_size(struct btr_node *btrn); -size_t btr_get_output_queue_size(struct btr_node *btrn); -bool btr_no_parent(struct btr_node *btrn); -size_t btr_next_buffer(struct btr_node *btrn, char **bufp); -size_t btr_next_buffer_omit(struct btr_node *btrn, size_t omit, char **bufp); +size_t btr_get_input_queue_size(const struct btr_node *btrn); +size_t btr_get_output_queue_size(const struct btr_node *btrn); +bool btr_no_parent(const struct btr_node *btrn); +size_t btr_next_buffer(const struct btr_node *btrn, char **bufp); +size_t btr_next_buffer_omit(const struct btr_node *btrn, size_t omit, + char **bufp); void btr_consume(struct btr_node *btrn, size_t numbytes); -int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result); +int btr_exec_up(const struct btr_node *btrn, const char *command, char **value_result); void btr_splice_out_node(struct btr_node **btrnp); void btr_pushdown(struct btr_node *btrn); -void *btr_context(struct btr_node *btrn); +void *btr_context(const struct btr_node *btrn); void btr_merge(struct btr_node *btrn, size_t dest_size); -void btr_log_tree(struct btr_node *btrn, int ll); +void btr_log_tree(const struct btr_node *btrn, int ll); void btr_pushdown_one(struct btr_node *btrn); -bool btr_inplace_ok(struct btr_node *btrn); -int btr_node_status(struct btr_node *btrn, size_t min_iqs, +bool btr_inplace_ok(const struct btr_node *btrn); +int btr_node_status(const struct btr_node *btrn, size_t min_iqs, enum btr_node_type type); -void btr_get_node_start(struct btr_node *btrn, struct timeval *tv); +void btr_get_node_start(const struct btr_node *btrn, struct timeval *tv); struct btr_node *btr_search_node(const char *name, struct btr_node *root); void btr_drain(struct btr_node *btrn); -struct btr_node *btr_parent(struct btr_node *btrn); +struct btr_node *btr_parent(const struct btr_node *btrn); diff --git a/check_wav.c b/check_wav.c index 3789f30a..cb39eb54 100644 --- a/check_wav.c +++ b/check_wav.c @@ -54,7 +54,7 @@ void check_wav_pre_monitor(struct sched *s, struct check_wav_context *cwc) sched_min_delay(s); } -static int check_wav_exec(struct btr_node *btrn, const char *cmd, char **result) +static int check_wav_exec(const struct btr_node *btrn, const char *cmd, char **result) { struct check_wav_context *cwc = btr_context(btrn); int val, header_val, given, arg; diff --git a/flacdec_filter.c b/flacdec_filter.c index fb8ebf15..bc3a678b 100644 --- a/flacdec_filter.c +++ b/flacdec_filter.c @@ -187,7 +187,7 @@ static int flacdec_init(struct filter_node *fn) return -E_FLACDEC_DECODER_INIT; } -static int flacdec_execute(struct btr_node *btrn, const char *cmd, +static int flacdec_execute(const struct btr_node *btrn, const char *cmd, char **result) { struct filter_node *fn = btr_context(btrn); diff --git a/mp3dec_filter.c b/mp3dec_filter.c index cf3e5d4b..d4d4712f 100644 --- a/mp3dec_filter.c +++ b/mp3dec_filter.c @@ -175,7 +175,8 @@ static void mp3dec_open(struct filter_node *fn) mad_stream_options(&pmd->stream, MAD_OPTION_IGNORECRC); } -static int mp3dec_execute(struct btr_node *btrn, const char *cmd, char **result) +static int mp3dec_execute(const struct btr_node *btrn, const char *cmd, + char **result) { struct filter_node *fn = btr_context(btrn); struct private_mp3dec_data *pmd = fn->private_data; diff --git a/oggdec_filter.c b/oggdec_filter.c index b1aec4bc..91c18c48 100644 --- a/oggdec_filter.c +++ b/oggdec_filter.c @@ -107,7 +107,8 @@ static void ogg_close(struct filter_node *fn) fn->private_data = NULL; } -static int oggdec_execute(struct btr_node *btrn, const char *cmd, char **result) +static int oggdec_execute(const struct btr_node *btrn, const char *cmd, + char **result) { struct filter_node *fn = btr_context(btrn); struct private_oggdec_data *pod = fn->private_data; diff --git a/opusdec_filter.c b/opusdec_filter.c index f36990fa..504ba0e8 100644 --- a/opusdec_filter.c +++ b/opusdec_filter.c @@ -75,7 +75,7 @@ struct opusdec_context { ogg_int32_t opus_serialno; }; -static int opusdec_execute(struct btr_node *btrn, const char *cmd, +static int opusdec_execute(const struct btr_node *btrn, const char *cmd, char **result) { struct filter_node *fn = btr_context(btrn); diff --git a/resample_filter.c b/resample_filter.c index 72cb3f62..6d4599a8 100644 --- a/resample_filter.c +++ b/resample_filter.c @@ -28,7 +28,8 @@ struct resample_context { struct check_wav_context *cwc; }; -static int resample_execute(struct btr_node *btrn, const char *cmd, char **result) +static int resample_execute(const struct btr_node *btrn, const char *cmd, + char **result) { struct filter_node *fn = btr_context(btrn); struct resample_context *ctx = fn->private_data; diff --git a/spxdec_filter.c b/spxdec_filter.c index 08eac02a..ce72125e 100644 --- a/spxdec_filter.c +++ b/spxdec_filter.c @@ -102,7 +102,7 @@ static void speexdec_close(struct filter_node *fn) fn->private_data = NULL; } -static int speexdec_execute(struct btr_node *btrn, const char *cmd, +static int speexdec_execute(const struct btr_node *btrn, const char *cmd, char **result) { struct filter_node *fn = btr_context(btrn); diff --git a/wmadec_filter.c b/wmadec_filter.c index f2ca273c..5b3d9874 100644 --- a/wmadec_filter.c +++ b/wmadec_filter.c @@ -1147,7 +1147,8 @@ static void wmadec_close(struct filter_node *fn) fn->private_data = NULL; } -static int wmadec_execute(struct btr_node *btrn, const char *cmd, char **result) +static int wmadec_execute(const struct btr_node *btrn, const char *cmd, + char **result) { struct filter_node *fn = btr_context(btrn); struct private_wmadec_data *pwd = fn->private_data; -- 2.39.2 From d63f84b1a243ce5d0a7d13928d9f522d7f5b476b Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 2 Jan 2023 15:07:31 +0100 Subject: [PATCH 16/16] btr: Streamline the documentation of buffer_tree.h. Nothing major, just a few minor English issues. --- buffer_tree.h | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/buffer_tree.h b/buffer_tree.h index 5eb3d6e5..70fb3055 100644 --- a/buffer_tree.h +++ b/buffer_tree.h @@ -3,45 +3,43 @@ /** * \file buffer_tree.h Buffer tree management. * - * \par Buffer trees and buffer tree nodes. - * The buffer tree API offers a more powerful method than standard unix pipes - * for managing the data flow from the producer of the data (e.g. the network - * receiver) to its consumer(s) (e.g. a sound card). + * Buffer trees and buffer tree nodes. * - * A buffer tree consists of buffer tree nodes linked via certain parent/child - * relationships. + * The buffer tree API offers an efficient method for managing the data flow + * from a producer (e.g. the network receiver) to the consumer(s) (e.g. a sound + * card). + * + * A buffer tree consists of buffer tree nodes which are linked together via + * parent/child relationships. Data buffers are propagated down without copying. * * Each data buffer starts its way from the root of the buffer tree. At each * node the data is investigated and possibly changed. New data is then fed to - * each child. Everything happens within one single-treaded process. There are - * no file descriptors and no calls to read() or write(). + * each child. There are no file descriptors, no processes/threads and no calls + * to read() or write(). * * Whenever a node in the buffer tree creates output, either by creating a new * buffer or by pushing down buffers received from its parent, references to - * that buffer are created for all children of the node. The buffer tree code - * tries hard to avoid to copy buffer contents, but is forced to do so in case - * there are alignment constraints. + * that buffer are created for all children of the node. The code avoids to + * copy buffer contents when possible. * - * Communication between nodes is possible via the btr_exec_up() function. - * For example, in para_audiod the alsa writer asks all parent nodes - * for for the number of channels and the sample rate of the current - * audio file. + * Communication between nodes is possible via the btr_exec_up() function. For + * example, in para_audiod the alsa writer asks all parent nodes for the number + * of channels and the sample rate of the current audio file. * * Buffer pools - An alternative to malloc/free buffer management. * - * Non-leaf nodes usually create output to be processed by their children. The - * data must be fed through the output channel(s) of the node in order to make - * that data available to each child. + * Non-leaf nodes usually create output to be processed by their child nodes. + * The data must be fed through the output channel(s) of the node in order to + * make that data available to each child. * * The easiest way to do so is to malloc() a buffer, fill it, and then call * btr_add_output(). This adds references to that buffer to all children. The * buffer is automatically freed if no buffer tree node is using it any more. * - * This approach, while being simple, has some drawbacks, especially affecting - * the root nodes of the buffer tree. Often the data source which is - * represented by a root node does not know in advance how much data will be - * available. Therefore the allocated buffer is either larger than what can - * currently be read, or is too small so that multiple buffers have to be used. + * This approach is simple but has some drawbacks. For example the data source + * represented by the root node does not know in advance how much data will be + * available. Therefore the allocated buffer will either be larger than + * necessary or too small so that multiple buffers have to be used. * * While this could be worked around by using a large buffer and calling * realloc() afterwards to shrink the buffer according to how much has been -- 2.39.2