roaraudio-1.0beta11/0000755000175000017500000000000012267553244012471 5ustar phiphiroaraudio-1.0beta11/build-system/0000755000175000017500000000000012267553166015115 5ustar phiphiroaraudio-1.0beta11/build-system/Makefile.binary0000644000175000017500000000202512057112772020026 0ustar phiphi# Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. TARGET ?= $(BASENAME) MANPAGE_1 ?= $(TARGET).1 RABS_INSTALL_TARGETS += bin include $(ROAR_BUILDSYSTEM_DIR)/Makefile.common include $(ROAR_BUILDSYSTEM_DIR)/Makefile.install roaraudio-1.0beta11/build-system/Makefile.common0000644000175000017500000000330212072606407020031 0ustar phiphi# Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. OBJS ?= $(BASENAME).o ifneq ($(origin BASENAME), undefined) DEFINES += -DBASENAME="\"$(BASENAME)\"" endif ifneq ($(origin LIBNAME), undefined) DEFINES += -DROAR_DBG_PREFIX="\"$(LIBNAME)\"" else ifneq ($(origin TARGET), undefined) DEFINES += -DROAR_DBG_PREFIX="\"$(TARGET)\"" endif endif TARGETS ?= $(TARGET) TARGET ?= DUMMY OPTI_O ?= -O2 CFLAGS += -g -Wall $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(ROAR_CFLAGS) LDFLAGS += -g -Wall $(Wextra) $(OPTI_O) $(LDPATH) LIBS += $(lib_roar) all: $(TARGETS) clean: rm -f $(TARGETS) *.o new: clean all distclean: clean rm -f Makefile.conf config.h config.log $(TARGET): $(OBJS) $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) #define at least some as phony .PHONY: all clean new distclean prep-install-dirs prep-install install semi-install uninstall #ll roaraudio-1.0beta11/build-system/Makefile.install0000644000175000017500000001123412101115726020202 0ustar phiphi# Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. RABS_INSTALL_TARGETS_PREP_DIRS := $(foreach c,$(RABS_INSTALL_TARGETS),prep-install-dirs-$c) RABS_INSTALL_TARGETS_INSTALL := $(foreach c,$(RABS_INSTALL_TARGETS),install-$c) RABS_INSTALL_TARGETS_SEMI_INSTALL := $(foreach c,$(RABS_INSTALL_TARGETS),semi-install-$c) RABS_INSTALL_TARGETS_UNINSTALL := $(foreach c,$(RABS_INSTALL_TARGETS),uninstall-$c) prep-install-dirs: $(RABS_INSTALL_TARGETS_PREP_DIRS) prep-install: all prep-install-dirs install: $(RABS_INSTALL_TARGETS_INSTALL) semi-install: $(RABS_INSTALL_TARGETS_SEMI_INSTALL) uninstall: $(RABS_INSTALL_TARGETS_UNINSTALL) prep-install-dirs-bin: mkdir -p '$(DESTDIR)$(PREFIX_BIN)' mkdir -p '$(DESTDIR)$(PREFIX_MAN)'/man1/ prep-install-dirs-tools: prep-install-dirs-bin prep-install-dirs-header: mkdir -p '$(DESTDIR)$(PREFIX_INC)'/'$(HEADER_PREFIX)' prep-install-dirs-lib: prep-install-dirs-header mkdir -p '$(DESTDIR)$(PREFIX_LIB)' mkdir -p '$(DESTDIR)$(PREFIX_PC)' mkdir -p '$(DESTDIR)$(PREFIX_MAN)'/man3/ mkdir -p '$(DESTDIR)$(PREFIX_CKPORT)' prep-install-dirs-plugin: mkdir -p '$(DESTDIR)$(PLUGIN_PATH)' prep-install-bin: all prep-install-dirs-bin prep-install-tools: all prep-install-dirs-tools prep-install-header: all prep-install-dirs-header prep-install-lib: all prep-install-dirs-lib prep-install-plugin: all prep-install-dirs-plugin # this works for both, -bin and -tools install-bin: prep-install-bin cp $(cp_v) $(TARGETS) '$(DESTDIR)$(PREFIX_BIN)' cp $(cp_v) $(MANPAGE_1) '$(DESTDIR)$(PREFIX_MAN)'/man1/ install-tools: install-bin install-lib: prep-install-lib cp $(cp_v) $(TARGETS) '$(DESTDIR)$(PREFIX_LIB)' cp $(cp_v) $(PCLIBNAME) '$(DESTDIR)$(PREFIX_PC)' cp $(cp_v) $(CKPORTDB) '$(DESTDIR)$(PREFIX_CKPORT)' sh -c 'set -e; for file in $(HEADERS); do cp $(cp_v) $(HEADERS_DIR)/$$file '$(DESTDIR)$(PREFIX_INC)'/'$(HEADER_PREFIX)'; done' sh -c 'set -e; for file in $(MANPAGE_3); do cp $(cp_v) $$file '$(DESTDIR)$(PREFIX_MAN)'/man3/; done' # cp $(cp_v) $(CKPORTDB) install-plugin: prep-install-plugin cp $(cp_v) $(TARGETS) '$(DESTDIR)$(PLUGIN_PATH)'/ semi-install-bin: prep-install-bin ln -fs `pwd`/$(TARGET) '$(DESTDIR)$(PREFIX_BIN)' ln -fs `pwd`/$(MANPAGE_1) '$(DESTDIR)$(PREFIX_MAN)'/man1/ semi-install-tools: prep-install-tools sh -c 'set -e; for file in $(TARGETS); do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_BIN)'/; done' sh -c 'set -e; for file in $(MANPAGE_1); do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_MAN)'/man1/; done' semi-install-lib: prep-install-lib sh -c 'set -e; for file in $(TARGETS); do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_LIB)'/; done' ln -fs `pwd`/$(PCLIBNAME) '$(DESTDIR)$(PREFIX_PC)' ln -fs `pwd`/$(CKPORTDB) '$(DESTDIR)$(PREFIX_CKPORT)' sh -c 'set -e; for file in $(HEADERS); do ln -fs `pwd`/$(HEADERS_DIR)/$$file '$(DESTDIR)$(PREFIX_INC)'/'$(HEADER_PREFIX)'; done' sh -c 'set -e; for file in $(MANPAGE_3); do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_MAN)'/man3/; done' semi-install-plugin: prep-install-plugin sh -c 'set -e; for file in $(TARGETS); do ln -fs `pwd`/$$file '$(DESTDIR)$(PLUGIN_PATH)/'; done' uninstall-bin: rm -f '$(DESTDIR)$(PREFIX_BIN)/$(TARGET)' rm -f '$(DESTDIR)$(PREFIX_MAN)/man1/$(MANPAGE_1)' uninstall-tools: sh -c 'set -e; for file in $(TARGETS); do rm -f '$(DESTDIR)$(PREFIX_BIN)/'$$file; done' sh -c 'set -e; for file in $(MANPAGE_1); do rm -f '$(DESTDIR)$(PREFIX_MAN)/man1/'$$file; done' uninstall-lib: sh -c 'set -e; for file in $(TARGETS); do rm -f '$(DESTDIR)$(PREFIX_LIB)/'$$file; done' rm -f '$(DESTDIR)$(PREFIX_PC)/$(PCLIBNAME)' rm -f '$(DESTDIR)$(PREFIX_CKPORT)/$(CKPORTDB)' sh -c 'set -e; for file in $(HEADERS); do rm -f '$(DESTDIR)$(PREFIX_INC)'/'$(HEADER_PREFIX)/'$$file; done' sh -c 'set -e; for file in $(MANPAGE_3); do rm -f '$(DESTDIR)$(PREFIX_MAN)/man3/$$file'; done' uninstall-plugin: sh -c 'set -e; for file in $(TARGETS); do rm -f '$(DESTDIR)$(PLUGIN_PATH)/'$$file; done' roaraudio-1.0beta11/build-system/Makefile.library0000644000175000017500000000477212057127462020223 0ustar phiphi# Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. RABS_INSTALL_TARGETS += lib CFLAGS += $(fPIC) $(SHARED_CF) LDFLAGS += $(SHARED) ifneq ($(origin COMMON_V_MAJOR), undefined) COMMON_SOVERSION ?= $(COMMON_V_MAJOR) endif ifneq ($(origin COMMON_SOVERSION), undefined) SOVERSION ?= $(COMMON_SOVERSION) else SOVERSION ?= dummy endif ifneq ($(origin COMMON_VERSION), undefined) PC_VERSION ?= $(COMMON_VERSION) else PC_VERSION ?= so$(SOVERSION) endif PC_DESC ?= DUMMY PC_LIBS += libroar LIBNAME = lib$(BASENAME) SOLIBNAME = $(LIBNAME)$(SHARED_SUFFIX) SOVLIBNAME = $(SOLIBNAME).$(SOVERSION) ALIBNAME = $(LIBNAME).a PCLIBNAME = $(LIBNAME).pc CKPORTDB = $(LIBNAME).ckport TARGETS=$(SOLIBNAME) $(SOVLIBNAME) $(ALIBNAME) $(PCLIBNAME) include $(ROAR_BUILDSYSTEM_DIR)/Makefile.common include $(ROAR_BUILDSYSTEM_DIR)/Makefile.install $(SOLIBNAME): $(SOVLIBNAME) ln -fs $(SOVLIBNAME) $(SOLIBNAME) $(SOVLIBNAME): $(OBJS) $(CC) $(LDFLAGS) -Wl,-soname,$(SOVLIBNAME) -o $(SOVLIBNAME) $(OBJS) $(LIBS) $(ALIBNAME): $(OBJS) $(AR) cru $(ALIBNAME) $(OBJS) $(RANLIB) $(ALIBNAME) $(PCLIBNAME): echo 'prefix=$(PREFIX)' > $(PCLIBNAME) echo 'exec_prefix=$${prefix}' >> $(PCLIBNAME) echo 'libdir=$(PREFIX_LIB)' >> $(PCLIBNAME) echo 'includedir=$(PREFIX_INC)' >> $(PCLIBNAME) echo '' >> $(PCLIBNAME) echo 'Name: $(LIBNAME)' >> $(PCLIBNAME) echo 'Description: $(PC_DESC)' >> $(PCLIBNAME) echo 'Version: $(PC_VERSION)' >> $(PCLIBNAME) echo 'Conflicts:' >> $(PCLIBNAME) ifeq ($(LINK_DEPS),full) echo 'Requires: $(PC_LIBS)' >> $(PCLIBNAME) else echo 'Requires.private: $(PC_LIBS)' >> $(PCLIBNAME) endif echo 'Libs: -L$${libdir} -l$(BASENAME)' >> $(PCLIBNAME) echo 'Cflags: -I$${includedir}' >> $(PCLIBNAME) roaraudio-1.0beta11/build-system/Makefile.plugin0000644000175000017500000000304512101115726020033 0ustar phiphi# Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. TARGET ?= $(BASENAME)$(SHARED_SUFFIX) ROAR_CFLAGS := $(shell roar-config --cflags) ROAR_LIBS := $(shell roar-config --libs) CFLAGS += $(fPIC) LDFLAGS += $(SHARED) LIBS += $(ROAR_LIBS) # cp $(cp_v) ${TARGETS} '$(DESTDIR)$(PREFIX_PLUGINS)/universal/universal/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/' PLUGIN_VENDOR ?= <$(DEV_VENDOR_STRING)> PLUGIN_PRODUCT_NAME ?= DUMMY PLUGIN_PRODUCT ?= $(PLUGIN_PRODUCT_NAME) $(PLUGIN_VENDOR) PLUGIN_PATH := $(shell roar-config --product '$(PLUGIN_PRODUCT)' --provider '$(PLUGIN_VENDOR)' --path prefix-plugins) RABS_INSTALL_TARGETS += plugin include $(ROAR_BUILDSYSTEM_DIR)/Makefile.common include $(ROAR_BUILDSYSTEM_DIR)/Makefile.install roaraudio-1.0beta11/build-system/Makefile.tools0000644000175000017500000000207412057112772017706 0ustar phiphi# Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. RABS_INSTALL_TARGETS += tools MANPAGE_1 ?= $(foreach c,$(TARGETS),$c.1) L = $(CC) $(LDFLAGS) -o $@ $< $(LIBS) include $(ROAR_BUILDSYSTEM_DIR)/Makefile.common include $(ROAR_BUILDSYSTEM_DIR)/Makefile.install roaraudio-1.0beta11/build-system/configure.all0000644000175000017500000000205112027617350017554 0ustar phiphi#!/bin/false # vim:ft=sh # Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. . "$ROAR_BUILDSYSTEM_DIR/configure.early" . "$ROAR_BUILDSYSTEM_DIR/configure.vars" . "$ROAR_BUILDSYSTEM_DIR/configure.lib" . "$ROAR_BUILDSYSTEM_DIR/configure.tests" #ll roaraudio-1.0beta11/build-system/configure.early0000644000175000017500000000202012027601450020106 0ustar phiphi#!/bin/false # vim:ft=sh # Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # check for bash... if [ "$(echo -n)" = '-n' ] then SHELL=$(which bash ksh sh 2> /dev/null | grep ^/ | head -n 1) exec $SHELL $0 "$@" fi #ll roaraudio-1.0beta11/build-system/configure.lib0000644000175000017500000004320012132520150017537 0ustar phiphi#!/bin/false # vim:ft=sh # Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # some very basic string functions: to_upper() { tr 'a-z' 'A-Z' } to_escaped() { tr 'A-Z/.+-' 'a-z____' } error_missing() { _object="$1" [ "$_object" = '' ] && _object="$last_tested_object" echo "Error: $_object is missing but required." exit 1 } error_internal() { if [ "$1" = '' ] then echo "Error: Internal error within configure script. Contact author." else echo "Error: $1" fi exit 1; } set_dev_vendor() { if [ "$#" = '2' ] then DEV_VENDOR="$1" DEV_VENDOR_NAME="$2" DEV_VENDOR_STRING="$DEV_VENDOR/$DEV_VENDOR_NAME" else DEV_VENDOR='' DEV_VENDOR_NAME="$1" DEV_VENDOR_STRING="$DEV_VENDOR_NAME" fi } set_std_vendor() { if [ "$#" = '2' ] then STD_VENDOR="$1" STD_VENDOR_NAME="$2" STD_VENDOR_STRING="$STD_VENDOR/$STD_VENDOR_NAME" else STD_VENDOR='' STD_VENDOR_NAME="$1" STD_VENDOR_STRING="$STD_VENDOR_NAME" fi } write_help() { echo 'COMMON OPTIONS:' echo echo '--ldpath DIR - Add DIR to (compile time) search list for libs' echo '--incpath DIR - Add DIR to search list for headers' echo '--addpath DIR - Add DIR/lib to lib, DIR/include to header search list' echo '--root DIR - The same as "--addpath DIR --prefix DIR"' echo echo '--cflags FLAGS - Sets additional compiler flags (default: '"$CFLAGS"')' echo '--ldflags FLAGS - Sets additional linker flags (default: '"$LDFLAGS"')' echo '--opti LEVEL - Sets optimizer level (default: '"$OPTI_O"')' echo '--without-debugging - Disable compiling debug information into binaries' echo '--link-deps MODE - Model for linking dependencies: auto, full or indirect' echo echo '--cc CC - Set name of C compiler (CC) to CC' echo '--ranlib RANLIB - Set name of ranlib (RANLIB) to RANLIB' echo echo '--root-uid UID - Sets User ID (UID) of the root user/superuser' echo echo '--no-LIB - disable library LIB' echo '--maybe-LIB - autodetect library LIB (default)' echo echo '--prefix DIR - Set general prefix (default: '"$PREFIX"')' echo '--prefix-bin DIR - Set prefix for binaries (default: $PREFIX/bin)' echo '--prefix-sbin DIR - Set prefix for system binaries (default: $PREFIX/sbin)' echo '--prefix-lib DIR - Set prefix for libraries (default: $PREFIX/libs)' echo '--prefix-inc DIR - Set prefix for include files (default: $PREFIX/include)' echo '--prefix-man DIR - Set prefix for manpages (default: $PREFIX/share/man)' echo '--prefix-pc DIR - Set prefix for pkg-config (default: $PREFIX_LIB/pkgconfig)' echo '--prefix-sysconf DIR - Set prefix for system configuration (default: '"$PREFIX_SYSCONF"')' echo '--prefix-dev DIR - Set prefix for devices (default: '"$PREFIX_DEV"')' echo '--prefix-doc DIR - Set prefix for documentation (default: $PREFIX/share/doc)' echo '--prefix-tmp DIR - Set prefix for temporary files (default: '"$PREFIX_TMP"')' echo '--prefix-var DIR - Set prefix for variable files (default: '"$PREFIX_VAR"')' echo '--prefix-cache DIR - Set prefix for application caches (default: $PREFIX_VAR/cache)' echo '--prefix-data DIR - Set prefix for variable application data (default: $PREFIX_VAR/lib)' echo '--prefix-lock DIR - Set prefix for lock files (locked resources) (default: $PREFIX_VAR/lock)' echo '--prefix-log DIR - Set prefix for log files (default: $PREFIX_VAR/log)' echo '--prefix-mail DIR - Set prefix for user'\''s mailboxes (default: $PREFIX_VAR/mail)' echo '--prefix-run DIR - Set prefix for information about the running system (default: $PREFIX_VAR/run)' echo '--prefix-spool DIR - Set prefix for spools (queued jobs) (default: $PREFIX_VAR/spool)' echo echo '--without-beta - Disable beta code' echo '--without-experimental - Disable experimental code' echo echo '--distribution-version-string STRING' echo ' - Sets distribution part of version string' echo echo '--mmcu MMCU - Sets -mmcu compiler/linker option' echo '--target-win32 - Disable everything useful' echo '--exec-helper HELPER - Exec all test programms using this command (HELPER $cmd $args)' echo ' use '\''--exec-helper wine'\'' when building win32 binaries' echo } parse_option() { # Options are given via $n. # we can not shift used ones so we tell the caller # how many to shift: shift $SHIFT_COUNT SHIFT_COUNT=0 # we also tell if the option was handelt. HANDLED=true # will be reset if not. case "$1" in '--ldpath') LDPATH="$LDPATH -L$2" SHIFT_COUNT=1 ;; '--incpath') INCPATH="$INCPATH -I$2" SHIFT_COUNT=1 ;; '--addpath') LDPATH="$LDPATH -L$2/lib/" INCPATH="$INCPATH -I$2/include/" SHIFT_COUNT=1 ;; '--root') LDPATH="$LDPATH -L$2/lib/" INCPATH="$INCPATH -I$2/include/" PREFIX="$2" SHIFT_COUNT=1 ;; '--cflags') CFLAGS="$2" SHIFT_COUNT=1 ;; '--ldflags') LDFLAGS="$2" SHIFT_COUNT=1 ;; '--opti') OPTI_O="$2" SHIFT_COUNT=1 ;; '--without-debugging') DEBUG_g='' ;; '--link-deps') LINK_DEPS="$2" SHIFT_COUNT=1 ;; '--cc') CC="$2" SHIFT_COUNT=1 ;; '--ranlib') RANLIB="$2" SHIFT_COUNT=1 ;; '--root-uid') ROOT_UID="$2" SHIFT_COUNT=1 ;; '--no-'*) lib=$(echo "$1" | sed 's/^--no-//' | to_escaped) eval no_lib_$lib=true ;; '--maybe-'*) lib=$(echo "$1" | sed 's/^--maybe-//' | to_escaped) eval unset no_lib_$lib ;; '--distribution-version-string') DISTRIBUTION_VERSION_STRING="$2" SHIFT_COUNT=1 ;; '--without-beta') BETA=false EXPERIMENTAL=false ;; '--without-experimental') EXPERIMENTAL=false ;; '--prefix') PREFIX="$2" SHIFT_COUNT=1 ;; '--prefix-bin') PREFIX_BIN="$2" SHIFT_COUNT=1 ;; '--prefix-sbin') PREFIX_SBIN="$2" SHIFT_COUNT=1 ;; '--prefix-lib') PREFIX_LIB="$2" SHIFT_COUNT=1 ;; '--prefix-inc') PREFIX_INC="$2" SHIFT_COUNT=1 ;; '--prefix-man') PREFIX_MAN="$2" SHIFT_COUNT=1 ;; '--prefix-pc') PREFIX_PC="$2" SHIFT_COUNT=1 ;; '--prefix-ckport') PREFIX_CKPORT="$2" SHIFT_COUNT=1 ;; '--prefix-sysconf') PREFIX_SYSCONF="$2" SHIFT_COUNT=1 ;; '--prefix-dev') PREFIX_DEV="$2" SHIFT_COUNT=1 ;; '--prefix-doc') PREFIX_DOC="$2" SHIFT_COUNT=1 ;; '--prefix-tmp') PREFIX_TMP="$2" SHIFT_COUNT=1 ;; '--prefix-var') PREFIX_VAR="$2" SHIFT_COUNT=1 ;; '--prefix-cache') PREFIX_CACHE="$2" SHIFT_COUNT=1 ;; '--prefix-data') PREFIX_DATA="$2" SHIFT_COUNT=1 ;; '--prefix-lock') PREFIX_LOCK="$2" SHIFT_COUNT=1 ;; '--prefix-log') PREFIX_LOG="$2" SHIFT_COUNT=1 ;; '--prefix-mail') PREFIX_MAIL="$2" SHIFT_COUNT=1 ;; '--prefix-run') PREFIX_RUN="$2" SHIFT_COUNT=1 ;; '--prefix-spool') PREFIX_SPOOL="$2" SHIFT_COUNT=1 ;; #################################### # autof* options block: '--prefix='*) PREFIX=$(echo "$1" | cut -d= -f2) ;; '--prefix-bin='*) PREFIX_BIN=$(echo "$1" | cut -d= -f2) ;; '--prefix-sbin='*) PREFIX_SBIN=$(echo "$1" | cut -d= -f2) ;; '--prefix-lib='*) PREFIX_LIB=$(echo "$1" | cut -d= -f2) ;; '--prefix-inc='*) PREFIX_INC=$(echo "$1" | cut -d= -f2) ;; '--prefix-man='*) PREFIX_MAN=$(echo "$1" | cut -d= -f2) ;; '--prefix-pc='*) PREFIX_PC=$(echo "$1" | cut -d= -f2) ;; '--prefix-ckport='*) PREFIX_CKPORT=$(echo "$1" | cut -d= -f2) ;; '--prefix-sysconf='*) PREFIX_SYSCONF=$(echo "$1" | cut -d= -f2) ;; '--prefix-dev='*) PREFIX_DEV=$(echo "$1" | cut -d= -f2) ;; '--prefix-doc='*) PREFIX_DOC=$(echo "$1" | cut -d= -f2) ;; '--prefix-tmp='*) PREFIX_TMP=$(echo "$1" | cut -d= -f2) ;; '--prefix-var='*) PREFIX_VAR=$(echo "$1" | cut -d= -f2) ;; '--prefix-cache='*) PREFIX_CACHE=$(echo "$1" | cut -d= -f2) ;; '--prefix-data='*) PREFIX_DATA=$(echo "$1" | cut -d= -f2) ;; '--prefix-lock='*) PREFIX_LOCK=$(echo "$1" | cut -d= -f2) ;; '--prefix-log='*) PREFIX_LOG=$(echo "$1" | cut -d= -f2) ;; '--prefix-mail='*) PREFIX_MAIL=$(echo "$1" | cut -d= -f2) ;; '--prefix-run='*) PREFIX_RUN=$(echo "$1" | cut -d= -f2) ;; '--prefix-spool='*) PREFIX_SPOOL=$(echo "$1" | cut -d= -f2) ;; #################################### '--mmcu') MMCU="$2" SHIFT_COUNT=1 ;; '--exec-helper') EXEC_HELPER="$2" SHIFT_COUNT=1 ;; '--target-win32') TARGET_WIN32=true ;; *) HANDLED=false ;; esac; if $HANDLED then SHIFT_COUNT=`expr $SHIFT_COUNT + 1` fi } open_configure_files() { exec 3> config.h 4> Makefile.conf 5> config.log } update_target() { TARGET_CYGWIN=`echo "$SYSNAME" | if grep CYGWIN > /dev/null; then echo true; else echo false; fi` TARGET_WIN32=`echo "$SYSNAME" | if grep MINGW32 > /dev/null; then echo true; else echo $TARGET_WIN32; fi` if $TARGET_WIN32 then TARGET_TYPE='win32' elif $TARGET_MICROCONTROLLER then TARGET_TYPE='microcontroller' elif $TARGET_CYGWIN then TARGET_TYPE='cygwin' else TARGET_TYPE='generic' fi if [ "$SYSNAME" = 'Darwin' ] then echo "Adding common $SYSNAME shared lib arguments..." SHARED="$SHARED -fno-common -dynamiclib -compatibility_version 0.1 -current_version 0.1.0" SHARED_CF="$SHARED_CF -fno-common" elif [ "$SYSNAME" = 'NetBSD' ] then echo "Adding common $SYSNAME libpath arguments..." LDPATH="$LDPATH -L/usr/local/lib/" elif [ "$SYSNAME" = 'OpenBSD' ] then echo "Adding common $SYSNAME search path arguments..." LDPATH="$LDPATH -L/usr/local/lib/" INCPATH="$INCPATH -I/usr/local/include/" # echo "Adding $SYSNAME build arguments..." # SNDIO_EMUL=false elif [ "$SYSNAME" = 'FreeBSD' ] then echo "Adding common $SYSNAME search path arguments..." LDPATH="$LDPATH -L/usr/local/lib/" INCPATH="$INCPATH -I/usr/local/include/" elif $TARGET_WIN32 then echo "Adding common win32 build arguments..." rdynamic=false fPIC=false SHARED_SUFFIX='.dll' TF_E="$TF_E.exe" # should those be also in the cygwin port? IMPLIB='$(BASENAME)$(SHARED_SUFFIX).a' LDFLAGS="$LDFLAGS -Wl,--out-implib=\$@.a" elif $TARGET_CYGWIN then echo "Adding common cygwin build arguments..." rdynamic=false fPIC=false SHARED_SUFFIX='.dll' TF_E="$TF_E.exe" fi } update_prefixes() { [ "$PREFIX_BIN" = '' ] && PREFIX_BIN="$PREFIX/bin/" [ "$PREFIX_SBIN" = '' ] && PREFIX_SBIN="$PREFIX/sbin/" [ "$PREFIX_LIB" = '' ] && PREFIX_LIB="$PREFIX/lib/" [ "$PREFIX_INC" = '' ] && PREFIX_INC="$PREFIX/include/" [ "$PREFIX_MAN" = '' ] && PREFIX_MAN="$PREFIX/share/man/" [ "$PREFIX_PC" = '' ] && PREFIX_PC="$PREFIX_LIB/pkgconfig/" [ "$PREFIX_CKPORT" = '' ] && PREFIX_CKPORT="$PREFIX_LIB/ckport/db/" [ "$PREFIX_SYSCONF" = '' ] && PREFIX_SYSCONF="/etc/" [ "$PREFIX_DEV" = '' ] && PREFIX_DEV="/dev/" [ "$PREFIX_DOC" = '' ] && PREFIX_DOC="$PREFIX/share/doc/" [ "$PREFIX_TMP" = '' ] && PREFIX_TMP="/tmp/" [ "$PREFIX_VAR" = '' ] && PREFIX_VAR="/var/" [ "$PREFIX_CACHE" = '' ] && PREFIX_CACHE="$PREFIX_VAR/cache/" [ "$PREFIX_DATA" = '' ] && PREFIX_DATA="$PREFIX_VAR/lib/" [ "$PREFIX_LOCK" = '' ] && PREFIX_LOCK="$PREFIX_VAR/lock/" [ "$PREFIX_LOG" = '' ] && PREFIX_LOG="$PREFIX_VAR/log/" [ "$PREFIX_MAIL" = '' ] && PREFIX_MAIL="$PREFIX_VAR/mail/" [ "$PREFIX_RUN" = '' ] && PREFIX_RUN="$PREFIX_VAR/run/" [ "$PREFIX_SPOOL" = '' ] && PREFIX_SPOOL="$PREFIX_VAR/spool/" } update_ccft() { CCTF="$CC $CFLAGS $LDFLAGS $LDPATH $INCPATH -Iinclude/ -o $TF_E $TF_C" } cleanup_ccft() { rm -f $TF_C $TF_E } update_cc() { if [ "$MMCU" != '' ] then CC="$CC -mmcu=$MMCU" fi } write_header_makefileconf() { { echo "VERSION=$VERSION" echo "DISTRIBUTION_VERSION_STRING=$DISTRIBUTION_VERSION_STRING" echo [ "$DEV_VENDOR" != '' ] && echo "DEV_VENDOR=$DEV_VENDOR" [ "$DEV_VENDOR_NAME" != '' ] && echo "DEV_VENDOR_NAME=$DEV_VENDOR_NAME" [ "$DEV_VENDOR_STRING" != '' ] && echo "DEV_VENDOR_STRING=$DEV_VENDOR_STRING" [ "$STD_VENDOR" != '' ] && echo "STD_VENDOR=$STD_VENDOR" [ "$STD_VENDOR_NAME" != '' ] && echo "STD_VENDOR_NAME=$STD_VENDOR_NAME" [ "$STD_VENDOR_STRING" != '' ] && echo "STD_VENDOR_STRING=$STD_VENDOR_STRING" echo echo "TARGET_TYPE=$TARGET_TYPE" echo "SHARED=$SHARED" echo "SHARED_CF=$SHARED_CF" echo "SHARED_SUFFIX=$SHARED_SUFFIX" $rdynamic && echo 'rdynamic=-rdynamic' $fPIC && echo 'fPIC=-fPIC' $Wextra && echo 'Wextra=-Wextra' echo "Wall=-Wall" echo echo "CC=$CC" echo "RANLIB=$RANLIB" echo "LDPATH=$LDPATH" echo "INCPATH=$INCPATH" echo "ROAR_BUILDSYSTEM_DIR=$ROAR_BUILDSYSTEM_DIR" echo echo "OPTI_O=-O$OPTI_O" echo "DEBUG_g=$DEBUG_g" echo "IMPLIB=$IMPLIB" echo [ "$CFLAGS" != '' ] && echo "CFLAGS += $CFLAGS" [ "$LDFLAGS" != '' ] && echo "LDFLAGS += $LDFLAGS" echo echo "EXEC_HELPER=$EXEC_HELPER" echo "CROSS_COMPILE=$CROSS_COMPILE" echo echo "PREFIX=$PREFIX" echo "PREFIX_BIN=$PREFIX_BIN" echo "PREFIX_SBIN=$PREFIX_SBIN" echo "PREFIX_LIB=$PREFIX_LIB" echo "PREFIX_INC=$PREFIX_INC" echo "PREFIX_MAN=$PREFIX_MAN" echo "PREFIX_PC=$PREFIX_PC" echo "PREFIX_CKPORT=$PREFIX_CKPORT" echo "PREFIX_SYSCONF=$PREFIX_SYSCONF" echo "PREFIX_DEV=$PREFIX_DEV" echo "PREFIX_DOC=$PREFIX_DOC" echo "PREFIX_TMP=$PREFIX_TMP" echo "PREFIX_VAR=$PREFIX_VAR" echo "PREFIX_CACHE=$PREFIX_CACHE" echo "PREFIX_DATA=$PREFIX_DATA" echo "PREFIX_LOCK=$PREFIX_LOCK" echo "PREFIX_LOG=$PREFIX_LOG" echo "PREFIX_MAIL=$PREFIX_MAIL" echo "PREFIX_RUN=$PREFIX_RUN" echo "PREFIX_SPOOL=$PREFIX_SPOOL" echo } >&4 } write_footer_makefileconf() { { echo echo '#ll' } >&4 } write_header_configlog() { { cat <<'EOF' //config.log: /* * Logfile for configure script $Revision: 1.20 $ of RoarAudio */ EOF echo '/* uname: ' $(uname -a) '*/' echo '/* Date : ' $(date) '*/' echo echo echo echo "ARGS(): $_CARGS" for i in PATH SHELL CC RANLIB PKG_CONFIG SYSNAME \ TARGET_TYPE TARGET_CYGWIN TARGET_WIN32 TARGET_MICROCONTROLLER CROSS_COMPILE \ MINIMAL EXEC_HELPER \ "$@" do eval echo "BASICCONF\($i\): \$$i"; done echo echo } >&5 } write_footer_configlog() { { echo echo '//ll' } >&5 } write_header_configh() { { echo '#ifdef __RABS_COMMENT__' echo '//config.h:' echo '#endif' echo echo "#ifndef $1" echo "#define $1" echo echo '#ifdef __RABS_COMMENT__' echo '/* uname: ' $(uname -a) '*/' echo '/* Date : ' $(date) '*/' echo '#endif' echo } >&3 } write_footer_configh() { { echo echo '#endif' echo echo '#ifdef __RABS_COMMENT__' echo 'End of File.' echo '#endif' } >&3 } write_vars_configh_string() { { for f in "$@" do eval val=\"\$$f\" echo "#define $f \"$val\"" done } >&3 } write_vars_configh_literal() { { for f in "$@" do eval val=\"\$$f\" echo "#define $f $val" done } >&3 } write_header() { write_header_makefileconf write_header_configlog write_header_configh "$@" } write_footer() { write_footer_makefileconf write_footer_configlog write_footer_configh } write_summery_header() { echo echo "Summery:" } write_summery() { _type="$1" _name="$2" _displayname="$3" [ "$_displayname" = '' ] && _displayname="$_name" #types: # Wextra # BIN_FORMAT # LINK_DEPS # lib # _envname=`echo "$_h" | to_escaped` # eval "_t=\$libname_$_envname" # RUNTIME_DETECT # func # eval funcname_$_funcname=true # generic: # var # bool # retval # convert types which are subtypes of others: case "$_type" in 'Wextra') _type=bool _name=Wextra [ "$_displayname" = '' ] && _displayname="-Wextra" ;; 'bin_format') _type=var _name=BIN_FORMAT [ "$_displayname" = '' ] && _displayname="binary format" ;; 'linkdeps') _type=var _name=LINK_DEPS [ "$_displayname" = '' ] && _displayname="linkage model" ;; 'RUNTIME_DETECT') _type=bool _name=RUNTIME_DETECT [ "$_displayname" = '' ] && _displayname="runtime detect" ;; 'lib') eval eval _no="\\\$no_lib_\$envname2envlib_`echo "$_name" | to_escaped`"; if [ "$_no" != '' ] then _no="disabled by user" _type=var _name=_no else _type=bool _name=libname_`echo "$_name" | to_escaped` fi ;; 'func') _type=bool _name=funcname_`echo "$_name" | to_escaped` ;; esac; _retval=999999 _status='' case "$_type" in 'retval') _retval="$_name" ;; 'bool') _false=false [ "$_name" = '' ] && _name=_false eval \$$_name > /dev/null _retval=$? ;; 'var') eval _status="\$$_name" _retval=0 ;; *) error_internal "Unknown type in summry display: $_type" ;; esac if [ "$_status" = '' ] then if [ "$_retval" = '0' ] then _status='ok' else _status='not supported' fi fi _dummy=`echo "$_displayname" | tr '[:print:]' x` _dots=`printf "%-24s" $_dummy | tr -d x | tr " " .` echo " $_displayname$_dots: $_status" } #ll roaraudio-1.0beta11/build-system/configure.tests0000644000175000017500000004327212132520150020144 0ustar phiphi#!/bin/false # vim:ft=sh # Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. test_libroar() { _min="$1" [ "$_min" = '' ] && _min='current' echo -n "checking for version of roaraudio... " if roar-config --compare-versions current ge "$_min" then echo "`roar-config --version`, good" return 0 else _ver="`roar-config --version 2> /dev/null`" if [ "$_ver" = '' ] then echo "unknown. bad." else echo "$_ver, too old (minimum required: $_min)" fi return 1 fi } test_pkgversion() { echo -n "checking for version of this package... " VERSION=`head -n 1 ChangeLog | cut -d' ' -f2` echo "$VERSION" return 0 } test_buildstamp() { echo -n "checking for build stamp of this package... " BUILD_STAMP="`date -u +'%F %X'` (`id -un`@`uname -n`)" echo "$BUILD_STAMP" return 0 } test_cc() { echo -n "checking for C compiler... " if [ "$CC" != '' ] then echo $CC return 0 else CC=$(which gcc cc 2> /dev/null | grep ^/ | head -n 1) if [ "$CC" = '' ] then echo 'none' exit 1; fi echo $CC return 0 fi } test_ranlib() { echo -n "checking for ranlib... " if [ "$RANLIB" != '' ] then echo $RANLIB return 0 else _guess=`echo $CC | sed 's/[gp]*cc\(-.*\)*//'` RANLIB=$(which ${_guess}ranlib ranlib 2> /dev/null | grep ^/ | head -n 1) if [ "$RANLIB" = '' ] then echo 'none' return 1 fi echo $RANLIB return 0 fi } test_pkgconfig() { echo -n "checking for pkg-config... " PKG_CONFIG=$(which pkg-config false 2> /dev/null | grep ^/ | head -n 1) if $PKG_CONFIG --help > /dev/null 2> /dev/null then echo $PKG_CONFIG return 0 else echo no return 1 fi } test_sysname() { echo -n "checking for sysname... " SYSNAME=$(uname -s) echo "$SYSNAME" return 0 } test_crosscompile() { echo -n 'checking if we cross compile... ' if $CROSS_COMPILE then echo yes echo -n "checking for exec helper... " if [ "$EXEC_HELPER" = '' ] then if $TARGET_WIN32 then EXEC_HELPER=$(which wine 2> /dev/null | grep ^/ | head -n 1) if [ "$EXEC_HELPER" = '' ] then echo 'none (please install wine)' else echo "$EXEC_HELPER" fi else echo 'none (unknown)' fi else echo "$EXEC_HELPER" fi echo -n "checking for sysname of target... " if $TARGET_CYGWIN then SYSNAME=cygwin elif $TARGET_WIN32 then SYSNAME=win32 else SYSNAME=unknown fi echo "$SYSNAME" return 0 else echo no return 1 fi } test_wextra() { # Check for -Wextra #Wextra echo -n "checking if compiler supports -Wextra... " echo 'int main (void) { return 0; }' > $TF_C if $CCTF -Wextra 2> /dev/null; then echo yes Wextra=true return 0 else echo no Wextra=false return 1 fi } test_cp_v() { echo -n 'checking if cp supports -v... ' if cp -v --help > /dev/null 2> /dev/null then echo "cp_v=-v" >&4 echo yes return 0 else echo "cp_v=" >&4 echo no return 1 fi } test_bin_format() { echo -n "checking for binary format... " echo "TEST BIN FORMAT:" >&5 { echo "#include " echo echo "int main (void) {" echo " char buf[512];" echo " size_t len;" echo echo " len = fread(buf, 1, sizeof(buf), stdin);" echo " if ( len < 4 )" echo " return 1;" echo echo " if ( buf[0] == '\\177' && buf[1] == 'E' && buf[2] == 'L' && buf[3] == 'F' ) {" echo " printf(\"ELF%c\", (char)10);" echo " return 0;" echo " }" echo echo " if ( buf[0] == 'M' && buf[1] == 'Z' ) {" echo " printf(\"MZ%c\", (char)10);" echo " return 0;" echo " }" echo echo " return 1;" echo "}" } > $TF_C echo "--- BEGIN OF CODE BLOCK ---" >&5 cat $TF_C >&5 echo "--- END OF CODE BLOCK ---" >&5 echo "BIN FORMAT() HAS COMPILER/LINKER OUTPUT:" >&5 echo "--- BEGIN OF CHILD OUTPUT BLOCK ---" >&5 $CCTF >&5 2>&5; R=$? echo "--- END OF CHILD OUTPUT BLOCK ---" >&5 if [ "$R" = '0' ] then BIN_FORMAT=`$EXEC_HELPER $TF_E < $TF_E 2> /dev/null` R=$? if [ "$R" = '0' ] then echo "$BIN_FORMAT" echo "BIN FORMAT() IS '$BIN_FORMAT'" >&5 return 0 else BIN_FORMAT=unknown echo 'unknown' echo "BIN FORMAT() NOT KNOWN" >&5 return 1 fi else BIN_FORMAT=unknown echo 'unknown' echo "BIN FORMAT() NOT KNOWN" >&5 return 1 fi } test_linkdeps() { if [ "$LINK_DEPS" = 'auto' ] then if [ "$BIN_FORMAT" = 'ELF' ] then LINK_DEPS='indirect' else LINK_DEPS='full' fi fi echo "LINK_DEPS=$LINK_DEPS" >&4 echo "checking for linkage model... $LINK_DEPS" return 0 } test_lib () { _have_libs=false _have_headers=false _defs='' echo > $TF_C $NEED_GNU_SOURCE && _defs="$_defs -D_GNU_SOURCE" name="$1" last_tested_object="$name" echo -n "checking for $name... " echo "TEST LIB: $name" >&5 shift; if [ "$infotext" = '' ] then _info='' else _info=" ($infotext)" fi LIBS='' while [ "$1" != '--' ] do echo "LIB($name) HAS LIB INFO: $1" >&5 case "$1" in 'c'|'-lc') :; # no need to do anything ;; '-'*) LIBS="$LIBS $1" _have_libs=true ;; *) LIBS="$LIBS -l$1" _have_libs=true ;; esac shift; done shift; echo "LIB($name) IS TESTED USING LIBS: $LIBS" >&5 while [ "$1" != '' ] do _h="$1"; shift; _envname=`echo "$_h" | to_escaped` eval "_t=\$libname_$_envname" echo "LIB($name) DEPENDS ON $_h($_envname) with state '$_t'" >&5 if [ "$_t" = 'false' ] then echo "// not including <$_h> as it was tested as not present" >> $TF_C else echo "#include <$_h>" >> $TF_C _have_headers=true fi done echo 'int main (void) { return 0; }' >> $TF_C if [ "$_have_libs" = 'false' -a "$_have_headers" = 'false' ] then echo "no (nothing left to test)$_info" echo "LIB($name) HAS NOTHING TO TEST" >&5 return 1 fi echo "LIB($name) IS TESTED USING TEST CODE:" >&5 echo "--- BEGIN OF CODE BLOCK ---" >&5 cat $TF_C >&5 echo "--- END OF CODE BLOCK ---" >&5 echo "LIB($name) HAS COMPILER/LINKER OUTPUT:" >&5 echo "--- BEGIN OF CHILD OUTPUT BLOCK ---" >&5 $CCTF $_defs $LIBS >&5 2>&5; R=$? echo "--- END OF CHILD OUTPUT BLOCK ---" >&5 if [ "$R" = '0' ] then echo "yes$_info" echo "LIB($name) WAS FOUND" >&5 else echo "no$_info" echo "LIB($name) NOT FOUND" >&5 fi return $R } test_lib_defmake () { def="$1" subdir="$2" shift shift name="$1" lib="$2" shift echo "TEST LIB: $name" >&5 [ "$subdir" = '%' ] && subdir='' envlib=`echo "$lib" | cut -d/ -f1 | to_escaped` envname=`echo "$name" | to_escaped` eval "envname2envlib_$envname=\$envlib" if [ "$envlib" = 'c' ] then envlib="$envname" fi echo "LIB($name) HAS envlib='$envlib', envname='$envname'" >&5 if [ "$lib" != '--' ] then echo "EVAL: _no=\$no_lib_$envlib" >&5 eval _no="\$no_lib_$envlib"; $MINIMAL && _no='XXX' if [ "$_no" != '' ] then echo "checking for $name... disabled by user" echo "LIB($name) IS DISABLED BY USER" >&5 [ "$subdir" != '' ] && \ echo "subdir_$subdir=" >&4 echo "lib_$envlib=" >&4 eval "libname_$envname=false" return; fi fi lib="$lib/" libn=`echo $lib | cut -d/ -f1` is_fatal=`echo $lib | cut -d/ -f2` lib="$libn" # echo "is_fatal(i)=$is_fatal" >&5 if [ "$is_fatal" = '' -o "$is_fatal" = 'no' -o "$is_fatal" = 'false' ] then is_fatal=false else is_fatal=true shift; # maybe we have a pkg name, not a lib fi echo "LIB($name) HAS FATAL FLAG SET TO $is_fatal" >&5 # echo "is_fatal(b)=$is_fatal" >&5 LIBS=$($PKG_CONFIG --silence-errors --cflags --libs $lib 2> /dev/null) if [ "$?" != '0' ] then if $is_fatal then echo "checking for $name... no (fatal config errors)" echo "LIB($name) HAS FATAL ERRORS" >&5 echo "LIB($name) NOT FOUND" >&5 [ "$subdir" != '' ] && \ echo "subdir_$subdir=" >&4 echo "lib_$envlib=" >&4 return fi LIBS="-l$lib" fi echo "LIB($name) HAS LIBS: $LIBS" >&5 if test_lib "$name" $LIBS "$@" then subdir_var='subdir_'"`echo $subdir | to_escaped`" echo "#define $def" >&3 [ "$subdir" != '' ] && \ echo "$subdir_var=$subdir" >&4 [ "$lib" != 'c' ] && \ echo "lib_$envlib=$LIBS" >&4 if [ "$lib" != 'c' ] then eval "lib_$envlib='$LIBS'" else echo "LIB($name) SETS libname_$envname=true" >&5 eval "libname_$envname=true" fi return 0 else [ "$subdir" != '' ] && \ echo "subdir_$subdir=" >&4 [ "$lib" != 'c' ] && \ echo "lib_$envlib=" >&4 echo "LIB($name) SETS libname_$envname=false" >&5 eval "libname_$envname=false" return 1 fi echo >&5 echo >&5 } test_tool_defmake () { DEF="$1" NAME="$2" shift; shift; echo -n "checking for $NAME... " echo "TEST TOOL: $NAME" >&5 if $RUNTIME_DETECT then echo "$1 (runtime detect)" echo "TOOL($NAME) WILL BE RUNTIME DETECTED" >&5 echo "#define $DEF "\""$1"\" >&3 return 0 elif $MINIMAL then echo "disabled by user (minimalstic build)" echo "TOOL($NAME) IS DISABLED BY USER" >&5 return 1 else LIST=$(which "$@" 2> /dev/null | grep ^/ | head -n 1) if [ "$LIST" = '' ] then echo 'no' echo "TOOL($NAME) NOT FOUND" >&5 return 1 else echo $LIST echo "#define $DEF "\""$LIST"\" >&3 echo "TOOL($NAME) IS AT $LIST" >&5 return 0 fi fi } test_func_defmake () { _defs='' DEF="$1" NAME="$2" shift; shift; echo -n "checking for $NAME()... " CALL="$1" shift; $NEED_GNU_SOURCE && _defs="$_defs -D_GNU_SOURCE" if [ "$infotext" = '' ] then _info='' else _info=" ($infotext)" fi LIBS='' _funcname=`echo "$NAME" | to_escaped` while [ "$1" != '--' ] do case "$1" in 'c'|'-lc') :; # no need to do anything ;; '-'*) LIBS="$LIBS $1" ;; *) LIBS="-l$1" ;; esac shift; done shift; # skip '--' echo "TEST FUNCTION: $NAME" >&5 { while [ "$1" != '' ] do _h="$1"; shift; _envname=`echo "$_h" | to_escaped` eval "_t=\$libname_$_envname" echo "LIB($name) DEPENDS ON $_h($_envname) with state '$_t'" >&5 if [ "$_t" = 'false' ] then echo "// not including <$_h> as it was tested as not present" else echo "#include <$_h>" fi done echo 'int main (void) {' echo " $CALL;" echo ' return 0;' echo '}' } > $TF_C echo "--- BEGIN OF CODE BLOCK ---" >&5 cat $TF_C >&5 echo "--- END OF CODE BLOCK ---" >&5 echo "FUNCTION($NAME) HAS COMPILER/LINKER OUTPUT:" >&5 echo "--- BEGIN OF CHILD OUTPUT BLOCK ---" >&5 $CCTF $_defs $LIBS >&5 2>&5; R=$? echo "--- END OF CHILD OUTPUT BLOCK ---" >&5 if [ "$R" = '0' ] then eval funcname_$_funcname=true echo "#define $DEF" >&3 echo "FUNCTION($NAME) IS OK" >&5 echo "yes$_info" return 0 else eval funcname_$_funcname=false echo "FUNCTION($NAME) IS NOT OK" >&5 echo "no$_info" return 1 fi } test_const_defmake () { DEF="$1" NAME="$2" shift; shift; echo -n "checking for constant $NAME... " TYPE="$1" CONST="$2" shift; shift; LIBS='' while [ "$1" != '--' ] do case "$1" in 'c'|'-lc') :; # no need to do anything ;; '-'*) LIBS="$LIBS $1" ;; *) LIBS="-l$1" ;; esac shift; done shift; # skip '--' echo "TEST CONST: $NAME" >&5 { while [ "$1" != '' ] do _h="$1"; shift; _envname=`echo "$_h" | to_escaped` eval "_t=\$libname_$_envname" echo "LIB($name) DEPENDS ON $_h($_envname) with state '$_t'" >&5 if [ "$_t" = 'false' ] then echo "// not including <$_h> as it was tested as not present" else echo "#include <$_h>" fi done case "$TYPE" in ':int') _type='int' ;; ':float') _type='float' ;; ':ptr') _type='void *' ;; *) _type="$TYPE" ;; esac echo 'int main (void) {' echo " $_type x;" echo " x = ($_type)$CONST;" echo ' return 0;' echo '}' } > $TF_C echo "--- BEGIN OF CODE BLOCK ---" >&5 cat $TF_C >&5 echo "--- END OF CODE BLOCK ---" >&5 echo "CONST($NAME) HAS COMPILER/LINKER OUTPUT:" >&5 echo "--- BEGIN OF CHILD OUTPUT BLOCK ---" >&5 $CCTF $LIBS >&5 2>&5; R=$? echo "--- END OF CHILD OUTPUT BLOCK ---" >&5 if [ "$R" = '0' ] then echo "#define $DEF" >&3 echo "CONST($NAME) IS OK" >&5 echo yes return 0 else echo "CONST($NAME) IS NOT OK" >&5 echo no return 1 fi } test_var_defmake () { DEF="$1" NAME="$2" shift; shift; echo -n "checking for global variable $NAME... " TYPE="$1" VAR="$2" shift; shift; LIBS='' while [ "$1" != '--' ] do case "$1" in 'c'|'-lc') :; # no need to do anything ;; '-'*) LIBS="$LIBS $1" ;; *) LIBS="-l$1" ;; esac shift; done shift; # skip '--' echo "TEST VAR: $NAME" >&5 { while [ "$1" != '' ] do _h="$1"; shift; _envname=`echo "$_h" | to_escaped` eval "_t=\$libname_$_envname" echo "LIB($name) DEPENDS ON $_h($_envname) with state '$_t'" >&5 if [ "$_t" = 'false' ] then echo "// not including <$_h> as it was tested as not present" else echo "#include <$_h>" fi done case "$TYPE" in ':int') _type='int' ;; ':float') _type='float' ;; ':ptr') _type='void *' ;; *) _type="$TYPE" ;; esac echo 'int main (void) {' echo " $_type x;" echo " x = ($_type)$VAR;" echo " $VAR = x;" echo ' return 0;' echo '}' } > $TF_C echo "--- BEGIN OF CODE BLOCK ---" >&5 cat $TF_C >&5 echo "--- END OF CODE BLOCK ---" >&5 echo "VAR($NAME) HAS COMPILER/LINKER OUTPUT:" >&5 echo "--- BEGIN OF CHILD OUTPUT BLOCK ---" >&5 $CCTF $LIBS >&5 2>&5; R=$? echo "--- END OF CHILD OUTPUT BLOCK ---" >&5 if [ "$R" = '0' ] then echo "#define $DEF" >&3 echo "VAR($NAME) IS OK" >&5 echo yes return 0 else echo "VAR($NAME) IS NOT OK" >&5 echo no return 1 fi } test_version () { DEF="$1" NAME="$2" PKGNAME="$3" echo -n "checking for version of $NAME... " _ver=$($PKG_CONFIG --modversion $PKGNAME 2> /dev/null) if [ "$_ver" = '' ] then _ver=unknown fi echo $_ver _ver_def=$(echo $_ver | to_escaped | to_upper) echo "#define ${DEF}_$_ver_def" >&3 echo "$_ver" | if grep '^[0-9]*\.[0-9]*\.[0-9]*$' > /dev/null then _ver_vdef=$(echo "$_ver" | sed 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]\)*$/_ROAR_MKVERSION(\1, \2, \3)/') echo "#define ${DEF} $_ver_vdef" >&3 else echo "#define ${DEF} 0" >&3 fi return 0 } test_type () { DEF="$1" NAME="$2" INITVAL="$3" DASHDASH="$4" shift; shift; if [ "$#" -ge '2' ] then shift; shift; fi HEADERS="stdint.h string.h unistd.h sys/types.h $*" #including headers here let #them get checked for presence. [ "$INITVAL" = '' ] && INITVAL='0' echo -n "checking for type $NAME... " echo "TEST TYPE: $NAME" >&5 echo "// type test for type $NAME" > $TF_C # need a clean file, write something for _h in $HEADERS do _envname=`echo "$_h" | to_escaped` eval "_t=\$libname_$_envname" echo "TYPE($NAME) DEPENDS ON $_h($_envname) with state '$_t'" >&5 if [ "$_t" = 'false' ] then echo "// not including <$_h> as it was tested as not present" >> $TF_C else echo "#include <$_h>" >> $TF_C fi done echo "int main (void) { $NAME _var = $INITVAL; return 0; }" >> $TF_C echo "--- BEGIN OF CODE BLOCK ---" >&5 cat $TF_C >&5 echo "--- END OF CODE BLOCK ---" >&5 echo "TYPE($NAME) HAS COMPILER/LINKER OUTPUT:" >&5 echo "--- BEGIN OF CHILD OUTPUT BLOCK ---" >&5 $CCTF >&5 2>&5; R=$? echo "--- END OF CHILD OUTPUT BLOCK ---" >&5 if [ "$R" = '0' ] then echo "#define $DEF" >&3 echo 'ok' echo "TYPE($NAME) IS OK" >&5 return 0 else echo 'not found' echo "TYPE($NAME) NOT FOUND" >&5 return 1 fi } test_pa_type () { DEF="$1" NAME="$2" TYPE="$3" V0="$4" V1="$5" TEST="$6" shift; shift; shift; shift; shift; shift; HEADER="$*" RS='%s' case "$TYPE" in 'type') MSG="checking for type of $NAME()... " ;; 'args:'*) MSG="checking for argument types of $NAME()... " RS=`echo "$TYPE" | cut -d: -f2` ;; esac; echo -n "$MSG" echo '#include ' > $TF_C for _h in $HEADERS do echo "#include <$_h>" >> $TF_C done echo '#include ' >> $TF_C echo 'int main (void) { return 0; }' >> $TF_C echo "$TEST" >> $TF_C if $CCTF 2> /dev/null; then R="$V0" else R="$V1" fi echo "#define $DEF $R" >&3 printf "$RS\n" "$R" return 0 } test_winsock() { test_lib_defmake ${ROAR_BUILDSYSTEM_DEFPREFIX}HAVE_LIBWSOCK32 % WinSockP0 wsock32 -- winsock2.h test_lib_defmake ${ROAR_BUILDSYSTEM_DEFPREFIX}HAVE_LIBWS2_32 % WinSockP1 ws2_32 -- winsock2.h echo 'NETLIBS += $(lib_wsock32) $(lib_ws2_32)' >&4 return 0 } test_netlibs() { __old_MINIMAL=$MINIMAL MINIMAL=false test_winsock MINIMAL=$__old_MINIMAL return 0 } test_pthread() { echo -n 'checking for -pthread... ' echo '#include ' > $TF_C echo 'int main (void) { pthread_self(); return 0; }' >> $TF_C if $CCTF -pthread 2> /dev/null; then echo "#define ${ROAR_BUILDSYSTEM_DEFPREFIX}HAVE_CC_PTHREAD_OPTION" >&3 echo 'opt_pthread=-pthread' >&4 echo 'pthread=$(opt_pthread)' >&4 echo yes _ret=0 else echo 'opt_pthread=' >&4 echo 'pthread=$(lib_pthread)' >&4 echo no test_lib_defmake ${ROAR_BUILDSYSTEM_DEFPREFIX}HAVE_LIBPTHREAD % libpthread pthread -- pthread.h _ret=$? fi [ "$_ret" = '0' ] && echo "#define ${ROAR_BUILDSYSTEM_DEFPREFIX}HAVE_PTHREAD" >&3 return $_ret } #ll roaraudio-1.0beta11/build-system/configure.vars0000644000175000017500000000410412101115726017751 0ustar phiphi#!/bin/false # vim:ft=sh # Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2012 # # This file is part of roard a part of RoarAudio, # a cross-platform sound system for both, home and professional use. # See README for details. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 # as published by the Free Software Foundation. # # RoarAudio is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # wine prints errors to stdout so stderr redirects do not work. # To avoid common problems with wine and $LANG/$LC_* we just reset them. LANG=C LC_CTYPE=C LC_NUMERIC=C LC_TIME=C LC_COLLATE=C LC_MONETARY=C DISTRIBUTION_VERSION_STRING='' DEV_VENDOR='' DEV_VENDOR_NAME='' DEV_VENDOR_STRING='' STD_VENDOR='' STD_VENDOR_NAME='' STD_VENDOR_STRING='' TF_C=testit.c TF_E=./testit LDPATH='' INCPATH='' OPTI_O=2 DEBUG_g='-g' CROSS_COMPILE=false SYSNAME='unknown' SHARED='-shared' SHARED_CF='' SHARED_SUFFIX='.so' fPIC=true Wextra=false rdynamic=true MMCU='' LINK_DEPS=auto PKG_CONFIG=false NEED_GNU_SOURCE=false PREFIX='/usr/local' PREFIX_BIN='' PREFIX_SBIN='' PREFIX_LIB='' PREFIX_INC='' PREFIX_MAN='' PREFIX_PC='' PREFIX_CKPORT='' PREFIX_SYSCONF='/etc' PREFIX_DEV='/dev' PREFIX_DOC='' PREFIX_TMP='/tmp' PREFIX_VAR='/var' PREFIX_CACHE='' PREFIX_DATA='' PREFIX_LOCK='' PREFIX_LOG='' PREFIX_MAIL='' PREFIX_RUN='' PREFIX_SPOOL='' ROOT_UID='' HAVE_MAIN_ARGS=true MINIMAL=false BETA=true EXPERIMENTAL=true TARGET_WIN32=false TARGET_MICROCONTROLLER=false TARGET_CYGWIN=false TARGET_TYPE='generic' EXEC_HELPER='' IMPLIB='' # other stuff we need to reset: infotext='' last_tested_object='' CCTF="false" _CARGS="$@"; #ll roaraudio-1.0beta11/AUTHORS0000644000175000017500000000324211765566463013553 0ustar phiphi--- Main Developer: Main work: libs, roard, applications: * Philipp 'ph3-der-loewe' Schafft --- Maintainer: archlinux: Hans-Kristian Arntzen OpenBSD : janus --- Old Maintainers: archlinux: kalasmannen --- Code contributors --- * Daniel Duntemann * Hans-Kristian 'maister' Arntzen --- With patches from --- * Simon Matter, MT Invoca Systems --- Testers: Many people around the world. --- Debian init script: * Javier Fernandez-Sanguino --- G.711 Codec vector tables: * Sun Microsystems, Inc. 2550 Garcia Avenue Mountain View, California 94043 --- Crypto Layer: * Steve Reid --- gstreamer code: * Arwed v. Merkatz * David A. Schleef * Erik Walthinsen * Richard Boulton --- Compatibility layers are based on code/prototypes/... by: * libroararts: - Stefan Westerfeld * libroaresd: - Eric B. Mitchell (aka 'Ricdude) - Carsten 'The Rasterman' Haitzler - Kjartan Maraas - Frederic Crozat - Stephen Browne - Timur Bakeyev - Yo Ric Dude - Manish Singh - Frank Belew - Myth - Isaac Richards * libroaross: - IEEE/POSIX - 4Front Technologies (Open Sound System) - Operating system vendors - ...and others * libroarpulse: - Lennart Poettering - Pierre Ossman * libroarsndio: - Alexandre Ratchov * libroaryiff: - Tara Milana - WolfPack Entertainment * libroarrsound: - Hans-Kristian 'maister' Arntzen roaraudio-1.0beta11/COPYING0000644000175000017500000000035711055631212013513 0ustar phiphiMost but not all software in this packet are under GNU GPL. Some is under GNU LGPL. See the license statments at the top of each file for more information. The licenses can be found in COPYING.* seem them for details on the terms of use. roaraudio-1.0beta11/COPYING.gplv20000644000175000017500000004310311415443753014553 0ustar phiphi GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. roaraudio-1.0beta11/COPYING.gplv30000644000175000017500000010451311026257360014552 0ustar phiphi GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . roaraudio-1.0beta11/COPYING.lgplv30000644000175000017500000001672711055603645014742 0ustar phiphi GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. roaraudio-1.0beta11/ChangeLog0000644000175000017500000007401112267551515014245 0ustar phiphiv. 1.0beta11 - Tue Jan 21 2014 21:04 CET Prereleases: 0: Sat Jan 18 2014 22:52 CET * Updated checks on commandlion parameters (Closes: DEB#716264, DEB#716251, DEB#716245, DEB#716240) * Marked roarcatvio as obsolete. Added all unique features to roarcatplay. * Code cleanup. * Removed roarfish(1) (Closes: #339) * Implemented read-only support for RAUM files using uniraum, support using libRAUM got disabled (See #233). * Added support for setting a default device for roard at compile time. * Removed OpenSSL support (See: #366) * Also use uname() and hostid for seeding nonce generator. * Updates of copyright and license headers v. 1.0beta10 - Tue Oct 15 2013 12:03 CEST Prereleases: 0: Mon Sep 30 2013 21:15 CEST * Added build summery feature to RABS and configure script. * Moved away from roar_libroar_get_path_static(). * Added GPIO service. * Added GPIO driver: piface. * Added roard driver: i2cdmx. v. 1.0beta9 - Mon Feb 18 2013 23:28 CET Prereleases: 0: Tue Jan 15 2013 14:47 CET 1: Thu Feb 14 2013 17:54 CET * Updated manpages. * Mark roarsockconnect, roartypes and roarfish as obsolete. * Removed unused checks in configure. Improves build speed slightly. * Re-ported to OpenBSD. * Made build system tests return correct error codes. * Improved CSI: Make it easier to register and access services. * Allow seperation of plugin's stdvios (See: #296) * Added half of the support for AppSched Triggers ABOUT, HELP and PREFERENCES. * Avoid %llX on win32 (Closes: #271) * Added support for +fork on win32 (Closes: #337) * Fixed symlink creation on win32 (Closes: #328) * Added support to disable debugging information (Closes: #338) * Corrected default paths (Closes: #345) (pr1) * Also set PATH so tests works on win32 as well (Closes: #341) (pr1) * Use 16 bit mixers in roard on win32 to avoid problems with wmm (Closes: #340) (pr1) * Corrected symlink creation to avoid problems on non-win32 (Closes: #346) (pr1) * Added new plugin service-client (pr1) v. 1.0beta8 - Mon Dec 10 2012 12:42 CET Prereleases: 0: Fri Dec 07 2012 26:32 CET * Changed plugin ABI version number for roard. * Removed check for libuuid as it is no longer used. * Fixed roard's 'dmx' driver. * Added new plugins: dmx-random, dmx-waveform, protocol-http. * Added CPI support to roarpluginrunner. * Moved protocol support into new plugins protocol-esound, protocol-rplay and protocol-gopher (Closes: #311) * Allow RAT builds on systems with full linkage. * Provide a more common interface for path config. * Improved env API. * Added support for configureable memmgr backend (Closes: #334) * Moved notify debugging support out of roard into plugin debug-notify. * Added support to roar-config to check versions (Closes: #336) * Improved build system a lot. v. 1.0beta7 - Tue Oct 23 2012 23:28 CEST Prereleases: 0: Tue Oct 16 2012 21:57 CEST * Improved kv API. * Avoid warning about failed memlock on win32 (Closes: #329) * Changed plugin ABI version number for roard. * Added support for v3 and v5 UUIDs. * Added new configure option '--root' (Closes: #326) * Improved roar-config. * Install parts from build system (Closes: #325) * Re-ported to win32 (Closes: #330, #331) * Fixed segfault caused by strstr() in low level socket interface. * Disabled gcrypt support by default. * Improved handling of mixing OpenSSL enabled applications with libroar without OpenSSL support. * Added scheduler (mainly for IO events) (Closes: #206) v. 1.0beta6 - Fri Sep 21 2012 18:03 CEST Prereleases: 0: Mon Sep 17 2012 20:42 CEST * Fixed memory leak in hash framwork. Affacted RNG (Closes: #310) * Updated CMD VIO to no longer eat more than needed. Helps resolving a endless loop in rpld. * Added audio clock to roard's libshout driver 'shout'. * Corrected typos. * Disabled building with libFLAC when using --without-beta (See: #306) * Removed roard's sched support (Closes: #277) * Removed support for roard's proto support (replaced by CPI) (Closes: #278) * Changed default linkage model for ELF to indirect (Closes: #281) * Updated VIO CMD to work around kernel bugs in Linux kernel. * Improved kstore API (See: #317) * Updated list of error values. * Optimized roar_buffer_set_len() for incremental buffer size growth (Closes: #284) * Added RAT test 'buffer_set_len'. * Added compiler checks for printf() like format strings. v. 1.0beta5 - Mon Aug 20 2012 23:52 CEST Prereleases: 0: Sat Aug 18 2012 18:10 CEST * Fixed pa_xfree() (Closes: #293) * Allow passing of extra parameters to cdrivers (Closes: #290) * Converted roard's protocol-irc plugin to CPI (Closes: #295) * Updated protocol magic numbers (See: #262) * Implemented watchdog (Closes: #291) * Added meta generes (See: #301) * Fixed metadata handling in meta.c. * Added support for RePlayGain (RPG) control (See: #300) * Fixed compiler warnings about roar_meta_strtype(3) (Closes: #305) v. 1.0beta4 - Mon Aug 06 2012 16:43 CEST Prereleases: 0: Sat Jul 28 2012 26:14 CEST; 1: Wed Aug 01 2012 12:52 CEST * Stop building roard with -rdynamic on win32 (Closes: #269) * Renamed protocol plugins for roard to protocol-* (Closes: #258) * roard now tries to auto load missing protocols as plugins (Closes: #275) * Improved tic-tac-toe plugin. * Improved roarclientpass in execed mode. * Improved support in roard for client passing. * Disable building of roard plugins on windows as PE doesn't support them (Closes: #274) * Support a common protocol interface (Closes: #257) * Converted roard plugins to universal where possible (Closes: #256) * Corrected critical bug in UUID support (compare function overwrote arguments) (Closes: #276) * Updated manpages. * Moved strselcmp() and strseltok() to libroar (Closes: #285) (pr1) * Added roar_buffer_moveintoqueue() (Closes: #283) (pr1) * Typo corrections (Closes: #282) (pr1) * Updated common protocol interface (Closes: #257, #256) (pr1) * Handle super long client names well (Closes: #286) (pr1) v. 1.0beta3 - Sun Jul 15 2012 26:08 CEST Prereleases: 0: Tue Jul 10 2012 24:12 CEST * Try use-execed workaround also on UNIX Domain Sockets (Closes: #207) * Implemented SHA1 support (Closes: #232) * Fixed usage of -R/-B/-C/-E as well as --aiprofile in roarclients (Closes: #176) * Done more hardending work. * Improved error handling (including on win32) (Closes: #235, #255) * Added small DTMF library. * Added filter based on Goertzel algorithm. v. 1.0beta2 - Wed Jun 06 2012 19:56 CEST Prereleases: 0: Fri Jun 01 2012 29:13 CEST * ROAR_DL_PLUGIN_START() now checks para structure (Closes: #236) * Added support for AutoAppSched to the plugin container. * Added simple UUID interface (Closes: #230) * Improved random number generator. * Added a way to register plugin parts with a universal API (Closes: #245) * Updated debian init script (Closes: #183) * Fixed detection of dynamic loader on *BSD. v. 1.0beta1 - Sat May 12 2012 11:49 CEST Prereleases: 0: Mon Apr 23 2012 11:59 CEST; 1: Sun May 06 2012 17:32 CEST * Added support to load plugins from search path * Added key based store (Closes: #199) * Improved plugincontainer. * Improved downmix filter. * Fixed support for chardev based servers. * Improved error handling (mainly in HTTP VIO support). * Added NO_RETEST flag to roar_vio_select(). * Seperated roard and universal plugins. * Added plugins: tic-tac-toe (roard) and helloworld (universal). * Some small, general improvements to roarclients. * Changed roard plugin ABI version to 1.0beta1. * Corrected usage of -Wextra (pr1). * Updated build options for RAT (pr1). * Work around bugs in win32 while using stdvios (pr1). * Added support to load plugins on win32 (pr1). * Added support for quotes strings to kv split and roardl para argument splitting (pr1). * Added support for an application mode in roarpluginrunner (pr1). * Improved plugincontainer (pr1). * Added manpages for roarpluginapplication and roarpluginrunner (pr1). v. 1.0beta0 - Fri Mar 16 2012 19:39 CET Prereleases: 0: Sun Feb 05 2012 16:25 CET; 1: Tue Feb 14 2012 18:38 CET; 2: Tue Feb 21 2012 14:17 CET * Updated API (SONAME change) (Closes: #184, #185, #128, #135, #134, #133, #129, #188, #126, #127) * Do not set errno to zero in ogg_vorbis codec filter (Closes: #191) * Updated data types for struct roar_audio_info (Closes: #189) * Removed old functions from API (Closes: #186, #187, #130) * Removed old roarclients (See: #130) * Improved plugin loader a lot (Closes: #190) * Added VIO/DSTR for SOCKS proxy (See: #187) * Added support for stream direction RECPLAY. * Ported to Win32 (again...) (pr1) * Updated debian init script (pr1) * Typos (Closes: #192) (pr2) * Support MUTE flag on output streams as well (Closes: #194) (pr2) * Fixed bug in MIDI clock (Closes: #193) (pr2) v. 0.4 - Fri Nov 11 2011 20:12 CET Prereleases: 0: Sun Oct 02 2011 16:40 CEST; 1: Fri Oct 28 2011 27:54 CEST; 2: Fri Nov 04 2011 15:37 CET * Fixed segfaul in FLAC cf (Closes: #177) * Fixed invalid pointer aliasing (Closes: #178) * Fixed segfaul in PortAudio driver(v19) if no device is found. * Fixed invalid pointer aliasing in filter code (pr1) * Fixed remote a local buffer overflow in client to message converter code as well as a remote attackable overflow in message to client converter code (pr1) * Updated error handling (pr1) * Moved error frame handling into proto functions (pr1) * Updated manpages (pr1) * Updated filters to support 8 and 32 bit mode as well (pr1) * Re-wrote ALSA plugin (pr1) * Updated ports to minimal, win32 and avr (pr2) v. 0.4rc0 - Mon Sep 05 2011 15:25 CEST Prereleases: 0: Fri Aug 18 2011 27:37 CEST * Fixed endlessloop in MIDI subsystem (Closes: #137) * Added new error codes (mostly from POSIX) * Corrected targets for complibs symlinks (Closes: #168) * roard now starts up in 32 bit mode by default. (configure option has been addded) (Closes: #48) * Updated debian init script (Closes: #169, #171) * Started to use compiler attributes (Also see: #130) v. 0.4beta7 - Sun Jul 10 2011 13:26 CEST Prereleases: 0: Mon Jun 20 2011 18:36 CEST * Updated roar_panic() (Closes: #132) * Updated roar_reset() (Closes: #131) * Added memory corruption and double free detection to buffer API. * Updated drivers to use new sync stream selection logic correctly (Closes: #136) * Converted most roarclients to to use VS API (See: #87) * Added support for ROAR_CMD_GETTIMEOFDAY * Added Meta Data types DISCNUMBER, SOURCEMEDIA, LABEL, LABELNO * Added manpages for all VS functions (Closing: #4) * Some updates and small fixes for the win32 stuff. * Support non-blocking latency request in VS API (Closes: #97) v. 0.4beta6 - Mon May 23 2011 19:49 CEST Prereleases: 0: Tue May 17 2011 16:33 CEST; 1: Sat May 21 2011 17:18 CEST * Added new error codes. * Improved listing of audio profiles. * Added functions to access symbolic names for audio info parameters (Closes: #51) * added VIOs and DSTR elements: full: * Some cleanup of roarclients to fix ckport warnings. * Fixed warning on FreeBSD about tempfile in ast2roar (Closes: #47) * Added support for role based handling in roard (Closes: #49) * Added support for non-stream execs (Closes: #32) * Done some libroardsp header cleanup (Closes: #36) * Use zlib for gzip and zlib format (Closes: #29) * Added simple memmgr (memory Manager) code. * Updated libroarpulse, includes converting libroarpulse-simple to VS API. * Added support for OpenBSD sndio's new TCP connection syntax. * Corrected linkage in indrect mode (pr1) v. 0.4beta5 - Tue Apr 26 2011 08:42 CEST Prereleases: 0: Sun Apr 17 2011 20:40 CEST * Started with support for non-blocking server locating attempts. * Speed up SLP lookup without DA by about 6 sec. * Added source radionoise to roard. This is used to generate low energy noise so codecs do not drop to (near) zero bitrate. * Added aRts (artsc) driver to roard. * Removed old -d and friends from roard (Closes: #122) * added support to roard for record streams. * Added commands clientinfo and streaminfo to roarctl. * Added Record Bridge to roard. * Added VIOs and DSTR elements: null:, zero:, nrandom: * Added support for HTTP Basic Auth * Fixed time display of roarvorbis if file has unknown playback length * Auto select a stream if no stream has sync flag. (Closes: #30) * Install ckport database * Updated PortAudio driver for roard (which now supports v.19 API) v. 0.4beta4 - Sun Mar 20 2011 12:15 CET Prereleases: 0: Thu Feb 24 2011 27:36 CET; 1: Mon Mar 14 2011 27:06 CET * Added support for UNMAPPED volume control (Closes: #55) * Better auth type order support (Closes: #6) * Updated configure (Closes: #94, #27) * Disable more stuff in minimal build (Closes: #104) * Added time display to roarvorbis (Closes: #102) * Added support to roarshout to read password form user or file (Closes: #101) * Added IPv6 support * Updated Debian init script (See: DEB#613772) * Added support for use of DECnet and ARP neighbour tables to locate servers (enumdev only at the moment) (pr1) * Added support for a simple trap mechanism (pr1) * Added simple authfile support to roard (pr1) * Moved error string lookup from VS into error.c (pr1) * Added Meta Data types COMPOSER, RIGHTS, ISRC, LANGUAGE, GTIN, PUBLISHER (pr1) * Added Adler32 support (Closes: #123) (pr1) v. 0.4beta3 - Wed Jan 26 2011 23:26 CET Prereleases: 0: Thu Jan 20 2011 19:36 CET * Updated roarvorbis (Closes: #103, See: #87) * Fixed small win32 bugs * Fixed Typos (Closes: #100) * Added basic gopher server to roard. * Added managed latency mode to VS API (Closes: #121) v. 0.4beta2 - Sun Dec 12 2010 10:28 CET Prereleases: 0: Mon Dec 06 2010 24:00 CET; 1: Thu Dec 09 2010 23:30 CET * Announce standards via OpenSLP (Closes: #5) * Updated VS API (Closes: #54, #99, #98) * Added a buffered mode for VS API (Closes: #2, #96) * Added a file mode for VS API (Closes: #3) * Added support for CRC24 (RFC 4880) * Added Base64 support. * Added codecfilter for FLAC (read-only, native FLAC). * Use libroar's MIME Type lookup functions (Closes: #56) * Added RSound's new 32 bit support to libroarrsound * Updated docs * Support dir parameter in OINFO command (Closes: #31) * Corrected error codes in VS API (Closes: #90) * Updated reassigned commands (GET_ACL->AUTHCTL, SET_ACL->ACLCTL) * Updated ring buffer code (Closes: #91) * Fixed a FTBFS error with clang (Closes: #86) * Corrected some typos in manpages (pr1) * Support option to disable OpenSLP (pr1) v. 0.4beta1 - Mon Nov 01 2010 16:14 CET Prereleases: 0: Fri Oct 29 2010 11:14 CEST * Implemented a very general test for types. Needed by win32 port. * Added support to enum servers with roarctl. * Improved server eunm. * Implemented SERVER_INFO command. * Added some basic crypto functions. * Implemented Tiger Hash Algo. * Implemented basic AUTH command. * Implemented CAPS command. * Wrote authfile API. * Changed SONAME version to 1. * Changed buffer interface, no public struct anymore. * Fixed lots of compiler warnings * Added new test system RAT * Added support for single sink mode (Closes: #25) * Implemented atomic flag toggling and flag protection. * Started porting to OpenVMS (See #24) * Escape user input to configure script correctly (Closes: #28) v. 0.4beta0 - Fri Oct 01 2010 13:36 CEST Prereleases: 0: Sun Sep 26 2010 18:29 CEST; 1: Tue Sep 28 2010 22:55 CEST * fixed FTBFS with newer versions of RSound * Added memory locking module to roard * fixed libroaross's select() to work with mplayer * fixed a problem with PASSFH on some systems * Added LTM support to libroar and roard (roard only supports RMS) * Added a lot const keywords * Added notify framework (process internal signals) * Added support for WAIT command * Added support to get a list of possible servers (enumdev) * Added hwmixer support to roard * fixed LD_LIBRARY_PATH bug in roarify (GNU systems only) (pr1) (Closes: DEB#598295, CVE-2010-3363) * fixed matrix pointer bug in libao driver. (pr1) * Some doc updates (final release) v. 0.3 - Sun Aug 22 2010 26:14 CEST Prereleases: 0: Mon Aug 16 2010 29:58 CEST; 1: Fri Aug 20 2010 11:13 CEST * Fixed locking bug with libroaross and Audacity * Added working resampler code thanks to maister. (Closes: DEB#592017) * Changed way to find default driver. * Updated Debian init script * Added VS API * Fixed strange bug in RSound emulation killing streams after long time. * Removed libao and audacious plugins (they are in upstream now) * Added basic bash completion script * Updated ckport database file to match the current libs (pr1) * Wrote more comments in the VS header (pr1) * fixed latency stuff in VS (pr1) v. 0.3beta7 - Fri Jul 23 2010 15:11 CEST Prereleases: 0: Mon Jul 19 2010 12:58 CEST; 1: Mon Jul 19 2010 20:37 CEST; 2: Wed Jul 21 2010 11:07 CEST * Added support for audio profiles * Updated libroarrsound * Added RPlay protocol to roard * Updates of copyright and license headers * Added ckport file * Updated some tools to get away from old, legacy and security relevant function calls * Fixed bug with incorrect number of arguments to roard * Added some more ROAR_INFO()s to roard * Added tool roarclientpass * Corrected Debian init script (pr1) * Fixed problems on Big Endian systems with libdnet (pr2) v. 0.3beta6 - Thu Jun 24 2010 20:47 CEST Prereleases: 0: Fri Jun 11 2010 10:47 CEST; 1: Sat Jun 12 2010 11:07 CEST; 2: Wed Jun 16 2010 12:52 CEST * Added something like select() for VIOs * Fixed a lot warnings * disabled cmd codecfilter by default * Fixed error with roarinterconnect on non-OSS systems * Fixed some problems with minimal builds * Some Copyright fixes * much better VIO support for connections * much better OSS emulation * Updated win32 port * Updated RSound support * fixed pos calc in case of PCM->PCM converting (pr1) * fixed libroarpulse (pr2) v. 0.3beta5 - Sun May 02 2010 12:41 CEST * added tool roardtmf * Support to store server address in X11's root window propertys * some small fixes * wrote a lot more libroarpulse code, some async API clients work now * added compbins for esddsp, artsdsp, audiooss, padsp * splited libroarpulse and libroarpulse-simple * upgraded some code to use VIO * more updates for Debian * fixed init script for Debian and Debian like systems * fixed some mixer stuff, a lot things work better now * added support for notify beeps * updated drivers * updated ROAR_{ERR,WARN,INFO,DBG}() * added syslog support * updated test suit * done a lot work on libroaross * fixed segfault in ALSA plugin * Added support for OSS to roarinterconnect(1) * Added server side RSound Emulation * Added libroarrsound, client side RSound Emulation * Added ALSA driver * Added RSound driver * Added PortAudio driver v. 0.3beta4 - Sat Feb 06 2010 26:02 CET * Applyed patches for Debian * updated roarify to load libs of correct version * updated list of supported versions (complibs) * added header with common units * added support for PulseAudio Simple protocol * added support to libroaross to emulate DMX4Linux (write only) * added DSTR driver to roard * updated librarys' soname * do not link OpenSSL by default (licence incompatible?) * support for dynamic lib loading, plugin interface * support to for registering DSTR types * moved WinSock things out of main vio.[ch] * support auto-tool --prefix*=* v. 0.3beta3 - Fri Jan 22 2010 22:17 CET * added some aRts/NAS/YIFF/PulseAudio tools to compbins * added support for comp libs to roar-config * added support for uni-directional streams in roarinterconnect * write much better support for config, including codec config * reduced the TCP overhead produced by speex * added support for speex preprocessor * get names of complibs from table, do not guess them * a lot small fixes * moved most of the mixer stuff out of roard into libroardsp * added flags immutable and enhance * test for signal.h * Corrected (DSTR) HTTP Protocol support so servers without headerflush should now work, too. * added protocol support for icy * Added version numbers to lib names * updated manpages * wrote OSS emulation * fixed test scripts v. 0.3beta2 - Mon Oct 05 2009 19:48 CEST * Added prethru flag * Added support to read info about client's network node * Ported libroaresd, libroarartsc * Fixed some problems with EsounD emulation * added support for compatibility binarys * added poll() support to libroarsndio * reject streams of unsupported codec v. 0.3beta1 - Sat Sep 26 2009 25:50 CEST * incremented nummber of streams per client fron 4 to 8 * RIFF WAVE codecfilter uses virtual streams * another set of changed names of parameters in roarctl * Interface to read byteorder of a client from roard * implemented a 'state of stream' var * cleanup, small fixes * added VIO interface to transcoder interface * ask codecfilter of parent in case of new child stream * added 'subsystem' complex: multi subsystem data on single streams * added basic /Radio Data and Trasmitter Control System/. * better support for stereo upmixing * make audio group a optional thing * better support for win32 * wrote WMM driver * better multi protocol support * Support for server side EsounD emulation on win32 v. 0.3beta0 - Sun Sep 06 2009 22:42 CEST * added new stream directions for MIDI and light control * cleanup of client stream struct * added basic light control subsystem * added DMX512 driver * wrote basic MIDI subsystem * added flag 'mute' * added flag 'mmap' * added lib libroarmidi and libroarlight * added OpenSLP support * rewote fillmixbuer2 code * added a roar_conv2() with a more clear API * added support to write pidfile * added support for encoding 32 bit Vorbis streams * added transcoding features in libroardsp * added tool 'roarphone' * added tool 'roarinterconnect' * added simple raw data subsystem * added working support for THRU streams * changed names of parameters in roarctl * added lib libroareio - Extended IO for RoarAudio * Update order of default drivers, now it is: oss, ao, esd, null * cleanup of old sysio driver interface * added server side EsounD emulation * added multi homed support to server * fixed a long outstanding bug with pa_path_get_filename() v. 0.2 - Thu May 21 2009 21:00 * do a some more testings for functions not existing on win32 * init winsock * done a lot fixes in order to get libroar and some clients work on win32 * done a lot cleanup on configure script v. 0.2rc2 - Sun May 17 2009 25:44 * corrected check for GNU peercred * added basic logging support to configure * fixed plugin configures * added and fixed semi-install target on plugins * call plugin configures from main configure * include plugins in Makefile known to work from configure * fixed Makefiles of plugins: added -I../../include, -L../../lib * Make use of pkg-config in plugin configures * corrected possition of -ls on linker commands in most Makefiles * added more explicide linker commands so most things now build with classic BSD make. * devided into components: libs, roard, clients, doc * add toption to set roard's cycle freq * moved a lot things in plugin's configure scripts to a commone one v. 0.2rc1 - Wed May 13 2009 12:05 * Started to port to OpenSolaris * fixed bug in default based sockets, make HTTP VIO from non default port work * got libroarsndio build under OpenBSD 4.5 * do not depend tests in configure on roaraudio.h: fixes some checks on *BSD * renamed member 'fh' of connection struct to '__fh', this breaks all code depending on it so we see how it behaves in case we replace this with a real VIO object in near future * started VIO 2popen interface * fixed exec() on systems with sizeof(int) != sizeof(char*) * do not do unnessesery calls to fdatasync() on sockets * link roarvorbis against libogg and libvorbis * remove need of GNU/Tar like -z on remote system from send-roaraudio * added support for hwmixer flag on OSS and sndio driver * fiexed some typos v. 0.2beta3 - Fri May 01 2009 15:15 * added esdfilt options to roarfilt, esdplay options to roarcatplay * added short options to roarcat/mon/filt as stated in the manpage * updated manpages * also build libroar{,dsp}.a * Changed VIO CTLs in a binary inkompatible way * added support for autoconf flag to OSS driver * added driver for OpenBSD sndio interface * started libroarsndio * added code for plugins: audacirus, mplayer, gst10 * fixed some building problems * added roarify and s start for it's manpage * added stream flags pause and hwmixer v. 0.2beta2 - Fri Mar 27 2009 21:20 * added (dummy) flags autoconf and cleanmeta * added streams_ctl() to server * added support for primary flag as -oO, support for blocks parameter * added (GnuPG) pinentry support. * added support for Ogg Vorbis encoder to set meta data :) * fixed some (minor) bugs, including segfault in vio * added a lot things to the vio interface * added gzip and simple OpenPGP support to vio interface * added a simple pointer stack. * added (OpenSSH) askpass support. * added vio pipe support, currectly pipe() and socketpair() based onse. * test for OpenSSL * added support to VIO open OpenSSL BIOs * added support to read a string and convert it into a VIO stack * added simple VIO stack as VIO pass object * started cleaner VIO Socket implementation * Reduced lib size with --minimal trasticly (>33%!) * Done a lot patches to makeing RoarAudio more portable (also to win32) * moved convert.[ch] and poly.[ch] from libroar to libroardsp * updated AUTHROS, README and check HACKING * added tools/send-roaraudio: tool to send RoarAudio von CVS to a diffrent host in order to test it. * added dist/archlinux and archlinux rc script. v. 0.2beta1 - Mon Feb 23 2009 25:08 * added options --default-codec and --without-cf-cmd to configure script * added some funcs to list of frozen API calls * added sleep command to roarctl * updated roard manpage * fixed a possible segfault within auto codec detection and added support for native flac * fixed some compiler warnings * made roarcat and roarmon 100% esdcat and esdmon compatible * set fragment size for OSS driver * fixed some minor bugs * changed buffer interface a bit to support non buffer alloced buffers v. 0.2beta0 - Wed Feb 04 2009 * use new driver interface as default (finally!) * fixed a bug in roard to not accept new streams in termination state * added support to filters to reset * added basic support to report latency * added vio support for ctl()s * allow overruns in sync output streams * solved double close bug * added support for non-execed streams with client behinde a NAT gateway * use socketpair() for AF_UNIX streams to create a new non-execed stream * got AF_UNIX support back working on OpenBSD * added needed paths for OpenBSD * only use use fsync() if there is no fdatasync() v. 0.1beta5 - Wed Jan 21 2009 * done some patchs to help porting libroar to win32 * made libm optional * added option to configure to build without any optional compontents * added option to configure to give a helper programm to exec tests (e.g. wine) * updated help a bit * fixed roarbidir * added support for sync vio * updated roarfctest * added filter reset command v. 0.1beta4 - Tue Dec 23 2008 * added roar_buffer_shift_out() * changed roarshout to be 100% compatible with oggfwd options * added full support for mu-Law * added VIO support for driver API * changed esd output driver to use new vio driver API * wrote OSS driver * added support for --standby and --auto-standby * write support for stream based drivers, finally! * added -o/-O-/-oO/-oN to roard: stream based output drivers * patched null and raw driver to use VIO interface * ported libao plugin to new VIO interface * added -oP support to mark outputs primary * added ROAR_INSTINT to abstract from __LP64__ * added new trivial filters: Add, Quantifier, Clip * added codecfilter for libfishsound, use it as default for ogg_flac and ogg_speex * added Ogg FLAC and Ogg Speex Magic * added tool roarmonhttp: http streaming tool, CGI or inetd * added writing support for RIFF/WAVE * flag sources as sources * patched some things for cygwin * fixed double-reconnect bug within XMMS plugin * include libao plugin in normal configure/build/install * added passthru for meta streams * fixed a lot small bugs * include basic rc/init script for debian like systems v. 0.1beta3 - Thu Nov 27 2008 * fixed some includes, patch by janus v. 0.1beta2 - Tue Nov 25 2008 * check for __LP64__ * added roaraudio/error.h * added manpages for roar_codec2str() and roar_str2codec() * got some YIFF clients working, including yplay! * added roarcleints/roarradio*: A RoarAudio client which inizialiszes a new source and has buildin HTTP support. * added CDRum support * added writeing support for A-Law * added proxy support for SOCKS4 and 4d, SSH and HTTP CONNECT * improved 32 bit support a lot * checking for IPv6 support, not just assuming it to exist (win32 fix) * updated docs a bit * added install target v. 0.1beta1 - Sun Sep 07 2008 * fixed a lot typos * Added readonly support for A-Law * now also build doc/ * fixed a bug with NetBSD's which * look for pkg-config * look for other tools, added --runtime-detect to configure * Fixed some manpages * added support for passive playback (passfh) * added support for ROAR_ATTACH_SIMPLE * cleaned codec ID #defines a bit up * added CMD PASSFH * get roard build again on MAC OS X * added tool roarcatpassfh * added --simple, --passive and --background to roarcatplay * got cf vorbis work on vio * got standard vio work better on DECnet v. 0.1 - Sun Aug 31 2008 * done basic stuff * started 'libroaresd' to support ESD clients * started 'libroararts' to support aRts clients * started 'libroaryiff' to support YIFF clients * started 'libroarpulse' to support PulseAudio clients * done a libao plugin * done a lot basic networking stuff, still need some more proxy code * got roard work file even with small buffers (<1ms) * support diffrent codecs server side decoding * support for meta data * done some manpages * added Ogg Vorbis support (server and client side) * added basic clients and some clients for testing and as examples roaraudio-1.0beta11/HACKING0000644000175000017500000001175511451340615013457 0ustar phiphi RoarAudio As loud as a Lion --------------------- --- 0. INDEX 0. Index 1. Infos for maintainers 2. Infos for developer --- 1. Infos for maintainers: If you want to maintain a packet for your favorite OS please let me know! We would love to be in contact with the maintainers to send them infos about updates and maybe get feedback or things like init scripts or the like (see 2. Infos for developer). If it would make your work simpler we can put things in trunk (info files for pkg build tools or the like). Just ask. Also if you need any help you may contact us. You can conntact us at our mailinglist or on IRC. If you do not want to subscribe to the full traffic mailinglist but want to keep informed about new releases and such (very recommended) please join our announce list. Contact information can be found in our homepage at: http://roaraudio.keep-cool.org/contact.html Here is my recommendation on how to split the RoarAudio in pkgs: libroar includes libroar, libroardsp, libroarmidi, libroarlight and libroareio roaraudio-common include roard and roarclients (at least the ones with no special deps) roaraudio-tools includes all other tools not in roaraudio-common because of special deps (if any) libroar-compat includes libroaresd, libroararts, libroarpulse and libroaryiff, ... and the compatinitly binarys. It would be nice to ask the user if he wants symlinks from libesd, libarts*, libpulse*. roaraudio-dev includes include/, *.pc and such someplayer-roar pkgs from plugins/ roaraudio-server virtual package provided by the package containing roard. Applications should recommend this package not the package with roard directly. This is to enable the use to use an alternative server. manpages should be included in the corresponding packet. If your system includes a libdnet (Linux DECnet support) please build it with DECnet support compiled in. There will be no strange warning messages anymore with DECnet enabled on a non-DECnet system. libdnet does not require any Kernel modules or has any non standard deps itself. But be aware that several systems ship a libdnet which is not DECnet support. In this case disable the build with libdnet. If your system includes libslp (normaly one of the deps of cups) please consider to build with libslp support. In addition you should configure with --runtime-detect: this will let roard/libroar detect the presents of some tools at runtime and will reduce deps. Please ensure that configure finds the correct audio users group. In case it does not detect the correct one please set it via --audio-group. In case you want to provide emulation of other sound systems they need to be install on the build system (only). This is because we use parts of them (mainly header files) in order to build the compatibility librarys and abstraction layers to ensure best comaptibility. They will not be required after the build has been done and thereof does not need to be a dependency of the final packet you build. The only expection is in case you build driver support for one or more of them. If you do so you of cause need to ensure that all needed librarys are avalible on the target system. Running roard: Global (system wide) roards normaly are started as root. Ensure it drops it's privilegs by setting --setuid/--setgid and maybe -U and -G. Common usernames are: roard, roar, roaraudio, nobody. You can use the init script for debian (in dist/debian-like/) as example. It is allways nice to use --pidfile. If you use a pidfile you can start and stop roard by using --start and --stop easily. You can use --chroot to chroot into an empty directory to improve security. roard does the chrooting after loading everything so it is perfectly safe to chroot into an empty directory. In case your system includes a /var/empty or simular directory please do the chroot. To ensure no drops consider to add one or two --realtime. In case of a public (for LAN) server have some way for the user to set --location and use --slp for Zero Conf. For more information see roard --help. --- 2. Infos for developer At the moment all the libs are under GPLv3. As libesd, libarts*, libpulse* and maybe other are under LGPL the corresponding roar replacements should be under LGPL as well. Because they link libroar independent of what licenses they are under they are downgraded to GPL. This may change in future. Because of that we *require* that *everything* that is contributed by someone we get under LGPL so we can upgrade code to LGPL if needed in future without asking. Code we get under a different license will *NOT* get into trunk nor will be hosted by us. Also add full contact infos when sending code to us, this includes: 1) Full name 2) nickname 3) E-Mail 4) OpenPGP key When sending code please sign it with OpenPGP. #ll roaraudio-1.0beta11/Makefile0000644000175000017500000001120512234462552014123 0ustar phiphiinclude Makefile.conf include Makefile.inc COMP_LIB=$(subdir_libroaresd) $(subdir_libroarsndio) $(subdir_libroaryiff) $(subdir_libroarpulse) $(subdir_libroararts) $(subdir_libroaross) $(subdir_libroarrsound) SUBDIRS=$(comp_libs) $(COMP_LIB) $(comp_comp_bins) $(comp_clients) $(comp_roard) $(comp_doc) PLUGINS=$(subdir_plugins_ao) $(subdir_plugins_xmms) $(subdir_plugins_audacious) $(subdir_plugins_roard) $(subdir_plugins_universal) CKPORTDB=libroar.ckport SUFFIX_LIB=$(SHARED_SUFFIX).$(COMMON_SOVERSION) ifeq ($(TARGET_TYPE),win32) SYMLINKPREFIX_ROOT=$(DESTDIR) SYMLINKPREFIX=$(SYMLINKPREFIX_ROOT)$(PREFIX_LIB)/ else SYMLINKPREFIX_ROOT= SYMLINKPREFIX= endif all: set -e; for i in ${SUBDIRS}; do cd $$i; $(MAKE) all; cd ..; done; set -e; for i in ${PLUGINS}; do cd $$i; $(MAKE) all; cd ../..; done; clean: rm -f lib/* || true set -e; for i in ${SUBDIRS}; do cd $$i; $(MAKE) clean; cd ..; done; set -e; for i in ${PLUGINS}; do cd $$i; $(MAKE) clean; cd ../..; done; set -e; cd tests/; $(MAKE) clean; cd ..; distclean: clean rm -f Makefile.conf config.log include/roaraudio/config.h new: clean all test: all set -e; cd tests; $(MAKE) test; cd ..; build-pc-files: set -e; if [ "$(CROSS_COMPILE)" = "false" -o "$(CROSS_COMPILE)" = "true" -a "$(EXEC_HELPER)" != "" ]; then for lib in $(comp_libs); do $(EXEC_HELPER) ./lib/roar-config --output-pc $$lib > lib/$$lib.pc; done; fi prep-install: prep-install-dirs build-pc-files prep-install-dirs: mkdir -p '$(DESTDIR)$(PREFIX_BIN)' mkdir -p '$(DESTDIR)$(PREFIX_LIB)' mkdir -p '$(DESTDIR)$(PREFIX_INC)' mkdir -p '$(DESTDIR)$(PREFIX_MAN)' mkdir -p '$(DESTDIR)$(PREFIX_PC)' mkdir -p '$(DESTDIR)$(PREFIX_COMP_LIBS)' mkdir -p '$(DESTDIR)$(PREFIX_COMP_BINS)' mkdir -p '$(DESTDIR)$(PREFIX_CKPORT)' mkdir -p '$(DESTDIR)$(PREFIX_PLUGINS)/universal/universal/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)' mkdir -p '$(DESTDIR)$(PREFIX_PLUGINS)/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/universal/' mkdir -p '$(DESTDIR)$(PREFIX_PLUGINS)/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/roard/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)' mkdir -p '$(DESTDIR)$(PREFIX_BUILDSYSTEM)' set -e; cd doc; $(MAKE) prep-install-dirs; cd .. install: prep-install cp $(cp_v) lib/roar* '$(DESTDIR)$(PREFIX_BIN)' cp $(cp_v) $(CKPORTDB) '$(DESTDIR)$(PREFIX_CKPORT)' set -e; if [ "$(CROSS_COMPILE)" = "false" -o "$(CROSS_COMPILE)" = "true" -a "$(EXEC_HELPER)" != "" ]; then cp $(cp_v) lib/*.pc '$(DESTDIR)$(PREFIX_PC)'; fi sh -c 'set -e; cd lib; for file in lib*$(SHARED_SUFFIX)*; do cp $$file '$(DESTDIR)$(PREFIX_LIB)'/$$file.$(COMMON_SOVERSION); done' sh -c 'set -e; cd lib; for file in lib*$(SHARED_SUFFIX)*; do ln -fs $(SYMLINKPREFIX)$$file.$(COMMON_SOVERSION) '$(DESTDIR)$(PREFIX_LIB)'/$$file; done' sh -c 'set -e; cd lib; while read d t; do if [ -e '$(DESTDIR)$(PREFIX_LIB)'/$$d$(SUFFIX_LIB) ]; then ln -fs '$(SYMLINKPREFIX_ROOT)$(PREFIX_LIB)'/$$d$(SUFFIX_LIB) '$(DESTDIR)$(PREFIX_COMP_LIBS)'/$$t; fi; done < ../symlinks.comp' sh -c 'set -e; cd lib; for file in *$(COMPBIN_SUFFIX); do b=`basename $$file $(COMPBIN_SUFFIX)`; cp $$file '$(DESTDIR)$(PREFIX_COMP_BINS)'/$$b; done' sh -c 'set -e; for file in include/roar* include/lib*; do cp $(cp_v) -r $$file '$(DESTDIR)$(PREFIX_INC)'/; done' set -e; cd doc; $(MAKE) install; cd .. set -e; for i in $(PLUGINS); do if [ "$$i" != '' ]; then cd $$i; $(MAKE) install; cd ../..; fi; done cp $(cp_v) build-system/*.* '$(DESTDIR)$(PREFIX_BUILDSYSTEM)' semi-install: prep-install sh -c 'set -e; for file in lib/roar*; do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_BIN)'/; done' ln -fs `pwd`/$(CKPORTDB) '$(DESTDIR)$(PREFIX_CKPORT)/' sh -c 'set -e; if [ "$(CROSS_COMPILE)" = "false" -o "$(CROSS_COMPILE)" = "true" -a "$(EXEC_HELPER)" != "" ]; then for file in lib/*.pc; do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_PC)'/; done; fi' sh -c 'set -e; cd lib; for file in lib*$(SHARED_SUFFIX)*; do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_LIB)'/; done' sh -c 'set -e; cd lib; for file in lib*$(SHARED_SUFFIX)*; do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_LIB)'/$$file.$(COMMON_SOVERSION); done' sh -c 'set -e; cd lib; while read d t; do if [ -e `pwd`/$$d$(SHARED_SUFFIX) ]; then ln -fs `pwd`/$$d$(SHARED_SUFFIX) '$(DESTDIR)$(PREFIX_COMP_LIBS)'/$$t; fi; done < ../symlinks.comp' sh -c 'set -e; cd lib; for file in *$(COMPBIN_SUFFIX); do b=`basename $$file $(COMPBIN_SUFFIX)`; ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_COMP_BINS)'/$$b; done' sh -c 'set -e; for file in include/roar* include/lib*; do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_INC)'/; done' set -e; cd doc; $(MAKE) semi-install; cd .. set -e; for i in $(PLUGINS); do if [ "$$i" != '' ]; then cd $$i; $(MAKE) semi-install; cd ../..; fi; done ln -fs `pwd`/build-system/*.* '$(DESTDIR)$(PREFIX_BUILDSYSTEM)' roaraudio-1.0beta11/Makefile.inc0000644000175000017500000000261512245101560014667 0ustar phiphi# Common: COMMON_V_MAJOR = 1 COMMON_V_MINOR = 0 COMMON_V_REV = 11 COMMON_V_MM = $(COMMON_V_MAJOR).$(COMMON_V_MINOR) COMMON_VERSION = $(COMMON_V_MM).$(COMMON_V_REV) COMMON_SOVERSION= 2 # libroar: LIBROAR_V = $(COMMON_SOVERSION) NETLIBS = $(lib_dnet) $(lib_wsock32) $(lib_ws2_32) AUXLIBS = $(lib_slp) $(lib_ssl) $(lib_gcrypt) $(lib_sendfile) $(lib_dl) $(lib_x11) $(lib_z) LIBROAR_NS = $(AUXLIBS) $(NETLIBS) # libroardsp: LIBROARDSP_V = $(COMMON_SOVERSION) DSP_CODECLIBS = $(lib_celt) $(lib_celt0) $(lib_speex) $(lib_speexdsp) DSP_AUXLIBS = $(lib_samplerate) LIBROARDSP_NS = $(DSP_CODECLIBS) $(DSP_AUXLIBS) $(LIBROAR) $(lib_m) # libroarmidi: LIBROARMIDI_V = $(COMMON_SOVERSION) LIBROARMIDI_NS = $(LIBROARDSP) # libroarlight: LIBROARLIGHT_V = $(COMMON_SOVERSION) LIBROARLIGHT_NS = $(LIBROAR) # libroareio: LIBROAREIO_V = $(COMMON_SOVERSION) EIO_CDRIVERLIBS = $(lib_ossaudio) LIBROAREIO_NS = $(EIO_CDRIVERLIBS) $(LIBROAR) # Linker Deps: ifeq ($(LINK_DEPS),indirect) LIBROAR = -lroar LIBROARDSP = -lroardsp LIBROARMIDI = -lroarmidi LIBROARLIGHT = -lroarlight LIBROAREIO = -lroareio else #LINK_DEPS=full LIBROAR = -lroar $(LIBROAR_NS) LIBROARDSP = -lroardsp $(LIBROARDSP_NS) LIBROARMIDI = -lroarmidi $(LIBROARMIDI_NS) LIBROARLIGHT = -lroarlight $(LIBROARLIGHT_NS) LIBROAREIO = -lroareio $(LIBROAREIO_NS) endif #ll roaraudio-1.0beta11/README0000644000175000017500000001013712267551500013344 0ustar phiphi RoarAudio As loud as a Lion --------------------- --- What is RoarAudio?: RoarAudio is a cross-platform sound system for both, home and professional use. It can be used to mix audio for output on a single-stream soundcard or to play audio over the network. For more Information see our website at: http://roaraudio.keep-cool.org/ --- Build: -- Build requirements: A POSIX system or win32. You should install libesd and libao and maybe some codecs. For Debian you may use this command: $ apt-get install build-essential libdnet-dev libesd0-dev libao-dev libvorbis-dev libspeex-dev libspeexdsp-dev libshout3-dev liboggz2-dev libslp-dev libx11-dev Note that in case you want to use any emulation you need to install the corresponding sound system on the build system as we are using headers and other files from those sound systems to be most compatible. You can safely uninstall them after building RoarAudio has been completed. The following binarys are suggested to be installed, too: gnupg, openssh-client, socat, wget Also you maybe want to install µRoar and µRoarD (on debian libmuroar* and muroard). -- How to build: $ ./configure $ make In order to build win32 binarys on UNIX or GNU/Linux: $ CC=...mingw32...gcc ./configure --target-win32 $ make In order to build win32 binarys on Win32 with MinGW/MSYS: $ bash configure $ make Building on OpenVMS: Ask on the RoarAudio Mailinglist. --- Plugins: Plugins should be build automaticly since 0.2rc2. --- Writing software for RoarAudio: See manpages: libroar(7) and roartut(7). You also should read the example code in roarclients/*.c --- Writing patches for this packet: See HACKING. --- Want to be a maintainer for your favorite OS?: See HACKING. --- Tested platforms: OPERATING SYSTEM ARCH COMPILER TESTED M/STATUS COMMENT AND VERSION VERSION --------------------------------------------------------------------------------------------------- Debian Etch ix86 gcc 4.1.2 current s/OK Debian Etch x86_64 gcc 4.1.2 1.0b9p1 s/OK Debian Lenny ix86 gcc 4.3.2 1.0b2 s/OK Debian Lenny x86_64 gcc 4.3.2 0.4b2 s/OK No speex (why?) Debian ? x86_64 gcc 4.3.4 0.3b3 m/OK Debian Squeeze * * 0.3 M/OK Debian Wheezy x86_64 gcc 4.7.2 1.0b11 s/OK Debian Sid ix86 gcc ? 1.0b2 M/OK Debian Sid ix86 clang 2.7 0.4b4 s/WIP Use --no-fishsound. roard broken. Why? Debian Sid * * * M/OK Debian Sid x86_64 gcc 4.7.1 1.0b7 M/OK Debian Sid x86_64 gcc 4.7.2 1.0b9p1 M/OK Ubuntu 9.04 ix86 gcc 4.3.3 0.2rc2 s/OK archlinux ? i686 gcc 4.3.2 0.4rc0 M/OK Gentoo 1.12.11.1 i686 gcc 4.3.2-r3 0.3b0 s/OK NetBSD 1.6.1 Alpha gcc 2.95.3 0.3b7 s/OK gcc too old, does not support debug macros NetBSD 4.0 i386 gcc 4.1.2 0.2 s/OK need to use --roard-cfreq 20 NetBSD 5 x86_64 gcc 4.1.3 0.2b? s/? OpenBSD ? x86_64 gcc ? 0.2rc2 s/OK OpenBSD 4.4 i386 gcc 3.3.5 1.0b11 s/OK OpenBSD 4.5 i386 gcc 3.3.5 0.2rc2 s/OK OpenBSD 5.0 x86_64 gcc 4.2.1 1.0b9p1 OpenVMS V8.3 Alpha HP C V7.3-009 0.4b1 s/WIP Work in process. Ask on ML. FreeBSD 6.2 i386 gcc 3.4.6 0.1b4 s/OK FreeBSD 7.1 i386 gcc 4.2.1 0.2 s/OK FreeBSD 7.2 i386 gcc 4.2.1 0.4b0 s/OK FreeBSD 7.3 i386 gcc 4.2.1 1.0b0 s/OK FreeBSD 7.4 i386 gcc 4.2.1 1.0b9p0 s/OK OpenSolaris 5.11 i386 gcc 3.4.3 ? s/OK Darwin 9.4.0 i386 gcc 4.0.1 0.1b? s/OK Cygwin 1.5.25 i686 gcc 3.4.4 0.3b6 s/Client+ Client libs work, roard only partly, Problems with libroaross, need to be disabled. Hostsystem: WinXP Home WinXP Home ix86 mingw 3.4.5 0.3 s/Client+ Some Clients work, roard only partly was build on Debian Etch Wine 0.9.25 ix86 mingw 3.4.5 1.0b9p0 s/Client+ Some Clients work, roard only partly Hostsystem: Debian Etch WinXP/MSys ix86 mingw 4.7.0 1.0b11 m/OK Automatic Build Bot. Tested Version: Current: Current as listed on Homepage last: Last released version (This system is on release checklist) *b*: Beta *p* Pre-Release Status: Maintenance/testing Status: Maintenance: s = your are on your own, sources. m = package in work, beta package M = maintained S = maintained source package B = maintained binary package roaraudio-1.0beta11/TODO0000644000175000017500000000310612003752752013152 0ustar phiphiMore Tickets on BTS at: https://bts.keep-cool.org/ Things we need to do: * (1.0 O/L/-) add support for sync streams Things we should do: * (*.* */*/*) add a lot other things * (1.0 O/H/-) General cleanup * (1.0 W/H/-) Work on docs * (1.0 O/h/-) Cleanup of plugins/ * (1.0 S/N/-) do a lot work on the manpages * (1.0 S/N/-) Clean and update libroarpulse * (1.0 O/N/- #232) Update crypto support * (1.0 O/N/- #50) Add HashTable support * (1.0 S/h/-) implement RTS/SDP/SAP * (1.0 O/l/-) replace OpenBSD's aucat * (1.0 S/L/- #233) add RAUM support * (?.? O/N/-) Better support for mixer streams * (?.? O/L/- #35) fix libroaryiff Things it would be nice to have: * (1.1 O/l/-) add code to handle streams with more than ROAR_MAX_CHANNELS channels * (1.1 O/L/-) add support for multiple mixers per type Will not fix: * (0.3 n/h/-) do not install .cvsignore files Fixed by: release-helper script * (0.3 n/N/-) publish IDs used in proto as public domain Fixed by: aroarfw * (0.4 O/L/-) Install bash completion script Fixed by: Debian install scripts. * (0.4 n/L/- #34) Implement support for ICY Meta Data * (0.4 O/L/- #37) do something about repeating error messages * (0.4 O/L/-) better tests for libspeex{,dsp}-dev Still needed? * (0.4 O/N/-) Clean up unused parts in plugins/ Fixed by: release-helper script Legent: * (Version State/Priory/Flags) Description States: O = Open W = WIP S = Started/WIP but not active at the moment n = will not fix (fixed in a diffrent way) Priority: l = very low L = low N = normal h = high H = very high Flags: - = NONE P = Patch roaraudio-1.0beta11/configure0000755000175000017500000015505212261446255014405 0ustar phiphi#!/bin/sh CWD="`pwd`" ROAR_BUILDSYSTEM_DIR="$CWD/build-system" ROAR_BUILDSYSTEM_DEFPREFIX="ROAR_" . "$ROAR_BUILDSYSTEM_DIR/configure.all" PATH="$PATH":/sbin:/usr/sbin:/usr/local/sbin:/usr/pkg/sbin # Ensure superuser paths PATH="$PATH":/usr/lib/ssh:/usr/lib/openssh # Ensure SSH paths #set -x # IDs officaly assigned set_dev_vendor 0 'RoarAudio' set_std_vendor 0 'RoarAudio' #-------- COMPBIN_SUFFIX='.r' RUNTIME_DETECT=false PREFIX_COMP_LIBS='' PREFIX_COMP_BINS='' PREFIX_PLUGINS='' PREFIX_BUILDSYSTEM='' CDROM_IS_DEV=true CDROM="" OSS_DEV="" OSS_MIX_DEV="" PROC_NET_DECNET="/proc/net/decnet" PROC_NET_DECNET_NEIGH="" PROC_NET_ARP="" TTY_DEV="" VORBIS_BITS=32 FSYNC=false DEFAULT_GRP='' AO_INST_DIR='' XMMS_INST_DIR='' AUDACIOUS_INST_DIR='' SNDIO_EMUL=true LIBAO=true XMMS=true AUDACIOUS=true DEFAULT_RATE='' DEFAULT_CHANNELS='' DEFAULT_BITS='' COMP_LIBS=true COMP_ROARD=true COMP_CLIENTS=true COMP_DOC=true COMP_COMP_BINS=true COMP_PLUGINS=true ALAW=true MULAW=true ALAW_RW=true MULAW_RW=true PROXY=true PASSWORD_API=true NO_LISTEN=false META_DATA=true SUPPORT_TRAP=false USE_MEMMGR=false WITHOUT_CF='cmd' WITHOUT_VIO='' WITHOUT_DCOMP='' ROAR_DRIVER_DEFAULT='' ROAR_DRIVER_DEVICE='' ROAR_DRIVER_CODEC='' ROARD_BITS='' # Bits per sample used by roard. ROARD_CFREQ='' # cycle frequens for roard, normally 100Hz # Libs which are per default disabled: no_lib_gcrypt=true test_pkgversion test_buildstamp test_cc test_ranlib test_pkgconfig test_sysname #Makefile.conf not yet open, write it later while [ "$1" != '' ] do parse_option "$@" shift $SHIFT_COUNT $HANDLED && continue; case "$1" in '--help') write_help echo 'OPTIONS:' echo echo '--help - This Help' echo echo '--cdrom DEV - Set default CDRum device' echo '--tty DEV - Set default TTY' echo '--oss-dev DEV - Set default OSS device' echo '--oss-mixer-dev DEV - Set default OSS mixer device' echo '--proc-net-decnet FILE - Set DECnet file for DECnet support auto detecting' echo ' (ignore this on non-Linux)' echo '--proc-net-decnet-neigh FILE' echo ' - Set file for DECnet neighbour table' echo '--proc-net-arp FILE - Set file for IP neighbour (ARP) table' echo '--audio-group GROUP - Sets group of audio permitted users' echo echo '--runtime-detect - do as much as posible auto detecting on runtime (for distributors)' echo echo '--ao-install-dir DIR - Set install dir for libao plugin' echo '--xmms-install-dir DIR - Set install dir for XMMS plugin' echo '--audacious-install-dir DIR - Set install dir for Audacious plugin' echo echo '--prefix-comp-libs DIR - Set prefix for compatibility libraries (default: $PREFIX_LIB/roaraudio/complibs)' echo '--prefix-comp-bins DIR - Set prefix for compatibility binaries (default: $PREFIX_LIB/roaraudio/compbins)' echo '--prefix-plugins DIR - Set prefix for plugin search path (default: $PREFIX_LIB/roaraudio/plugins)' echo '--prefix-buildsystem DIR - Set prefix for plugin search path (default: $PREFIX_LIB/roaraudio/build-system)' echo echo '--default-rate RATE - Set default sample rate for roard and roarclients' echo '--default-channels CHANNELS - Set default number of channels for roard and roarclients' echo '--default-bits BITS - Set default number of bits per sample for roarclients' echo '--default-driver DRIVER - Set default driver for roard' echo '--default-device DEVICE - Set default device for roard. Should only be used with --default-driver' echo '--default-codec CODEC - Set default codec used for the default driver' echo echo '--without-alaw - Disable support of A-Law codec (de- and encoding)' echo '--without-alaw-rw - Disable support for writing A-Law (saves 8KB)' echo '--without-mulaw - Disable support of mu-Law codec (de- and encoding)' echo '--without-mulaw-rw - Disable support for writing mu-Law (saves 16KB)' echo '--without-proxy - Disable support for proxies' echo echo '--without-comp-libs - Disable build of libraries' echo '--without-comp-roard - Disable build of roard' echo '--without-comp-clients - Disable build of clients' echo '--without-comp-doc - Disable build of documentation' echo '--without-comp-comp-bins - Disable build of compatibility binaries' echo echo '--without-dcomp-COMP - Disable build of roard'\''s component COMP' echo echo '--without-meta-data - Disable support for Meta Data' echo echo '--without-cf-cmd - Disable support for command codecfilter' echo echo '--without-vio-MODULE - Disable support for VIO module MODULE' echo echo '--without-password-api - Disable build of Password API' echo '--with-trap-api - Build with Trap support' echo echo '--with-memory-api - Use internal memory API (memmgr)' echo '--without-memory-api - Do not use internal memory API (memmgr)' echo echo '--without-listen - Disable listening sockets in roard' echo ' This is the same as allways using --no-listen' echo echo '--roard-cfreq FREQ - Sets the cycle frequency of roard in Hz' echo '--roard-bits BITS - Sets the number of bits per sample used by roard' echo '--vorbis-bits BITS - Sets bits per sample used by Vorbis code' echo # echo '--without-libao - Disable build of libao plugin' echo '--without-xmms - Disable build of XMMS plugin' # echo '--without-audacious - Disable build of Audacious plugin' echo echo '--minimal - Disable all optional components' echo '--cross-compile - Enable cross compiler workarounds' echo '--target-microcontroller - Set Options for mircocontrollers without a OS' echo ' Implys --cross-compile' echo echo echo 'LIBRARY NAMES (to be used with --no-* and --maybe-*):' echo grep '^test_lib_defmake ROAR_' configure | awk '{print $5 == "c" ? $4 : $5}' | grep -v '\.h'\''*$' | \ cut -d/ -f1 | sort | uniq | grep -v ^c$ | \ while read lib do envlib=`echo "$lib" | to_escaped` eval _no="\$no_lib_$envlib"; if [ "$_no" != '' ] then echo -n "$lib (disabled) " else echo -n "$lib " fi done echo '' # print \n exit 0; ;; '--cdrom') CDROM="$2" shift; ;; '--tty') TTY_DEV="$2" shift; ;; '--oss-dev') OSS_DEV="$2" shift; ;; '--oss-mixer-dev') OSS_MIX_DEV="$2" shift; ;; '--proc-net-decnet') PROC_NET_DECNET="$2" shift; ;; '--proc-net-decnet-neigh') PROC_NET_DECNET_NEIGH="$2" shift; ;; '--proc-net-arp') PROC_NET_ARP="$2" shift; ;; '--audio-group') DEFAULT_GRP="$2" shift; ;; '--runtime-detect') RUNTIME_DETECT=true ;; '--ao-install-dir') AO_INST_DIR="$2" shift; ;; '--xmms-install-dir') XMMS_INST_DIR="$2" shift; ;; '--audacious-install-dir') AUDACIOUS_INST_DIR="$2" shift; ;; '--default-rate') DEFAULT_RATE="$2" shift; ;; '--default-channels') DEFAULT_CHANNELS="$2" shift; ;; '--default-bits') DEFAULT_BITS="$2" shift; ;; '--default-driver') ROAR_DRIVER_DEFAULT="$2" shift; ;; '--default-device') ROAR_DRIVER_DEVICE="$2" shift; ;; '--default-codec') ROAR_DRIVER_CODEC="$2" shift; ;; '--without-alaw') ALAW=false ALAW_RW=false ;; '--without-alaw-rw') ALAW_RW=false ;; '--without-mulaw') MULAW=false MULAW_RW=false ;; '--without-mulaw-rw') MULAW_RW=false ;; '--without-proxy') PROXY=false ;; '--without-comp-libs') COMP_LIBS=false ;; '--without-comp-roard') COMP_ROARD=false ;; '--without-comp-clients') COMP_CLIENTS=false ;; '--without-comp-doc') COMP_DOC=false ;; '--without-comp-comp-bins') COMP_COMP_BINS=false ;; '--without-comp-plugins') COMP_PLUGINS=false ;; '--without-meta-data') META_DATA=false ;; '--without-cf-'*) WITHOUT_CF="$WITHOUT_CF"' '$(echo "$1" | cut -d- -f5) ;; '--without-vio-'*) WITHOUT_VIO="$WITHOUT_VIO"' '$(echo "$1" | cut -d- -f5) ;; '--without-dcomp-'*) WITHOUT_DCOMP="$WITHOUT_DCOMP"' '$(echo "$1" | cut -d- -f5) ;; '--without-password-api') PASSWORD_API=false ;; '--with-trap-api') SUPPORT_TRAP=true ;; '--with-memory-api'|'--use-memory-api') USE_MEMMGR=true ;; '--without-memory-api') USE_MEMMGR=false ;; '--without-listen') NO_LISTEN=true ;; '--roard-cfreq') ROARD_CFREQ="$2" shift; ;; '--roard-bits') ROARD_BITS="$2" shift; ;; '--vorbis-bits') VORBIS_BITS="$2" shift; ;; '--without-libao') LIBAO=false no_lib_ao=true ;; '--without-xmms') XMMS=false ;; '--without-audacious') AUDACIOUS=false ;; '--minimal') MINIMAL=true RUNTIME_DETECT=false XMMS=false AUDACIOUS=false LIBAO=false PROXY=false MULAW=false MULAW_RW=false ALAW=false ALAW_RW=false META_DATA=false PASSWORD_API=false SUPPORT_TRAP=false USE_MEMMGR=false COMP_PLUGINS=false WITHOUT_VIO="$WITHOUT_VIO"' cmd stdio' WITHOUT_CF="$WITHOUT_CF"' wave cmd cf au' WITHOUT_DCOMP="$WITHOUT_DCOMP"' sources ssynth cb midi light raw rdtcs cdriver emul_esd emul_simple emul_rsound emul_rplay emul_gopher mixer' ;; # we should remove --prefix-comp soon '--prefix-comp'|'--prefix-comp-libs') PREFIX_COMP_LIBS="$2" shift; ;; '--prefix-comp-bins') PREFIX_COMP_BINS="$2" shift; ;; '--prefix-plugins') PREFIX_PLUGINS="$2" shift; ;; '--prefix-buildsystem') PREFIX_BUILDSYSTEM="$2" shift; ;; #################################### # autof* options block: '--prefix-comp-libs='*) PREFIX_COMP_LIBS=$(echo "$1" | cut -d= -f2) ;; '--prefix-comp-bins='*) PREFIX_COMP_BINS=$(echo "$1" | cut -d= -f2) ;; '--prefix-plugins='*) PREFIX_PLUGINS=$(echo "$1" | cut -d= -f2) ;; '--prefix-buildsystem='*) PREFIX_BUILDSYSTEM=$(echo "$1" | cut -d= -f2) ;; #################################### '--cross-compile') CROSS_COMPILE=true RUNTIME_DETECT=true ;; '--target-microcontroller') TARGET_MICROCONTROLLER=true CROSS_COMPILE=true RUNTIME_DETECT=true HAVE_MAIN_ARGS=false XMMS=false AUDACIOUS=false LIBAO=false WITHOUT_VIO="$WITHOUT_VIO"' cmd' ;; esac; shift; done [ "$no_lib_yiff" != '' ] && no_lib_y2=true if $BETA then : else WITHOUT_DCOMP="$WITHOUT_DCOMP"' rdtcs' no_lib_gcrypt=true no_lib_jack=true no_lib_dbus_1=true no_lib_flac=true fi if $EXPERIMENTAL then : else : # Add list of experimental things here. fi open_configure_files update_target if $TARGET_WIN32 then CROSS_COMPILE=true RUNTIME_DETECT=true no_lib_dnet=true PROXY=false LIBAO=false XMMS=false AUDACIOUS=false WITHOUT_VIO="$WITHOUT_VIO"' pipe cmd' # hope that with buffered pipes we can remove this soon WITHOUT_DCOMP="$WITHOUT_DCOMP"' cb' # [ "$ROARD_CFREQ" = '' ] && ROARD_CFREQ=20 [ "$ROARD_BITS" = '' ] && ROARD_BITS=16 fi if [ "$SYSNAME" = 'FreeBSD' ] then echo "Adding $SYSNAME search path arguments..." [ "$DEFAULT_GRP" = '' ] && DEFAULT_GRP='wheel' elif $TARGET_WIN32 then echo "Adding win32 build arguments..." COMPBIN_SUFFIX='.bat' elif $TARGET_CYGWIN then echo "Adding cygwin build arguments..." COMPBIN_SUFFIX='.bat' fi test_crosscompile update_prefixes [ "$PREFIX_COMP_LIBS" = '' ] && PREFIX_COMP_LIBS="$PREFIX_LIB/roaraudio/complibs/" [ "$PREFIX_COMP_BINS" = '' ] && PREFIX_COMP_BINS="$PREFIX_LIB/roaraudio/compbins/" [ "$PREFIX_PLUGINS" = '' ] && PREFIX_PLUGINS="$PREFIX_LIB/roaraudio/plugins/" [ "$PREFIX_BUILDSYSTEM" = '' ] && PREFIX_BUILDSYSTEM="$PREFIX_LIB/roaraudio/build-system/" [ "$DEFAULT_GRP" = '' ] && DEFAULT_GRP='audio' update_ccft update_cc test_wextra # now write the cc name to Makefile.conf write_header_makefileconf { echo "COMPBIN_SUFFIX=$COMPBIN_SUFFIX" echo echo "PREFIX_COMP_LIBS=$PREFIX_COMP_LIBS" echo "PREFIX_COMP_BINS=$PREFIX_COMP_BINS" echo "PREFIX_PLUGINS=$PREFIX_PLUGINS" echo "PREFIX_BUILDSYSTEM=$PREFIX_BUILDSYSTEM" echo $COMP_LIBS && echo "comp_libs=libroar libroardsp libroarmidi libroarlight libroareio" $COMP_ROARD && echo "comp_roard=roard" $COMP_CLIENTS && echo "comp_clients=roarclients" $COMP_DOC && echo "comp_doc=doc" $COMP_COMP_BINS && echo "comp_comp_bins=compbins" echo $SNDIO_EMUL && echo "subdir_libroarsndio=libroarsndio" echo "subdir_libroaross=libroaross" # this builds an empty file in case of not supported } >&4 write_header_configlog RUNTIME_DETECT write_header_configh _ROARAUDIO_CONFIG_H_ { echo "#define ROAR_VERSION_STRING \"$VERSION\"" grep -E '^COMMON_V_(MAJOR|MINOR|REV) *= [0-9]*$' Makefile.inc | sed 's/^COMMON_V_/#define ROAR_VERSION_/; s/=//' echo '#define ROAR_VERSION_COMMON_REAL0(a,b,c) (#a "." #b "." #c)' echo '#define ROAR_VERSION_COMMON_REAL1(a,b,c) ROAR_VERSION_COMMON_REAL0(a,b,c)' echo '#define ROAR_VERSION_COMMON ROAR_VERSION_COMMON_REAL1(ROAR_VERSION_MAJOR, ROAR_VERSION_MINOR, ROAR_VERSION_REV)' echo "#define ROAR_VERSION_DISTRIBUTION_STRING \"$DISTRIBUTION_VERSION_STRING\"" echo "#define ROAR_BUILD_STAMP \"$BUILD_STAMP\"" echo echo "#define ROAR_DEV_VENDOR $DEV_VENDOR" echo "#define ROAR_DEV_VENDOR_NAME \"$DEV_VENDOR_NAME\"" echo "#define ROAR_DEV_VENDOR_STRING \"$DEV_VENDOR_STRING\"" echo [ "$DEFAULT_RATE" = '' ] || echo "#define ROAR_RATE_DEFAULT $DEFAULT_RATE" [ "$DEFAULT_CHANNELS" = '' ] || echo "#define ROAR_CHANNELS_DEFAULT $DEFAULT_CHANNELS" [ "$DEFAULT_BITS" = '' ] || echo "#define ROAR_BITS_DEFAULT $DEFAULT_BITS" [ "$ROAR_DRIVER_DEFAULT" = '' ] || echo "#define ROAR_DRIVER_DEFAULT \"$ROAR_DRIVER_DEFAULT\"" [ "$ROAR_DRIVER_DEVICE" = '' ] || echo "#define ROAR_DRIVER_DEVICE \"$ROAR_DRIVER_DEVICE\"" [ "$ROAR_DRIVER_CODEC" = '' ] || echo "#define ROAR_DRIVER_CODEC \"$ROAR_DRIVER_CODEC\"" echo [ "$ROARD_CFREQ" = '' ] || echo "#define ROAR_OUTPUT_CFREQ $ROARD_CFREQ" [ "$ROARD_BITS" = '' ] || echo "#define ROAR_ROARD_BITS $ROARD_BITS" echo "#define ROAR_VORBIS_BITS $VORBIS_BITS" echo echo "#define ROAR_SHARED_SUFFIX \"$SHARED_SUFFIX\"" echo echo "#define ROAR_PREFIX \"$PREFIX\"" echo "#define ROAR_PREFIX_BIN \"$PREFIX_BIN\"" echo "#define ROAR_PREFIX_SBIN \"$PREFIX_SBIN\"" echo "#define ROAR_PREFIX_LIB \"$PREFIX_LIB\"" echo "#define ROAR_PREFIX_INC \"$PREFIX_INC\"" echo "#define ROAR_PREFIX_MAN \"$PREFIX_MAN\"" echo "#define ROAR_PREFIX_PC \"$PREFIX_PC\"" echo "#define ROAR_PREFIX_CKPORT \"$PREFIX_CKPORT\"" echo "#define ROAR_PREFIX_SYSCONF \"$PREFIX_SYSCONF\"" echo "#define ROAR_PREFIX_DEV \"$PREFIX_DEV\"" echo "#define ROAR_PREFIX_DOC \"$PREFIX_DOC\"" echo "#define ROAR_PREFIX_TMP \"$PREFIX_TMP\"" echo "#define ROAR_PREFIX_VAR \"$PREFIX_VAR\"" echo "#define ROAR_PREFIX_CACHE \"$PREFIX_CACHE\"" echo "#define ROAR_PREFIX_DATA \"$PREFIX_DATA\"" echo "#define ROAR_PREFIX_LOCK \"$PREFIX_LOCK\"" echo "#define ROAR_PREFIX_LOG \"$PREFIX_LOG\"" echo "#define ROAR_PREFIX_MAIL \"$PREFIX_MAIL\"" echo "#define ROAR_PREFIX_RUN \"$PREFIX_RUN\"" echo "#define ROAR_PREFIX_SPOOL \"$PREFIX_SPOOL\"" echo "#define ROAR_PREFIX_COMP_LIBS \"$PREFIX_COMP_LIBS\"" echo "#define ROAR_PREFIX_COMP_BINS \"$PREFIX_COMP_BINS\"" echo "#define ROAR_PREFIX_PLUGINS \"$PREFIX_PLUGINS\"" echo "#define ROAR_PREFIX_BUILDSYSTEM \"$PREFIX_BUILDSYSTEM\"" echo $MINIMAL && echo '#define ROAR_MINIMAL' $BETA && echo '#define ROAR_BETA' $EXPERIMENTAL && echo '#define ROAR_EXPERIMENTAL' $ALAW && echo '#define ROAR_SUPPORT_ALAW' $ALAW_RW && echo '#define ROAR_SUPPORT_ALAW_RW' $MULAW && echo '#define ROAR_SUPPORT_MULAW' $MULAW_RW && echo '#define ROAR_SUPPORT_MULAW_RW' $PROXY && echo '#define ROAR_SUPPORT_PROXY' $PASSWORD_API && echo '#define ROAR_SUPPORT_PASSWORD_API' $SUPPORT_TRAP && echo '#define ROAR_SUPPORT_TRAP' $USE_MEMMGR && echo '#define ROAR_USE_MEMMGR' $NO_LISTEN || echo '#define ROAR_SUPPORT_LISTEN' $META_DATA && echo '#define ROAR_SUPPORT_META' echo $HAVE_MAIN_ARGS && echo '#define ROAR_HAVE_MAIN_ARGS' echo for i in $WITHOUT_CF do i=$(echo $i | to_upper); echo '#define ROAR_WITHOUT_CF_'$i done for i in $WITHOUT_VIO do i=$(echo $i | to_upper); echo '#define ROAR_WITHOUT_VIO_'$i done for i in $WITHOUT_DCOMP do i=$(echo $i | to_upper); echo '#define ROAR_WITHOUT_DCOMP_'$i done echo $TARGET_MICROCONTROLLER && echo '#define ROAR_TARGET_MICROCONTROLLER' $TARGET_WIN32 && echo '#define ROAR_TARGET_WIN32' $TARGET_CYGWIN && echo '#define ROAR_TARGET_CYGWIN' echo '#define ROAR_OS_'$(echo $SYSNAME | to_escaped | to_upper) echo } >&3 # test binary format. test_bin_format test_linkdeps # #define name cmds... test_tool_defmake ROAR_HAVE_BIN_SH sh sh test_tool_defmake ROAR_HAVE_BIN_OGG123 ogg123 ogg123 test_tool_defmake ROAR_HAVE_BIN_FLAC flac flac test_tool_defmake ROAR_HAVE_BIN_TIMIDITY TiMidity++ timidity test_tool_defmake ROAR_HAVE_BIN_CDPARANOIA cdparanoia cdparanoia test_tool_defmake ROAR_HAVE_BIN_GNUPLOT gnuplot gnuplot test_tool_defmake ROAR_HAVE_BIN_SSH OpenSSH ssh test_tool_defmake ROAR_HAVE_BIN_PINENTRY PIN-Entry pinentry test_tool_defmake ROAR_HAVE_BIN_SSH_ASKPASS SSH-AskPass ssh-askpass test_tool_defmake ROAR_HAVE_BIN_GTK_LED_ASKPASS GTK-LED-AskPass gtk-led-askpass test_tool_defmake ROAR_HAVE_BIN_X11_SSH_ASKPASS X11-SSH-AskPass x11-ssh-askpass test_tool_defmake ROAR_HAVE_BIN_GNOME_SSH_ASKPASS GNOME-SSH-AskPass gnome-ssh-askpass test_tool_defmake ROAR_HAVE_BIN_GPG GnuPG gpg test_tool_defmake ROAR_HAVE_BIN_EJECT eject eject echo >&3 echo >&5 echo >&5 echo >&5 # Those tests should not be disabled as they do not reduce the lib size just # break --minimal on full systems OLD_MINIMAL=$MINIMAL MINIMAL=false # Test haders: test_lib_defmake ROAR_HAVE_H_STDINT % stdint.h c -- stdint.h test_lib_defmake ROAR_HAVE_H_STRING % string.h c -- string.h test_lib_defmake ROAR_HAVE_H_SYS_TYPES % sys/types.h c -- sys/types.h test_lib_defmake ROAR_HAVE_H_SYS_SOCKET % sys/socket.h c -- sys/types.h sys/socket.h test_lib_defmake ROAR_HAVE_H_SYS_TIME % sys/time.h c -- sys/time.h test_lib_defmake ROAR_HAVE_H_SYS_IOCTL % sys/ioctl.h c -- sys/ioctl.h test_lib_defmake ROAR_HAVE_H_SYS_STAT % sys/stat.h c -- sys/types.h sys/stat.h test_lib_defmake ROAR_HAVE_H_SYS_REBOOT % sys/reboot.h c -- sys/reboot.h test_lib_defmake ROAR_HAVE_H_TIME % time.h c -- time.h test_lib_defmake ROAR_HAVE_H_FCNTL % fcntl.h c -- fcntl.h test_lib_defmake ROAR_HAVE_H_UNISTD % unistd.h c -- unistd.h test_lib_defmake ROAR_HAVE_H_DIRENT % dirent.h c -- dirent.h test_lib_defmake ROAR_HAVE_H_STDLIB % stdlib.h c -- stdlib.h test_lib_defmake ROAR_HAVE_H_SIGNAL % signal.h c -- signal.h test_lib_defmake ROAR_HAVE_H_POLL % poll.h c -- poll.h test_lib_defmake ROAR_HAVE_H_MMSYSTEM % mmsystem.h c -- windows.h mmsystem.h test_lib_defmake ROAR_HAVE_H_ESD libroaresd esd.h c -- esd.h test_lib_defmake ROAR_HAVE_H_ARTSC libroararts artsc.h c -- kde/artsc/artsc.h test_lib_defmake ROAR_HAVE_H_ICONV % iconv.h c -- iconv.h test_lib_defmake ROAR_HAVE_H_NETINET_IN % 'netinet/in.h' c -- 'netinet/in.h' test_lib_defmake ROAR_HAVE_H_LINUX_REBOOT % linux/reboot.h c -- linux/reboot.h test_lib_defmake ROAR_HAVE_H_LINUX_SPI_SPIDEV % linux/spi/spidev.h c -- linux/spi/spidev.h test_lib_defmake ROAR_HAVE_H_LINUX_I2C % linux/i2c.h c -- linux/i2c.h test_lib_defmake ROAR_HAVE_H_LINUX_I2C_DEV % linux/i2c-dev.h c -- linux/i2c-dev.h test_lib_defmake ROAR_HAVE_H_WINDOWS % windows.h c -- windows.h test_lib_defmake ROAR_HAVE_H_WINSOCK % winsock.h c -- winsock.h test_lib_defmake ROAR_HAVE_H_WINSOCK2 % winsock2.h c -- winsock2.h MINIMAL=$OLD_MINIMAL #Those headers are checked with minimal mode as it is set by the user: test_lib_defmake ROAR_HAVE_H_DLFCN % dlfcn.h c -- dlfcn.h # #define subdir name -lxxx -- header test_lib_defmake ROAR_HAVE_LIBM % 'MathLibrary' m -- math.h rt='' libname_rt=false if test_lib 'realtime Library' rt -- sys/mman.h mqueue.h semaphore.h then { echo '#define ROAR_HAVE_LIBRT' echo '#define ROAR_NEED_LIBRT' libname_rt=true rt=rt } >&3 fi echo >&3 # #define subdir name -lxxx -- header test_lib_defmake ROAR_HAVE_ESD % EsounD esd -- esd.h test_lib_defmake ROAR_HAVE_LIBAO % libao ao -- ao/ao.h ao/plugin.h test_lib_defmake ROAR_HAVE_LIBRAUM % RAUM raum -- raum.h test_lib_defmake ROAR_HAVE_LIBUNIRAUM % uniraum uniraum -- uniraum/uniraum.h test_lib_defmake ROAR_HAVE_LIBOGG % libogg ogg -- ogg/ogg.h test_lib_defmake ROAR_HAVE_LIBVORBIS % libvorbis vorbis -- vorbis/codec.h test_lib_defmake ROAR_HAVE_LIBVORBISFILE % libvorbisfile vorbisfile -- vorbis/vorbisfile.h test_lib_defmake ROAR_HAVE_LIBVORBISENC % libvorbisenc vorbisenc -- vorbis/vorbisenc.h test_lib_defmake ROAR_HAVE_LIBSPEEX % libspeex speex -- speex/speex.h speex/speex_stereo.h test_lib_defmake ROAR_HAVE_LIBSPEEXDSP % libspeexdsp speexdsp -- speex/speex.h speex/speex_echo.h test_lib_defmake ROAR_HAVE_LIBCELT % libcelt celt -- celt/celt.h celt/celt_header.h test_lib_defmake ROAR_HAVE_LIBCELT0 % libcelt0 celt0 -- celt/celt.h celt/celt_header.h test_lib_defmake ROAR_HAVE_LIBOGGZ % liboggz oggz -- oggz/oggz.h test_lib_defmake ROAR_HAVE_LIBSNDFILE % libsndfile sndfile -- sndfile.h test_lib_defmake ROAR_HAVE_LIBFISHSOUND % libfishsound fishsound -- fishsound/fishsound.h test_lib_defmake ROAR_HAVE_LIBFLAC % libFLAC FLAC -- FLAC/all.h test_lib_defmake ROAR_HAVE_LIBSAMPLERATE % libsamplerate samplerate -- samplerate.h test_lib_defmake ROAR_HAVE_LIBSHOUT % libshout shout -- shout/shout.h test_lib_defmake ROAR_HAVE_LIBPULSE libroarpulse libpulse pulse -- pulse/pulseaudio.h pulse/simple.h test_lib_defmake ROAR_HAVE_LIBPULSESIMPLE % libpulse-simple pulse-simple -- pulse/simple.h test_lib_defmake ROAR_HAVE_LIBY2 libroaryiff libyiff Y2 -- Y2/Y.h Y2/Ylib.h test_lib_defmake ROAR_HAVE_LIBARTSC % libartsc artsc -- kde/artsc/artsc.h test_lib_defmake ROAR_HAVE_LIBOSSAUDIO % libossaudio ossaudio -- sys/ioctl.h test_lib_defmake ROAR_HAVE_LIBSNDIO % libsndio sndio -- sndio.h test_lib_defmake ROAR_HAVE_LIBRSOUND libroarrsound librsound rsound -- rsound.h test_lib_defmake ROAR_HAVE_LIBPORTAUDIO % PortAudio portaudio -- portaudio.h test_lib_defmake ROAR_HAVE_LIBPABLIO % PABLIO pablio -- pablio/pablio.h test_lib_defmake ROAR_HAVE_LIBSLP % OpenSLP slp -- slp.h test_lib_defmake ROAR_HAVE_LIBDNET % libdnet dnet -- sys/socket.h netdnet/dn.h netdnet/dnetdb.h OLD_MINIMAL=$MINIMAL MINIMAL=false test_lib_defmake ROAR_HAVE_BSDSOCKETS % BSDSockets c -- sys/types.h sys/socket.h test_lib_defmake ROAR_HAVE_UNIX % UNIX c -- sys/types.h sys/socket.h sys/un.h test_lib_defmake ROAR_HAVE_IPV4 % IPv4 c -- sys/types.h sys/socket.h 'netinet/in.h' winsock2.h MINIMAL=$OLD_MINIMAL test_lib_defmake ROAR_HAVE_IPX % IPX c -- netipx/ipx.h test_lib_defmake ROAR_HAVE_OSS % OSS c -- sys/ioctl.h sys/soundcard.h test_lib_defmake ROAR_HAVE_OSS_BSD % BSDOSS c -- sys/ioctl.h soundcard.h test_lib_defmake ROAR_HAVE_LIBWINMM % WinMM winmm -- windows.h mmsystem.h test_lib_defmake ROAR_HAVE_LIBASOUND % ALSA asound -- alsa/asoundlib.h alsa/pcm_external.h alsa/control_external.h test_lib_defmake ROAR_HAVE_LIBDL % DynLinkerLib dl -- dlfcn.h test_lib_defmake ROAR_HAVE_LIBZ % zlib z -- zlib.h test_lib_defmake ROAR_HAVE_LIBSENDFILE % sendfile sendfile -- sys/sendfile.h test_lib_defmake ROAR_HAVE_LIBSOCKET % libsocket socket -- sys/socket.h test_lib_defmake ROAR_HAVE_LIBX11 % X11 X11 -- X11/Xlib.h X11/Xatom.h test_lib_defmake ROAR_HAVE_GTK_P_2_0 % GTK+2.0 gtk+-2.0/t -- gtk/gtk.h gdk/gdkkeysyms.h test_lib_defmake ROAR_HAVE_LIBGCRYPT % libgcrypt gcrypt -- gcrypt.h test_lib_defmake ROAR_HAVE_LIBJACK % libjack jack/t -- jack/jack.h test_lib_defmake ROAR_HAVE_LIBUSTE % libuste uste -- uste.h test_netlibs echo >&3 test_version ROAR_HAVE_CELT_VERSION libcelt celt test_version ROAR_HAVE_SPEEX_VERSION libspeex speex test_version ROAR_HAVE_PULSE_VERSION libpulse libpulse test_version ROAR_HAVE_GTK_P_2_0_VERSION GTK+2.0 gtk+-2.0 test_version ROAR_HAVE_FLAC_VERSION libflac flac test_version ROAR_HAVE_PA19_VERSION portaudio-19 portaudio-2.0 echo >&3 # Those tests should not be disabled as they do not reduce the lib size just # break --minimal on full systems OLD_MINIMAL=$MINIMAL MINIMAL=false # Test types: # DEF type/name init value -- headers test_type ROAR_HAVE_T_ID_T id_t test_type ROAR_HAVE_T_PID_T pid_t test_type ROAR_HAVE_T_UID_T uid_t test_type ROAR_HAVE_T_GID_T gid_t test_type ROAR_HAVE_T_SOCKLEN_T socklen_t 0 -- sys/socket.h test_type ROAR_HAVE_T_MODE_T mode_t test_type ROAR_HAVE_T_OFF_T off_t test_type ROAR_HAVE_T_SSIZE_T ssize_t test_type ROAR_HAVE_T_TIME_T time_t test_type ROAR_HAVE_T_SA_FAMILY_T sa_family_t 0 -- sys/socket.h MINIMAL=$OLD_MINIMAL echo >&3 # add a better test here #test_lib 'linux sendfile()' -- sys/sendfile.h && echo '#define ROAR_HAVE_LINUX_SENDFILE' >&3 echo -n 'checking for IPv6... ' if $MINIMAL then echo "disabled by user (minimalstic build)" else echo '#include ' > $TF_C echo '#include ' >> $TF_C echo 'int main (void) { struct sockaddr_in6 in6; return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_IPV6' >&3 echo yes else echo no fi fi echo -n 'checking for _exit()... ' echo '#include ' > $TF_C echo 'int main (void) { _exit(0); return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_U_EXIT' >&3 echo '#define ROAR_U_EXIT _exit' >&3 echo yes else echo '#define ROAR_U_EXIT exit' >&3 echo no fi # def name call -- header test_func_defmake ROAR_HAVE_MALLOC malloc 'malloc(0)' -- stdlib.h test_func_defmake ROAR_HAVE_CALLOC calloc 'calloc(0, 0)' -- stdlib.h test_func_defmake ROAR_HAVE_REALLOC realloc 'realloc((void*)0, 0)' -- stdlib.h test_func_defmake ROAR_HAVE_FREE free 'free((void*)0)' -- stdlib.h test_func_defmake ROAR_HAVE_STRDUP strdup 'strdup((void*)0)' -- string.h test_func_defmake ROAR_HAVE_STRNDUP strndup 'strndup((void*)0)' -- string.h test_func_defmake ROAR_HAVE_STRLEN strlen 'strlen((void*)0)' -- string.h test_func_defmake ROAR_HAVE_STRNLEN strnlen 'strnlen((void*)0)' -- string.h test_func_defmake ROAR_HAVE_SETENV setenv 'setenv("", "", 0)' -- stdlib.h test_func_defmake ROAR_HAVE_PUTENV putenv 'putenv("")' -- stdlib.h test_func_defmake ROAR_HAVE_STRTOK_R strtok_r 'strtok_r("","",(char**)0)' -- string.h test_func_defmake ROAR_HAVE_STRLCPY strlcpy 'strlcpy((char*)0, "", 0)' -- string.h test_func_defmake ROAR_HAVE_STRLCAT strlcat 'strlcat((char*)0, "", 0)' -- string.h test_func_defmake ROAR_HAVE_QSORT qsort 'qsort((void*)0, 0, 0, (int(*)(const void *, const void *))0)' -- stdlib.h test_func_defmake ROAR_HAVE_NICE nice 'nice(0)' -- unistd.h test_func_defmake ROAR_HAVE_GETHOSTID gethostid 'gethostid()' -- unistd.h test_func_defmake ROAR_HAVE_GETGID getgid 'getgid()' -- sys/types.h unistd.h test_func_defmake ROAR_HAVE_GETUID getuid 'getuid()' -- sys/types.h unistd.h test_func_defmake ROAR_HAVE_SETGID setgid 'setgid(0)' -- sys/types.h unistd.h test_func_defmake ROAR_HAVE_SETUID setuid 'setuid(0)' -- sys/types.h unistd.h test_func_defmake ROAR_HAVE_SETSID setsid 'setsid()' -- sys/types.h unistd.h test_func_defmake ROAR_HAVE_GETPWNAM getpwnam 'getpwnam("")' -- sys/types.h pwd.h test_func_defmake ROAR_HAVE_GETGRNAM getgrnam 'getgrnam("")' -- sys/types.h grp.h test_func_defmake ROAR_HAVE_GETTIMEOFDAY gettimeofday 'struct timeval tv; gettimeofday(&tv, NULL)' -- sys/time.h time.h test_func_defmake ROAR_HAVE_USLEEP usleep 'usleep(0)' -- sys/types.h unistd.h test_func_defmake ROAR_HAVE_SLEEP sleep 'sleep(0)' -- unistd.h test_func_defmake ROAR_HAVE_NANOSLEEP nanosleep 'nanosleep((void*)0, (void*)0)' -- time.h test_func_defmake ROAR_HAVE_ALARM alarm 'alarm(0)' -- sys/types.h unistd.h test_func_defmake ROAR_HAVE_TIME time 'time((void*)0)' -- time.h test_func_defmake ROAR_HAVE_CTIME ctime 'ctime((void*)0)' -- time.h test_func_defmake ROAR_HAVE_CTIME_R ctime_r 'ctime_r((void*)0,(char*)0)' -- time.h test_func_defmake ROAR_HAVE_KILL kill 'kill(0,0)' -- sys/types.h signal.h test_func_defmake ROAR_HAVE_UNAME uname 'uname((void*)0)' -- sys/utsname.h test_func_defmake ROAR_HAVE_GETHOSTNAME gethostname 'gethostname((void*)0, 0)' -- unistd.h test_func_defmake ROAR_HAVE_SYSLOG syslog 'syslog(0, "")' -- syslog.h test_func_defmake ROAR_HAVE_OPENLOG openlog 'openlog("", 0, 0)' -- syslog.h test_func_defmake ROAR_HAVE_CLOSELOG closelog 'closelog()' -- syslog.h test_func_defmake ROAR_HAVE_FOPEN fopen 'fopen("","")' -- stdio.h test_func_defmake ROAR_HAVE_FDOPEN fdopen 'fdopen(0,"")' -- stdio.h test_func_defmake ROAR_HAVE_FREOPEN freopen 'freopen("","",(void*)0)' -- stdio.h test_func_defmake ROAR_HAVE_FCLOSE fclose 'fclose(0)' -- stdio.h test_func_defmake ROAR_HAVE_FILENO fileno 'fileno(0)' -- stdio.h test_func_defmake ROAR_HAVE_FTELL ftell 'ftell(0)' -- stdio.h test_func_defmake ROAR_HAVE_FSEEK fseek 'fseek(0, 0, 0)' -- stdio.h test_func_defmake ROAR_HAVE_POPEN popen 'popen("", "")' -- stdio.h test_func_defmake ROAR_HAVE_PCLOSE pclose 'pclose(0)' -- stdio.h test_func_defmake ROAR_HAVE_STAT stat 'stat((char*)0, (void*)0)' -- sys/types.h sys/stat.h unistd.h test_func_defmake ROAR_HAVE_SYSTEM system 'system("")' -- stdlib.h test_func_defmake ROAR_HAVE_GETSOCKNAME getsockname 'getsockname(0, 0, 0)' $lib_wsock32 -- sys/socket.h winsock.h test_func_defmake ROAR_HAVE_GETPEERNAME getpeername 'getpeername(0, 0, 0)' $lib_wsock32 -- sys/socket.h winsock.h test_func_defmake ROAR_HAVE_GETSOCKOPT getsockopt 'getsockopt(0, 0, 0, (void*)0, (void*)0)' -- sys/types.h sys/socket.h test_func_defmake ROAR_HAVE_SETSOCKOPT setsockopt 'setsockopt(0, 0, 0, (void*)0, (void*)0)' -- sys/types.h sys/socket.h test_func_defmake ROAR_HAVE_GETADDRINFO getaddrinfo 'getaddrinfo((void*)0, (void*)0, (void*)0, (void**)0)' -- sys/types.h sys/socket.h netdb.h test_func_defmake ROAR_HAVE_RAND rand 'rand()' -- stdlib.h test_func_defmake ROAR_HAVE_RAND_R rand_r 'rand_r((unsigned int*)0)' -- stdlib.h test_func_defmake ROAR_HAVE_SRAND srand 'srand((unsigned int)0)' -- stdlib.h test_func_defmake ROAR_HAVE_FCNTL fcntl 'fcntl(0, 0)' -- unistd.h fcntl.h test_func_defmake ROAR_HAVE_POSIX_OPENPT posix_openpt 'posix_openpt(0)' -- stdlib.h fcntl.h test_func_defmake ROAR_HAVE_GRANTPT grantpt 'grantpt(0)' -- stdlib.h test_func_defmake ROAR_HAVE_UNLOCKPT unlockpt 'unlockpt(0)' -- stdlib.h test_func_defmake ROAR_HAVE_TCGETATTR tcgetattr 'tcgetattr(0, (struct termios *)0)' -- termios.h unistd.h test_func_defmake ROAR_HAVE_TCSETATTR tcsetattr 'tcsetattr(0, TCSANOW, (struct termios *)0)' -- termios.h unistd.h test_func_defmake ROAR_HAVE_CFMAKERAW cfmakeraw 'cfmakeraw((struct termios *)0)' -- termios.h unistd.h test_func_defmake ROAR_HAVE_REBOOT reboot 'reboot(LINUX_REBOOT_CMD_RESTART|LINUX_REBOOT_CMD_HALT|LINUX_REBOOT_CMD_POWER_OFF|LINUX_REBOOT_CMD_CAD_ON|LINUX_REBOOT_CMD_CAD_OFF)' -- unistd.h linux/reboot.h sys/reboot.h test_func_defmake ROAR_HAVE_LINUX_SENDFILE sendfile 'sendfile(-1, -1, (void*)0, 0)' -- sys/sendfile.h test_func_defmake ROAR_HAVE_GETVERSIONEX GetVersionEx 'OSVERSIONINFO osinfo; osinfo.dwOSVersionInfoSize = sizeof(osinfo);GetVersionEx(&osinfo);' -- windows.h test_func_defmake ROAR_HAVE_AO_APPEND_GLOBAL_OPTION ao_append_global_option 'ao_append_global_option("","")' ao -- ao/ao.h test_func_defmake ROAR_HAVE_DLADDR dladdr 'dladdr((void*)0, (Dl_info*)0)' dl -- dlfcn.h echo "STATE: funcname_dladdr=$funcname_dladdr" >&5 if [ "$funcname_dladdr" = 'false' ] then infotext='retested with _GNU_SOURCE' _old="$NEED_GNU_SOURCE" NEED_GNU_SOURCE=true test_func_defmake ROAR_HAVE_DLADDR dladdr 'dladdr((void*)0, (Dl_info*)0)' dl -- dlfcn.h [ "$funcname_dladdr" = 'false' ] && NEED_GNU_SOURCE="$_old" infotext='' fi test_func_defmake ROAR_HAVE_CLOCK_GETRES clock_getres 'struct timespec ts; clock_getres((clockid_t)0, &ts)' -- time.h test_func_defmake ROAR_HAVE_CLOCK_GETTIME clock_gettime 'struct timespec ts; clock_gettime((clockid_t)0, &ts)' -- time.h test_func_defmake ROAR_HAVE_CLOCK_SETTIME clock_settime 'struct timespec ts; clock_settime((clockid_t)0, &ts)' -- time.h echo "STATE: funcname_clock_getres=$funcname_clock_getres" >&5 echo "STATE: libname_rt=$libname_rt" >&5 if [ "$funcname_clock_getres" = 'false' ] then if $libname_rt then infotext='retested using realtime library' test_func_defmake ROAR_HAVERT_CLOCK_GETRES clock_getres 'struct timespec ts; clock_getres((clockid_t)0, &ts)' $rt -- time.h test_func_defmake ROAR_HAVERT_CLOCK_GETTIME clock_gettime 'struct timespec ts; clock_gettime((clockid_t)0, &ts)' $rt -- time.h test_func_defmake ROAR_HAVERT_CLOCK_SETTIME clock_settime 'struct timespec ts; clock_settime((clockid_t)0, &ts)' $rt -- time.h infotext='' if $funcname_clock_getres then echo "clock_rt=-l$rt" >&4 fi fi fi test_const_defmake ROAR_HAVE_CONST_CLOCK_REALTIME CLOCK_REALTIME clockid_t CLOCK_REALTIME -- time.h test_const_defmake ROAR_HAVE_CONST_CLOCK_MONOTONIC CLOCK_MONOTONIC clockid_t CLOCK_MONOTONIC -- time.h test_const_defmake ROAR_HAVE_CONST_CLOCK_PROCESS_CPUTIME_ID CLOCK_PROCESS_CPUTIME_ID clockid_t CLOCK_PROCESS_CPUTIME_ID -- time.h test_const_defmake ROAR_HAVE_CONST_CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID clockid_t CLOCK_THREAD_CPUTIME_ID -- time.h test_const_defmake ROAR_HAVE_CONST_M_PI_2 M_PI_2 double M_PI_2 -- math.h test_var_defmake ROAR_HAVE_VAR_H_ERRNO h_errno int h_errno -- netdb.h echo -n 'checking for basic IO calls... ' cat < $TF_C #include #include #include #include #include int main(void) { open(NULL, 0, 0); close(0); read(0, NULL, 0); write(0, NULL, 0); lseek(0, 0, 0); return 0; } EOF if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_IO_POSIX' >&3 echo posix else echo none fi echo -n 'checking for basic FS calls... ' cat < $TF_C #include #include int main(void) { chdir(NULL); unlink(NULL); return 0; } EOF if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_FS_POSIX' >&3 echo posix else echo none fi test_func_defmake ROAR_HAVE_CHROOT chroot 'chroot((void*)0)' -- unistd.h test_func_defmake ROAR_HAVE_MLOCK mlock 'mlock((void*)0, 0)' -- sys/mman.h test_func_defmake ROAR_HAVE_MUNLOCK munlock 'munlock((void*)0, 0)' -- sys/mman.h test_func_defmake ROAR_HAVE_MLOCKALL mlockall 'mlockall(MCL_CURRENT|MCL_FUTURE)' -- sys/mman.h test_func_defmake ROAR_HAVE_MUNLOCKALL munlockall 'munlockall()' -- sys/mman.h test_func_defmake ROAR_HAVE_MMAP mmap 'mmap((void*)0,0,0,0,0,0)' -- sys/mman.h echo -n 'checking for fsync()... ' echo '#include ' > $TF_C echo 'int main (void) { fsync(0); return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_FSYNC' >&3 FSYNC=true echo yes else FSYNC=false echo no fi echo -n 'checking for fdatasync()... ' echo '#include ' > $TF_C echo 'int main (void) { fdatasync(0); return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_FDATASYNC' >&3 echo '#define ROAR_FDATASYNC fdatasync' >&3 echo yes else $FSYNC && echo '#define ROAR_FDATASYNC fsync' >&3 echo no fi #test_func_defmake ROAR_HAVE_STRCASESTR strcasestr 'strcasestr("", "")' -- string.h echo -n 'checking for strcasestr()... ' echo '#define _GNU_SOURCE' > $TF_C echo '#include ' >> $TF_C echo 'int main (void) { strcasestr("", ""); return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_STRCASESTR' >&3 NEED_GNU_SOURCE=true echo yes else echo no fi echo -n 'checking for fopencookie()... ' echo '#define _GNU_SOURCE' > $TF_C echo '#include ' >> $TF_C echo 'int main (void) { cookie_io_functions_t f; fopencookie(NULL, "", f); return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_FOPENCOOKIE' >&3 NEED_GNU_SOURCE=true echo yes else echo no fi echo -n 'checking for funopen()... ' echo '#define __BSD_VISIBLE 1' > $TF_C echo '#include ' >> $TF_C echo 'int main (void) { funopen(NULL, NULL, NULL, NULL, NULL); return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_FUNOPEN' >&3 echo '#define ROAR_NEED_BSD_VISIBLE' >&3 echo yes else echo no fi test_func_defmake ROAR_HAVE_PIPE pipe 'pipe(NULL)' -- unistd.h test_func_defmake ROAR_HAVE_FORK fork 'fork()' -- unistd.h test_func_defmake ROAR_HAVE_WAIT wait 'wait(NULL)' -- string.h sys/wait.h test_func_defmake ROAR_HAVE_SINF sinf 'sinf(0.)' m -- math.h echo -n 'checking for square root func... ' if $TARGET_CYGWIN then echo 'sqrt() (cygwin)' elif [ "$SYSNAME" = 'FreeBSD' ] then echo 'sqrt() (FreeBSD, fix your gcc)' elif [ "$SYSNAME" = 'Linux' ] then echo '#include ' > $TF_C echo 'int main (void) { sqrtl(0); return 0; }' >> $TF_C if $CCTF -lm 2> /dev/null; then echo '#define ROAR_HAVE_SQRTL' >&3 echo 'sqrtl()' else echo 'sqrt()' fi else echo 'sqrt()' fi echo -n 'checking for inline funcs... ' echo 'inline int test (void) { return 0; }' > $TF_C echo 'int main (void) { return test(); }' >> $TF_C if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_INLINE' >&3 echo yes else echo no fi test_pthread echo -n 'checking for broken peercred... ' echo '#include ' > $TF_C echo '#include ' >> $TF_C echo '#include ' >> $TF_C echo 'int main (void) { struct ucred cred; return 0; }' >> $TF_C if $CCTF 2> /dev/null; then echo working else if $CCTF -D_GNU_SOURCE 2> /dev/null; then NEED_GNU_SOURCE=true echo need to set _GNU_SOURCE else echo '#define ROAR_BROKEN_PEERCRED' >&3 echo broken fi fi test_func_defmake ROAR_HAVE_GETPEEREID getpeereid 'getpeereid(0, NULL, NULL)' -- sys/types.h sys/socket.h echo -n 'checking for select()... ' cat < $TF_C #ifndef WITHOUT_SYS_SELECT_H #include #endif #ifdef WITH_WINSOCK_H #include #endif #include #include #include int main (void) { fd_set rfds; struct timeval tv; FD_ZERO(&rfds); FD_SET(0, &rfds); tv.tv_sec = 0; tv.tv_usec = 0; select(1, &rfds, NULL, NULL, &tv); return 0; } EOF if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_SELECT' >&3 echo '#define ROAR_HAVE_H_SYS_SELECT' >&3 echo yes, POSIX.1-2001 elif $CCTF -DWITHOUT_SYS_SELECT_H 2> /dev/null; then echo '#define ROAR_HAVE_SELECT' >&3 echo yes, old style elif $CCTF -DWITHOUT_SYS_SELECT_H -DWITH_WINSOCK_H $lib_wsock32 >&5 2>&5; then echo '#define ROAR_HAVE_SELECT' >&3 echo yes, WinSock else echo no fi echo -n 'checking for shutdown()... ' cat < $TF_C #include #ifndef WITHOUT_SYS_SOCKET_H #include #endif #ifdef WITH_WINSOCK_H #include #endif int main (void) { shutdown(0, 0); return 0; } EOF if [ "$SYSNAME" = 'SunOS' ] then _l='-lsocket' else _l='' fi if $CCTF $_l 2> /dev/null; then echo '#define ROAR_HAVE_SHUTDOWN' >&3 echo '#define ROAR_SHUTDOWN shutdown' >&3 echo yes elif $CCTF -DWITHOUT_SYS_SOCKET_H -DWITH_WINSOCK_H $lib_wsock32 2> /dev/null; then echo '#define ROAR_HAVE_SHUTDOWN' >&3 echo '#define ROAR_SHUTDOWN shutdown' >&3 echo yes, WinSock else echo '#define ROAR_SHUTDOWN(x,y) (-1)' >&3 echo no fi echo -n 'checking for accept()... ' cat < $TF_C #include #ifndef WITHOUT_SYS_SOCKET_H #include #endif #ifdef WITH_WINSOCK_H #include #endif int main (void) { accept(0, 0, 0); return 0; } EOF if [ "$SYSNAME" = 'SunOS' ] then _l='-lsocket' else _l='' fi if $CCTF $_l 2> /dev/null; then echo '#define ROAR_HAVE_ACCEPT' >&3 echo '#define ROAR_ACCEPT accept' >&3 echo yes elif $CCTF -DWITHOUT_SYS_SOCKET_H -DWITH_WINSOCK_H $lib_wsock32 2> /dev/null; then echo '#define ROAR_HAVE_ACCEPT' >&3 echo '#define ROAR_ACCEPT accept' >&3 echo yes, WinSock else echo '#define ROAR_ACCEPT(x,y,z) (-1)' >&3 echo no fi test_func_defmake ROAR_HAVE_GETOBJECTBYNAME getobjectbyname 'getobjectbyname(NULL)' dnet -- stdlib.h netdnet/dn.h netdnet/dnetdb.h test_func_defmake ROAR_HAVE_GETSERVBYNAME getservbyname 'getservbyname((void*)0, (void*)0)' -- netdb.h # --- PulseAudio tests --- test_pa_type ROAR_HAVE_TYPE_PA_PATH_GET_FILENAME pa_path_get_filename type 'const char *' 'char *' 'const char *pa_path_get_filename(const char *p) { return NULL; }' pulse/simple.h test_pa_type ROAR_HAVE_TYPE_PA_UTF8_VALID pa_utf8_valid type 'const char *' 'char *' 'const char *pa_utf8_valid(const char *str) { return NULL; }' test_pa_type ROAR_HAVE_ARG_SINK_NAME_OF_PA_CONTEXT_MOVE_SINK_INPUT_BY_NAME pa_context_move_sink_input_by_name args:'pa_context *c, uint32_t idx, %s sink_name, pa_context_success_cb_t cb, void* userdata' 'const char *' 'char *' 'pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, const char *sink_name, pa_context_success_cb_t cb, void* userdata) { return NULL; }' test_pa_type ROAR_HAVE_ARG_SOURCE_NAME_OF_PA_CONTEXT_MOVE_SOURCE_OUTPUT_BY_NAME pa_context_move_source_output_by_name args:'pa_context *c, uint32_t idx, %s source_name, pa_context_success_cb_t cb, void* userdata)' 'const char *' 'char *' 'pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, const char *source_name, pa_context_success_cb_t cb, void* userdata) { return NULL; }' test_pa_type ROAR_HAVE_ARG_VOLUME_OF_PA_STREAM_CONNECT_PLAYBACK pa_stream_connect_playback args:'pa_stream *s, const char *dev, const pa_buffer_attr *attr, pa_stream_flags_t flags, %s volume, pa_stream *sync_stream' 'const pa_cvolume *' 'pa_cvolume *' 'int pa_stream_connect_playback(pa_stream *s, const char *dev, const pa_buffer_attr *attr, pa_stream_flags_t flags, const pa_cvolume * volume, pa_stream *sync_stream) { return -1; }' # --- End of PulseAudio tests --- echo -n 'checking for struct rsound'\''s sample size member... ' cat > $TF_C << EOF #define RSD_EXPOSE_STRUCT #include int main (void) { rsound_t var; var.samplesize = 0; return 0; } EOF if $CCTF 2> /dev/null; then echo '#define ROAR_HAVE_RSOUND_SAMPLESIZE' >&3 echo '#define ROAR_HAVE_RSOUND_SAMPLESIZE_MEMBER samplesize' >&3 echo samplesize else echo '#define ROAR_HAVE_RSOUND_SAMPLESIZE_MEMBER framesize' >&3 echo framesize fi echo -n 'checking for safe 32 bit integer overflow... ' cat > $TF_C << EOF #include #include #define TYPE uint32_t #define MAX ((TYPE)4294967295U) int main (void) { TYPE a = MAX; a += 2; if ( a == 1 ) { printf("#define ROAR_HAVE_SAFE_OVERFLOW\n"); return 0; } return 1; } EOF if $CCTF 2> /dev/null; then $EXEC_HELPER $TF_E >&3 2> /dev/null if [ "$?" = '0' ] then echo yes else echo no fi else echo 'no (can not compile!, no stdint.h?)' fi echo -n 'checking for __LP64__... ' if $TARGET_WIN32 then echo 'no need to set (win32 build)' else cat > $TF_C << EOF #include int main (void) { #ifdef __LP64__ fprintf(stderr, "set by compiler\n"); #else if ( sizeof(int) == sizeof(void*) ) { fprintf(stderr, "no need to set\n"); } else { fprintf(stderr, "need to set\n"); printf("\n#ifndef __LP64__\n#define __LP64__\n#endif\n\n"); } #endif return 0; } EOF if $CCTF 2> /dev/null; then $EXEC_HELPER $TF_E >&3 else echo 'error, can not compile' exit 1 fi fi echo -n 'checking for 64 bit types... ' if $TARGET_WIN32 then echo 'int64_t, uint64_t (win32 build)' echo '#define ROAR_NATIVE_INT64 int64_t' >&3 echo '#define ROAR_NATIVE_UINT64 uint64_t' >&3 else cat > $TF_C << EOF #include #include int main (void) { char * i64 = NULL, * ui64 = NULL; if ( sizeof(int) == 8 ) { i64 = "int"; ui64 = "unsigned int"; } else if ( sizeof(long int) == 8 ) { i64 = "long int"; ui64 = "unsigned long int"; } else if ( sizeof(long long int) == 8 ) { i64 = "long long int"; ui64 = "unsigned long long int"; } else if ( sizeof(int64_t) == 8 ) { i64 = "int64_t"; ui64 = "uint64_t"; } else { fprintf(stderr, "none\n"); return 0; } fprintf(stderr, "%s, %s\n", i64, ui64); printf("#define ROAR_NATIVE_INT64 %s\n#define ROAR_NATIVE_UINT64 %s\n", i64, ui64); return 0; } EOF if $CCTF 2> /dev/null; then $EXEC_HELPER $TF_E >&3 else echo 'error, can not compile' exit 1 fi fi test_cp_v echo -n 'checking for cdrom device... ' if [ -n "$CDROM" ] then if [ "$CDROM" = '(none)' ] then echo "none (disabled by user)" else if $CROSS_COMPILE then echo "$CDROM (cross compile)" elif [ -e "$CDROM" ] then echo "$CDROM (forced by user)" else echo "$CDROM (not existing, forced by user)" fi echo '#define ROAR_DEFAULT_CDROM "'"$CDROM"'"' >&3 echo '#define ROAR_HAVE_CDROM' >&3 fi elif $CROSS_COMPILE then echo 'none (cross compiling, use --cdrom to enable CDROM support)' else CDROM=$(ls /dev/cdrom /dev/rcd0c 2> /dev/null | head -n 1); if [ -e "$CDROM" ] then echo "$CDROM" echo '#define ROAR_DEFAULT_CDROM "'"$CDROM"'"' >&3 echo '#define ROAR_HAVE_CDROM' >&3 else echo 'none' echo '#define ROAR_HAVE_CDROM' >&3 fi fi echo -n 'checking for default tty device... ' if [ -n "$TTY_DEV" ] then if [ "$TTY_DEV" = '(none)' ] then echo "none (disabled by user)" else if $CROSS_COMPILE then echo "$TTY_DEV (cross compile)" elif [ -e "$TTY_DEV" ] then echo "$TTY_DEV (forced by user)" else echo "$TTY_DEV (not existing, forced by user)" fi echo '#define ROAR_DEFAULT_TTY "'"$TTY_DEV"'"' >&3 fi elif $CROSS_COMPILE then echo 'none (cross compiling, use --tty to set default device)' else TTY_DEV=$(ls /dev/tty 2> /dev/null | head -n 1); if [ -e "$TTY_DEV" ] then echo "$TTY_DEV" echo '#define ROAR_DEFAULT_TTY "'"$TTY_DEV"'"' >&3 else echo 'none' fi fi echo -n 'checking for OSS device... ' if [ -n "$OSS_DEV" ] then if [ "$OSS_DEV" = '(none)' ] then echo "none (disabled by user)" else if $CROSS_COMPILE then echo "$OSS_DEV (cross compile)" elif [ -e "$OSS_DEV" ] then echo "$OSS_DEV (forced by user)" else echo "$OSS_DEV (not existing, forced by user)" fi echo '#define ROAR_DEFAULT_OSS_DEV "'"$OSS_DEV"'"' >&3 fi elif $CROSS_COMPILE then echo 'none (cross compiling, use --oss-dev to set default device)' else OSS_DEV=$(ls /dev/dsp /dev/audio 2> /dev/null | head -n 1); if [ -e "$OSS_DEV" ] then echo "$OSS_DEV" echo '#define ROAR_DEFAULT_OSS_DEV "'"$OSS_DEV"'"' >&3 else echo 'none' fi fi echo -n 'checking for OSS mixer device... ' if [ -n "$OSS_MIX_DEV" ] then if [ "$OSS_MIX_DEV" = '(none)' ] then echo "none (disabled by user)" else if $CROSS_COMPILE then echo "$OSS_MIX_DEV (cross compile)" elif [ -e "$OSS_MIX_DEV" ] then echo "$OSS_MIX_DEV (forced by user)" else echo "$OSS_MIX_DEV (not existing, forced by user)" fi echo '#define ROAR_DEFAULT_OSS_MIX_DEV "'"$OSS_MIX_DEV"'"' >&3 fi elif $CROSS_COMPILE then echo 'none (cross compiling, use --oss-mixer-dev to set default device)' else OSS_MIX_DEV=$(ls /dev/mixer 2> /dev/null | head -n 1); if [ -e "$OSS_MIX_DEV" ] then echo "$OSS_MIX_DEV" echo '#define ROAR_DEFAULT_OSS_MIX_DEV "'"$OSS_MIX_DEV"'"' >&3 else echo 'none' fi fi echo 'checking for DECnet status file... '"$PROC_NET_DECNET" echo '#define ROAR_PROC_NET_DECNET "'"$PROC_NET_DECNET"'"' >&3 echo -n 'checking for DECnet neighbour file... ' if [ -n "$PROC_NET_DECNET_NEIGH" ] then if [ "$PROC_NET_DECNET_NEIGH" = '(none)' ] then echo "none (disabled by user)" else if $CROSS_COMPILE then echo "$PROC_NET_DECNET_NEIGH (cross compile)" elif [ -e "$PROC_NET_DECNET_NEIGH" ] then echo "$PROC_NET_DECNET_NEIGH (forced by user)" else echo "$PROC_NET_DECNET_NEIGH (not existing, forced by user)" fi echo '#define ROAR_PROC_NET_DECNET_NEIGH "'"$PROC_NET_DECNET_NEIGH"'"' >&3 fi elif $CROSS_COMPILE then echo 'none (cross compiling, use --proc-net-decnet-neigh to set default device)' else PROC_NET_DECNET_NEIGH=$(ls /proc/net/decnet_neigh 2> /dev/null | head -n 1); if [ -e "$PROC_NET_DECNET_NEIGH" ] then echo "$PROC_NET_DECNET_NEIGH" echo '#define ROAR_PROC_NET_DECNET_NEIGH "'"$PROC_NET_DECNET_NEIGH"'"' >&3 else echo 'none' fi fi echo -n 'checking for IP neighbour (ARP) file... ' if [ -n "$PROC_NET_ARP" ] then if [ "$PROC_NET_ARP" = '(none)' ] then echo "none (disabled by user)" else if $CROSS_COMPILE then echo "$PROC_NET_ARP (cross compile)" elif [ -e "$PROC_NET_ARP" ] then echo "$PROC_NET_ARP (forced by user)" else echo "$PROC_NET_ARP (not existing, forced by user)" fi echo '#define ROAR_PROC_NET_ARP "'"$PROC_NET_ARP"'"' >&3 fi elif $CROSS_COMPILE then echo 'none (cross compiling, use --proc-net-arp to set default device)' else PROC_NET_ARP=$(ls /proc/net/arp 2> /dev/null | head -n 1); if [ -e "$PROC_NET_ARP" ] then echo "$PROC_NET_ARP" echo '#define ROAR_PROC_NET_ARP "'"$PROC_NET_ARP"'"' >&3 else echo 'none' fi fi echo -n 'checking for default audio group... ' if [ "$DEFAULT_GRP" = '(none)' ] then echo "none (disabled by user)" else echo "$DEFAULT_GRP" echo '#define ROAR_DEFAULT_SOCKGRP "'"$DEFAULT_GRP"'"' >&3 fi echo -n 'checking for user id of root/superuser... ' if [ "$ROOT_UID" = '(none)' ] then echo "none (disabled by user)" elif [ "$ROOT_UID" = '' ] then ROOT_USER='root' ROOT_UID=`id -u $ROOT_USER` if [ "$ROOT_UID" = '' ] then echo "none (please report this)" else echo "$ROOT_UID($ROOT_USER)" echo '#define ROAR_ROOT_UID '"$ROOT_UID" >&3 fi else echo "$ROOT_UID" echo '#define ROAR_ROOT_UID '"$ROOT_UID" >&3 fi $NEED_GNU_SOURCE && echo '#define ROAR_NEED_GNU_SOURCE' >&3 cat >&3 << EOF #if defined(ROAR_HAVE_LIBCELT0) && !defined(ROAR_HAVE_LIBCELT) #define ROAR_HAVE_LIBCELT #endif EOF cd plugins #if $LIBAO #then # echo 'running libao plugin configure...' # cd ao/ # if [ "$AO_INST_DIR" = '' ] # then # ./configure --force-have-roar --pkg-config "$PKG_CONFIG" && \ # echo "subdir_plugins_ao=plugins/ao" >&4 # else # ./configure --force-have-roar --pkg-config "$PKG_CONFIG" --inst-dir "$AO_INST_DIR" && \ # echo "subdir_plugins_ao=plugins/ao" >&4 # fi # cd .. #else # echo "running libao plugin configure... disabled by user" #fi if $XMMS then echo 'running xmms plugin configure...' cd xmms/ ./configure --force-have-roar --pkg-config "$PKG_CONFIG" --inst-dir "$XMMS_INST_DIR" && \ echo "subdir_plugins_xmms=plugins/xmms" >&4 cd .. else echo "running xmms plugin configure... disabled by user" fi #if $AUDACIOUS #then # echo 'running Audacious plugin configure...' # cd audacious/ # ./configure --force-have-roar --pkg-config "$PKG_CONFIG" --inst-dir "$AUDACIOUS_INST_DIR" && \ # echo "subdir_plugins_audacious=plugins/audacious" >&4 # cd .. #else # echo "running Audacious plugin configure... disabled by user" #fi if $COMP_PLUGINS then # Do not build roard plugins on win32 as they use upwards binding (-rdynamic). # This mode of binding is not supported by PE. $TARGET_WIN32 || echo "subdir_plugins_roard=plugins/roard" >&4 echo "subdir_plugins_universal=plugins/universal" >&4 fi cd .. cleanup_ccft write_footer_makefileconf write_footer_configlog write_footer_configh mv config.h include/roaraudio/ echo 'config.h created and moved into include/roaraudio/' write_summery_header write_summery Wextra write_summery bin_format write_summery linkdeps #write_summery bool MINIMAL 'minimal build' #write_summery bool USE_MEMMGR 'memory manager' #write_summery bool SUPPORT_TRAP 'trap support' write_summery lib EsounD write_summery lib libao write_summery lib libvorbisfile 'Codec Vorbis' write_summery lib libspeex 'Codec Speex' write_summery lib libshout 'Icecast2 source' write_summery lib libsndio 'OpenBSD sndio' write_summery lib WinMM write_summery lib ALSA write_summery lib libdnet 'DECnet' write_summery lib OpenSLP write_summery lib libuste uste #ll roaraudio-1.0beta11/libroar.ckport0000644000175000017500000011716212266510163015347 0ustar phiphi#ckport(1) database for RoarAudio core librarys: !NAME: RoarAudio core librarys !TYPE: func !TARGET: libroar2 # Unsorted misc: roar_cdrom_run_cdparanoia unknown roar_vio_open_get_cookie unknown roar_reset wip Do not use yet roar_panic_real maybe Mostly for internal use only. roar_fork ok roar_libroar_set_forkapi ok _libroar_fork ok # Versions: roar_version_string ok roar_version_num ok # VIO: roar_vio_clear_calls ok roar_vio_close removed roar_vio_ref ok roar_vio_unref ok roar_vio_read ok roar_vio_write ok roar_vio_lseek ok roar_vio_sync ok roar_vio_nonblock ok roar_vio_ctl ok roar_vio_accept ok roar_vio_shutdown ok roar_vio_select ok # VIO String functions: roar_vio_fgets ok roar_vio_getc ok roar_vio_printf ok roar_vio_putc ok # VIO other ops: roar_vio_copy_data ok roar_vio_open_tee wip Does not yet work roar_vio_open_split wip Does not yet work # VIO Open functions: # very basic: roar_vio_open_pass ok roar_vio_open_re ok # basic: roar_vio_open_fh maybe roar_vio_open_file removed # network: roar_vio_open_fh_socket maybe roar_vio_open_socket ok roar_vio_open_socket_listen ok # stdio: roar_vio_open_stdio maybe Not supported by all archs roar_vio_to_stdio maybe Not supported by all archs roar_vio_stdio_read internal roar_vio_stdio_write internal roar_vio_stdio_lseek internal roar_vio_stdio_sync internal roar_vio_stdio_ctl internal roar_vio_stdio_close internal roar_vio_to_stdio_close internal roar_vio_to_stdio_write internal roar_vio_to_stdio_read internal # VIO based streams: roar_vio_simple_stream ok roar_vio_simple_new_stream_obj ok # VIO internals: roar_vio_init_calls removed roar_vio_set_inst removed roar_vio_set_fh removed roar_vio_get_fh legacy roar_vio_basic_read internal roar_vio_basic_write internal roar_vio_basic_lseek internal roar_vio_basic_nonblock removed roar_vio_basic_sync internal roar_vio_basic_ctl internal roar_vio_basic_close internal roar_vio_null_rw internal roar_vio_null_sync internal roar_vio_pass_read internal roar_vio_pass_write internal roar_vio_pass_lseek internal roar_vio_pass_nonblock removed roar_vio_pass_sync internal roar_vio_pass_ctl internal roar_vio_pass_close internal roar_vio_re_read internal roar_vio_re_write internal roar_vio_re_lseek internal # VIO for Winsock: roar_vio_winsock_read internal roar_vio_winsock_write internal roar_vio_winsock_nonblock internal roar_vio_winsock_sync internal roar_vio_winsock_ctl internal roar_vio_winsock_close internal # VIO OpenSSL BIO: roar_vio_open_bio maybe requires OpenSSL support to be compiled in roar_vio_to_bio maybe requires OpenSSL support to be compiled in roar_vio_bio_read internal roar_vio_bio_write internal roar_vio_bio_lseek internal roar_vio_bio_nonblock internal roar_vio_bio_sync internal roar_vio_bio_close internal # VIO buffer: roar_vio_open_buffer wip roar_vio_buffer_read internal roar_vio_buffer_write internal roar_vio_buffer_lseek internal roar_vio_buffer_nonblock removed roar_vio_buffer_sync internal roar_vio_buffer_ctl internal roar_vio_buffer_close internal # VIO Buffer Store: roar_vio_open_buffer_store wip roar_vio_buffer_store_read internel roar_vio_buffer_store_write internal roar_vio_buffer_store_lseek internal roar_vio_buffer_store_nonblock removed roar_vio_buffer_store_sync internal roar_vio_buffer_store_ctl internal roar_vio_buffer_store_close internal # VIO Commands: roar_vio_open_cmd likely This requires forking processes roar_vio_cmd_close internal roar_vio_cmd_fork internal roar_vio_cmd_wait internal roar_vio_open_2popen likely This requires forking processes roar_vio_2popen_close internal roar_vio_cmd_read internal roar_vio_cmd_write internal roar_vio_cmd_nonblock removed roar_vio_cmd_sync internal roar_vio_cmd_ctl internal roar_vio_open_gzip legacy Use roar_vio_open_zlib roar_vio_open_gpg wip Currently requires cmd vio roar_vio_open_pgp_decrypt wip Currently requires cmd vio roar_vio_open_pgp_store wip Currently requires cmd vio roar_vio_open_pgp_encrypt_sym wip Currently requires cmd vio roar_vio_open_pgp_encrypt_pub wip Currently requires cmd vio # VIO DSTR: roar_vio_dstr_get_type ok roar_vio_dstr_get_name ok roar_vio_dstr_register_type wip roar_vio_dstr_init_defaults ok roar_vio_dstr_init_defaults_c ok roar_vio_open_default ok roar_vio_open_dstr ok roar_vio_open_dstr_vio ok roar_vio_open_dstr_simple ok roar_vio_open_dstr_simple_new ok roar_vio_dstr_parse_opts internal roar_vio_dstr_set_defaults internal roar_vio_dstr_build_chain internal _roar_vio_dstr_init_otherlibs internal roar_vio_dstr_get_by_type internal roar_vio_dstr_cat ok # VIO Jumbo (frames): roar_vio_open_jumbo ok roar_vio_jumbo_read internal roar_vio_jumbo_write internal roar_vio_jumbo_lseek internal roar_vio_jumbo_nonblock removed roar_vio_jumbo_sync internal roar_vio_jumbo_ctl internal roar_vio_jumbo_close internal # VIO Magic: roar_vio_open_magic wip Does not yet work roar_vio_magic_read removed roar_vio_magic_write removed roar_vio_magic_lseek removed roar_vio_magic_nonblock removed roar_vio_magic_sync removed roar_vio_magic_close internal # VIO pipe: roar_vio_open_pipe wip No support for buffer based pipes roar_vio_pipe_init internal roar_vio_pipe_read internal roar_vio_pipe_write internal roar_vio_pipe_nonblock removed roar_vio_pipe_sync internal roar_vio_pipe_ctl internal roar_vio_pipe_close internal # VIO proto: roar_vio_proto_init_def internal roar_vio_open_proto likely use DSTR interface roar_vio_proto_read internal roar_vio_proto_write internal roar_vio_proto_lseek internal roar_vio_proto_nonblock removed roar_vio_proto_sync internal roar_vio_proto_ctl internal roar_vio_proto_close internal _handle_header internal _parse_header internal roar_vio_open_proto_http internal roar_vio_open_proto_gopher internal # VIO RTP: roar_vio_open_rtp wip Does not always work correctly roar_vio_rtp_read internal roar_vio_rtp_write internal roar_vio_rtp_lseek internal roar_vio_rtp_nonblock removed roar_vio_rtp_sync internal roar_vio_rtp_ctl internal roar_vio_rtp_close internal # VIO Socket: roar_vio_open_def_socket internal use DSTR interface roar_vio_socket_init_socket_def internal roar_vio_socket_init_dstr_def internal roar_vio_socket_conv_def internal roar_vio_socket_get_port internal roar_vio_socket_init_unix_def internal roar_vio_socket_init_decnetnode_def internal roar_vio_socket_init_decnet_def internal roar_vio_socket_init_inet4host_def internal roar_vio_socket_init_inet4_def internal roar_vio_socket_init_tcp4_def internal roar_vio_socket_init_udp4_def internal roar_vio_socket_init_inet6host_def internal roar_vio_socket_init_inet6_def internal roar_vio_socket_init_tcp6_def internal roar_vio_socket_init_udp6_def internal # VIO Stack: roar_vio_open_stack legacy Use roar_vio_open_stack2 roar_vio_open_stack2 ok roar_vio_stack_add ok roar_vio_stack_read internal roar_vio_stack_write internal roar_vio_stack_lseek internal roar_vio_stack_nonblock removed roar_vio_stack_sync internal roar_vio_stack_ctl internal roar_vio_stack_close internal # VIO Tantalos: roar_vio_open_tantalos ok # VIO Stream: _vio_stream_close internal _vio_stream_ctl internal _vio_stream_lseek internal _vio_stream_read internal _vio_stream_sync internal _vio_stream_write internal # VIO Misc: roar_vio_misc_close internal roar_vio_misc_ctl internal roar_vio_misc_lseek internal roar_vio_misc_nonblock removed roar_vio_misc_op_zero internal roar_vio_misc_read internal roar_vio_misc_sync internal roar_vio_misc_write internal roar_vio_misc_op_random_nonce internal roar_vio_misc_op_random_salt_nonce internal roar_vio_misc_op_return_len internal roar_vio_misc_op_return_zero internal roar_vio_misc_op_full internal roar_vio_open_misc ok roar_vio_open_misc_by_name ok # VIO zlib: roar_vio_open_zlib ok roar_vio_zlib_close internal roar_vio_zlib_ctl internal roar_vio_zlib_lseek internal roar_vio_zlib_nonblock removed roar_vio_zlib_read internal roar_vio_zlib_sync internal roar_vio_zlib_write internal _set_error internal _zalloc internal _zfree internal # VIO proxy: roar_vio_open_proxy ok roar_vio_proxy_openvio internal roar_vio_proxy_setdef internal _dstrtype2proxytype internal init_socks4 internal roar_vio_proxy_ctl internal roar_vio_proxy_init_def internal # Buffer: roar_buffer_add ok roar_buffer_delete ok roar_buffer_duplicate ok roar_buffer_free removed Recompile, transition macro provided. roar_buffer_get_data ok roar_buffer_get_flag ok roar_buffer_get_len ok roar_buffer_get_datalen ok roar_buffer_get_meta ok roar_buffer_get_meta_i32 ok roar_buffer_get_next ok roar_buffer_get_type ok roar_buffer_new ok roar_buffer_new_data ok roar_buffer_new_no_ma ok roar_buffer_new_str ok roar_buffer_ring_new ok roar_buffer_ring_read ok roar_buffer_ring_stats ok roar_buffer_ring_write ok roar_buffer_set_flag ok roar_buffer_set_len ok roar_buffer_set_meta ok roar_buffer_set_meta_i32 ok roar_buffer_set_type ok roar_buffer_set_offset ok roar_buffer_shift_out ok roar_buffer_clear_next removed roar_buffer_moveinto ok roar_buffer_moveintoqueue ok roar_buffer_next ok roar_buffer_ref ok roar_buffer_unref ok roar_buffer_ring_avail ok roar_buffer_ring_reset ok _ckmem_corruption internal # Some internal functions: roar_debug_msg internal roar_debug_message_print removed roar_debug_audio_info_print removed # Connection handling: roar_connect_raw removed roar_connect_raw2 removed roar_connect ok roar_connect2 removed use roar_connect roar_connect_fh likely roar_connect_none likely mostly for internal use roar_connect_vio ok roar_disconnect removed replaced by roar_connectionunref roar_connectionref ok roar_connectionunref ok roar_get_connection_fh critical roar_get_connection_vio removed use roar_get_connection_vio2 roar_get_connection_vio2 ok roar_set_connection_callback wip roar_get_connection_server maybe use for user info only roar_libroar_set_connect_internal maybe roar_set_connection_version likely This is for internal use mostly roar_message_genseq likely This is for internal use mostly roar_sync ok roar_wait_msg wip roar_noop ok roar_identify internal _connect_server internal __get_daemonimage internal # Messages: roar_send_message likely This is for internal use mostly roar_recv_message likely This is for internal use mostly roar_req likely This is for internal use mostly roar_vsend_message likely This is for internal use mostly roar_vrecv_message likely This is for internal use mostly roar_vreq likely This is for internal use mostly roar_recv_message2 likely This is for internal use mostly roar_req2 likely This is for internal use mostly roar_vrecv_message2 likely This is for internal use mostly roar_vreq2 likely This is for internal use mostly # Client handling: roar_client_new ok roar_client_set_fh maybe Using FHs directly may not work on all systems roar_client_set_proto ok roar_client_pass ok roar_client_exec ok # Streams: roar_stream_connect ok roar_stream_connect2 removed use roar_stream_connect roar_stream_new ok roar_stream_set_rel_id ok roar_stream_get_rel_id ok roar_stream_new_by_id ok roar_stream_new_empty ok roar_stream_new_by_info ok roar_stream_set_id ok roar_stream_get_id ok roar_stream_set_fh likely roar_stream_get_fh likely roar_stream_set_dir ok roar_stream_get_dir ok roar_stream_exec ok roar_stream_connect_to maybe roar_stream_connect_to_ask internal roar_stream_passfh maybe Does not work on all systems roar_stream_attach_simple ok roar_stream_add_data removed does not work most of the time roar_stream_send_data removed roar_stream_get_info ok roar_stream_get_name ok roar_stream_get_chanmap wip roar_stream_set_chanmap wip roar_stream_set_flags ok roar_stream_set_flags2 removed Use roar_stream_set_flags roar_stream_set_role ok roar_stream_s2m likely mostly for internal use only roar_stream_m2s likely mostly for internal use only # Accessing name database: roar_dir2str ok roar_str2dir ok roar_str2codec ok roar_codec2str ok roar_codec2mime ok roar_mime2codec ok roar_str2bits ok roar_str2channels ok roar_str2rate ok roar_streamstate2str ok roar_str2role ok roar_role2str ok roar_str2proto ok roar_proto2str ok roar_str2byteorder ok roar_byteorder2str ok roar_str2autht ok roar_autht2str ok roar_meta_strtype ok roar_meta_inttype ok roar_meta_strgenre ok roar_meta_intgenre ok roar_ht2str ok roar_str2ht ok roar_ot2str ok roar_str2ot ok roar_stds_str2vendor ok roar_stds_vendor2str ok # Audio info: roar_info2samplesize ok roar_info2framesize ok roar_info2bitspersec ok roar_profile2info ok roar_profiles_list ok # Config: roar_libroar_set_server ok roar_libroar_get_server ok roar_libroar_get_path ok roar_libroar_get_path_static legacy Migrate to roar_libroar_get_path() roar_libroar_list_path ok roar_libroar_set_memmgrapi ok roar_libroar_nowarn internal roar_libroar_warn internal roar_libroar_get_config_ptr fail roar_libroar_get_config internal roar_libroar_config_codec_get_conf internal roar_libroar_config_codec_get internal roar_libroar_config_parse likely Why do you want to parse additional config? roar_libroar_reset_config internal __lookup_path internal __strip_double_slashes internal # Controling the server: roar_get_clientid ok roar_get_standby ok roar_set_standby ok roar_exit removed use roar_terminate roar_terminate ok roar_server_oinfo ok roar_server_oinfo2 removed use roar_server_oinfo roar_list ok roar_list_filtered ok roar_get_client ok roar_get_stream ok roar_kick ok roar_set_vol ok roar_set_vol2 removed use roar_set_vol roar_get_vol ok roar_stream_set_rpg ok roar_stream_get_rpg ok roar_rpgmode2str ok roar_ctl_f2m internal roar_ctl_m2f internal roar_ctl_ia2m internal roar_ctl_m2ia internal roar_ctl_c2m legacy Will removed soon because of buffer overflow problems. Use roar_ctl_c2m2. roar_ctl_c2m2 likely mostly for internal use only roar_ctl_m2c legacy Will removed soon because of buffer overflow problems. Use roar_ctl_m2c2. roar_ctl_m2c2 likely mostly for internal use only roar_conv_volume maybe mostly for internal use only # Env: roar_env_set ok roar_env_get ok roar_env_get_home likely use roar_env_get_home_r roar_env_get_home_r ok roar_env_render_path_r maybe Why do you want to use this? # File handlung: roar_file_codecdetect ok roar_file_send_raw removed use roar_vio_copy_data roar_file_play removed use roar_simple_play_file roar_file_play_full removed use roar_simple_play_file roar_file_map removed roar_file_unmap removed roar_cdromdevice maybe # KeyVal: roar_keyval_lookup ok roar_keyval_split ok roar_keyval_copy ok # ACL: roar_acl_rule_chk_connect wip # Auth: roar_auth wip roar_auth_from_mes likely mostly for internal use roar_auth_init_mes likely mostly for internal use roar_auth_mes_init likely mostly for internal use roar_auth_to_mes likely mostly for internal use roar_auth_ask_server internal # Authfile API: roar_authfile_add_key maybe mostly for internal use roar_authfile_close maybe mostly for internal use roar_authfile_key_new maybe mostly for internal use roar_authfile_key_new_random maybe mostly for internal use roar_authfile_key_ref maybe mostly for internal use roar_authfile_key_unref maybe mostly for internal use roar_authfile_lock maybe mostly for internal use roar_authfile_lookup_key maybe mostly for internal use roar_authfile_open maybe mostly for internal use roar_authfile_sync maybe mostly for internal use roar_authfile_unlock maybe mostly for internal use # Beep: roar_beep ok # CDRum / CDDA: roar_cdrom_open wip roar_cdrom_close wip roar_cdrom_stop wip roar_cdrom_play wip # Debug: roar_debug_warn_sysio_real internal roar_debug_warn_obsolete_real internal roar_debug_bin_obsolete internal roar_debug_option_obsolete internal roar_debug_set_stderr_fh likely use roar_debug_set_stderr_vio roar_debug_set_stderr_vio ok roar_debug_set_stderr_mode ok roar_debug_get_stderr ok roar_debug_msg_simple legacy roar_debug_msg ok # Error handling: roar_err_int removed Use roar_err_init roar_err_init ok roar_err_buildmsg ok roar_err_buildmsg2 removed Use roar_err_buildmsg roar_err_parsemsg ok roar_err_parsemsg2 removed Use roar_err_parsemsg roar_err_to_errno maybe This function should be avoided outside of libroar* roar_err_from_errno maybe This function should be avoided outside of libroar* roar_err_clear maybe This function should be avoided outside of libroar* roar_err_clear_errno likely This function should be avoided outside of libroar* roar_err_clear_all maybe This function should be avoided outside of libroar* roar_err_is_errno_clean removed Use roar_err_is_errno_clear roar_err_is_errno_clear likely This function should be avoided outside of libroar* roar_err_update likely This function should be avoided outside of libroar* roar_err_set maybe It should be avoided to set libroar's error state externally. roar_errno2 ok roar_err_errorframe ok roar_err_initstore ok roar_err_restore ok roar_err_store ok roar_error2str ok roar_error2str_ms internal __errno_to_roar internal __roar_to_errno internal roar_err_convert_table_lookup internal roar_err_convert ok roar_err_get_default_error ok # Trap API: roar_strap_impl ok should ne used directly, will be used by macros roar_trap_register_group ok roar_trap_get_groupid ok roar_trap_get_groupname ok # MemMgr: roar_mm_calloc ok roar_mm_malloc ok roar_mm_free ok roar_mm_free_noerror ok roar_mm_realloc ok roar_mm_memdup ok roar_mm_strdup ok roar_mm_strndup ok roar_mm_strdup2 ok roar_mm_strlen ok roar_mm_strnlen ok roar_mm_strlcpy ok roar_mm_strlcat ok roar_mm_strtok_r ok roar_mm_strselcmp ok roar_mm_strseltok ok roar_mm_mlock ok roar_mm_munlock ok roar_mm_free_retvoid likely Use roar_mm_free when possible (No error checking by caller) _ROAR_MLOCK legacy Use roar_mm_mlock __libroar_calloc internal __libroar_free internal __libroar_malloc internal __libroar_realloc internal # Meta Data: roar_stream_meta_set ok roar_stream_meta_get ok roar_stream_meta_list ok roar_meta_free ok roar_meta_parse_audioinfo ok # NNode: roar_nnode_new ok roar_nnode_new_from_af ok roar_nnode_new_from_sockaddr maybe not supported on all systems roar_nnode_new_from_fh likely not supported on all systems roar_nnode_free ok roar_nnode_get_socktype ok roar_nnode_to_str ok roar_nnode_from_blob internal mostly for internal use roar_nnode_to_blob internal mostly for internal use roar_nnode_cmp ok # Password API: roar_pinentry_open internal roar_pinentry_simple_open internal roar_pinentry_close internal roar_pinentry_send internal roar_pinentry_recv internal roar_pinentry_req internal roar_pinentry_set_desc internal roar_pinentry_set_prompt internal roar_pinentry_set_yes internal roar_pinentry_set_no internal roar_pinentry_set internal roar_pinentry_getpin internal roar_pinentry_confirm internal roar_sshaskpass_getpass internal roar_passwd_simple_ask_pw ok # RoarDL: roar_dl_open ok roar_dl_close removed use roar_dl_unref roar_dl_ref ok roar_dl_unref ok roar_dl_getsym ok roar_dl_ra_init ok roar_dl_errstr ok roar_dl_getlibname ok roar_dl_getpara ok roar_dl_context_restore ok roar_dl_context_store ok roar_dl_appsched_trigger ok roar_dl_appsched_trigger__handle_about internal roar_dl_appsched_trigger__handle_help internal roar_dl_appsched_trigger__handle_preferences internal roar_dl_para_new ok roar_dl_para_ref ok roar_dl_para_unref ok roar_dl_para_check_version ok libroar_dl_service_free_api_real ok libroar_dl_service_get_api_real ok roar_dl_register_fn ok roar_dl_unregister_fn likely This is mostly for internal use. roar_dl_unregister_fn2 maybe _roardl2ldl internal __fnreg_check_trigger internal __fnreg_trigger_by_handler internal __fnreg_trigger_by_reg internal __fnreg_trigger_if_match internal # Plugin Container: roar_plugincontainer_new_simple ok roar_plugincontainer_new ok roar_plugincontainer_ref ok roar_plugincontainer_unref ok roar_plugincontainer_load ok roar_plugincontainer_load_lhandle maybe roar_plugincontainer_appsched_trigger ok roar_plugincontainer_ra_init maybe roar_plugincontainer_unload ok roar_plugincontainer_unload_lhandle maybe roar_plugincontainer_get_lhandle_by_name maybe roar_plugincontainer_get_userdata ok roar_plugincontainer_set_userdata ok roar_plugincontainer_set_callbacks ok roar_plugincontainer_set_autoappsched ok roar_plugincontainer_get_info_by_name ok _copy_para internal _loader internal # Scheduler: roar_scheduler_new ok roar_scheduler_ref ok roar_scheduler_unref ok roar_scheduler_iterate ok roar_scheduler_run ok roar_scheduler_source_add ok roar_scheduler_source_del ok __cpi_callback internal __delete_cpi_client internal __run_waits internal __update_cpi_listen_client internal __update_cpi_service internal # RoarSLP: roar_slp_url_callback internal roar_slp_search internal roar_slp_cookie_init internal # Those may be more public in futur: roar_slp_find_roard internal roar_slp_find_roard_r internal # RoarX11: roar_x11_connect ok roar_x11_connect_display maybe not supported on all systems roar_x11_disconnect ok roar_x11_flush ok roar_x11_set_prop ok roar_x11_delete_prop ok roar_x11_get_prop ok # (old) Simple API: roar_simple_connect ok roar_simple_connect2 ok roar_simple_stream removed use VIO based streams roar_simple_stream_obj removed use VIO based streams roar_simple_new_stream_attachexeced_obj internal roar_simple_new_stream removed roar_simple_new_stream_obj removed roar_simple_play_file ok roar_simple_play removed use roar_vs_new_simple roar_simple_monitor removed use roar_vs_new_simple roar_simple_record removed use roar_vs_new_simple roar_simple_filter removed use roar_vs_new_simple roar_simple_connect_virtual ok roar_simple_close removed use roar_vio_close roar_simple_get_standby removed use roar_get_standby # (old) Socket API: roar_socket_listen legacy use roar_vio_open_socket_listen roar_socket_connect legacy use roar_vio_open_socket roar_socket_new likely roar_socket_new_tcp removed roar_socket_new_udp removed roar_socket_new_tcp6 removed roar_socket_new_udp6 removed roar_socket_new_unix removed roar_socket_new_decnet_seqpacket removed roar_socket_new_decnet_stream removed roar_socket_new_ipxspx removed roar_socket_new_ipx removed roar_socket_open legacy use roar_vio_open_socket or roar_vio_open_socket_listen roar_socket_open_fork removed roar_socket_open_file removed roar_socket_open_proxy removed roar_socket_listen_decnet removed roar_socket_get_local_nodename internal roar_socket_nonblock internal use roar_vio_nonblock roar_socket_decnet_set_timeout removed roar_socket_recvbuf removed roar_socket_set_tos removed roar_socket_dup_udp_local_end internal roar_socket_send_fh internal roar_socket_recv_fh internal roar_socket_open_socks4 internal roar_socket_open_socks4a internal roar_socket_open_socks4d internal roar_socket_open_socks4x internal roar_socket_open_http internal roar_socket_open_ssh internal # Stack: roar_stack_new ok roar_stack_newalloc ok roar_stack_free ok roar_stack_set_free ok roar_stack_set_flag ok roar_stack_push ok roar_stack_pop ok roar_stack_get_cur ok __free internal # KeyStore: roar_kstore_add ok roar_kstore_delete ok roar_kstore_get ok roar_kstore_new ok roar_kstore_ref ok roar_kstore_unref ok roar_kstore_name ok # VS: roar_vs_new ok roar_vs_volume internal roar_vs_pause ok roar_vs_read ok roar_vs_stream_obj maybe roar_vs_vio_obj maybe roar_vs_close ok roar_vs_blocking ok roar_vs_new_from_con maybe roar_vs_sync ok roar_vs_volume_get ok roar_vs_stream ok roar_vs_mute ok roar_vs_volume_mono ok roar_vs_new_simple ok roar_vs_position ok roar_vs_latency ok roar_vs_latency2 removed use roar_vs_latency roar_vs_init internal roar_vs_strerr ok roar_vs_write ok roar_vs_flag internal roar_vs_meta ok roar_vs_connection_obj maybe roar_vs_volume_stereo ok roar_vs_role ok roar_vs_ctl likely This is for internal use mostly roar_vs_run ok roar_vs_iterate ok roar_vs_reset_buffer maybe This should be avoided as it may desync codecs roar_vs_new_from_file ok roar_vs_buffer ok roar_vs_file ok roar_vs_file_simple ok roar_vs_get_avail_read ok roar_vs_get_avail_write ok roar_vs_write_direct internal _handle_async_req internal _send_async_req internal # Server enumeration roar_enum_servers ok roar_enum_servers_free ok roar_enum_servers_num ok _esl_defaults internal _esl_slp internal _esl_neighbours internal # notify core handling: roar_notify_core_emit ok roar_notify_core_emit_simple ok roar_notify_core_new ok roar_notify_core_new_global ok roar_notify_core_ref ok roar_notify_core_unref ok roar_notify_core_register_proxy ok roar_notify_core_subscribe ok roar_notify_core_unsubscribe ok roar_notify_core_swap_global ok roar_notify_proxy_std ok roar_event_from_blob likely This is for internal use mostly roar_event_to_blob likely This is for internal use mostly _hash_event internal # LTM - Long Term Monitoring: roar_ltm_extract ok roar_ltm_get ok roar_ltm_get_mt ok roar_ltm_get_numchans ok roar_ltm_get_numstreams ok roar_ltm_get_streamptr internal roar_ltm_get_window ok roar_ltm_numbits internal roar_ltm_pack_req internal roar_ltm_register ok roar_ltm_unregister ok roar_ltm_regunreg internal # CAPS + CAPS/Standards: roar_caps_from_msg likely This is for internal use mostly roar_caps_to_msg likely This is for internal use mostly roar_caps_stds ok roar_stds_free ok roar_stds_new ok libroar_libstds ok # general server info: roar_server_info ok roar_library_info ok roar_server_info_free ok roar_server_info_from_mes likely This is for internal use mostly roar_server_info_to_mes likely This is for internal use mostly # RoarAudio Standard Floats: roar_float32_isinf ok roar_float32_isnan ok roar_float32_iszero ok roar_ufloat32_build ok roar_ufloat32_from_float ok roar_ufloat32_mul ok roar_ufloat32_scale ok roar_ufloat32_to_float ok # Async control: roar_wait ok # Filters: roar_filter_match likely This is for internal use mostly # Time functions: roar_clock_gettime ok roar_get_time ok roar_time_from_msg likely This is for internal use mostly roar_time_to_msg likely This is for internal use mostly # Base64 encoding: roar_base64_uninit ok roar_base64_init ok roar_base64_is_eof ok roar_base64_decode ok roar_base64_encode ok # Crypto API: roar_crypto_init ok # Random bits source: roar_random_gen ok roar_random_genbuf ok roar_random_gen_nonce ok roar_random_salt_nonce ok roar_random_init internal roar_random_uint16 ok roar_random_uint32 ok # Hash API: roar_hash_buffer ok roar_hash_salted_buffer ok roar_ht_digestlen ok roar_ht_is_supported ok roar_hash_digest2str ok _bin2hex internal # Hash statefull API: roar_hash_new ok roar_hash_free ok roar_hash_digest ok roar_hash_proc ok # Hash API Internals: roar_ht2cmds internal roar_hash_crc24_init internal roar_hash_crc24_digest internal roar_hash_crc24_proc internal roar_hash_adler32_init internal roar_hash_adler32_digest internal roar_hash_adler32_proc internal # Hash Tiger: roar_hash_tiger_init ok roar_hash_tiger_uninit ok roar_hash_tiger_init_from_pstate ok roar_hash_tiger_to_pstate ok roar_hash_tiger_blocklen ok roar_hash_tiger_finalize likely just use roar_hash_tiger_get_digest roar_hash_tiger_get_digest ok roar_hash_tiger_proc ok roar_hash_tiger_proc_block ok roar_hash_tiger_statelen ok key_schedule internal pass internal tiger_round internal roar_hash_tiger_export internal # CRC API: roar_crc24_add ok roar_adler32_add ok # Hash SHA1: roar_hash_sha1_digest internal roar_hash_sha1_init internal roar_hash_sha1_proc internal roar_hash_sha1_proc_block internal roar_hash_sha1_uninit internal # UUID functions: roar_str2uuid ok roar_uuid2str ok roar_uuid_eq ok roar_uuid_gen ok roar_uuid_get_ns_real ok # Timing stuff: roar_usleep ok roar_sleep ok # Watchdog: roar_watchdog_start ok roar_watchdog_stop maybe Stopping a watchdog isn't a good idea roar_watchdog_trigger ok roar_watchdog_tick ok roar_watchdog_gettime ok __event_handler internal _on_sig_alarm internal !TARGET: libroardsp2 # amp.h: roar_amp_pcm ok roar_amp_pcm_8bit internal roar_amp_pcm_16bit internal roar_amp_pcm_24bit removed roar_amp_pcm_32bit internal # channels.h: roardsp_chan2str ok roardsp_str2chan ok roardsp_chanlist2str ok roardsp_chanlist_init wip roardsp_chanmap_calc wip roardsp_chanmap_mappcm8 wip roardsp_chanmap_mappcm16 wip roardsp_chanmap_mappcm24 wip roardsp_chanmap_mappcm32 wip roardsp_chanmap_mappcm wip # convert.h: roar_conv_bits ok roar_conv_bits_8to16 internal roar_conv_bits_8to24 internal roar_conv_bits_8to32 internal roar_conv_bits_16to8 internal roar_conv_bits_16to24 internal roar_conv_bits_16to32 internal roar_conv_bits_24to8 internal roar_conv_bits_24to16 internal roar_conv_bits_24to32 internal roar_conv_bits_32to8 internal roar_conv_bits_32to16 internal roar_conv_bits_32to24 internal roar_conv_chans legacy roar_conv_chans_1ton8 internal roar_conv_chans_1ton16 internal roar_conv_chans_1to28 internal roar_conv_chans_1to216 internal roar_conv_chans_1ton32 internal roar_conv_chans_nto18 internal roar_conv_chans_nto116 internal roar_conv_chans_nto132 internal roar_conv_chans_2to18 internal roar_conv_chans_2to116 internal roar_conv_chans_2to38 internal roar_conv_chans_2to316 internal roar_conv_chans_2to48 internal roar_conv_chans_2to416 internal roar_conv_chans_2to58 internal roar_conv_chans_2to516 internal roar_conv_chans_2to68 internal roar_conv_chans_2to616 internal roar_conv_chans_3to28 internal roar_conv_chans_3to216 internal roar_conv_chans_4to28 internal roar_conv_chans_4to216 internal roar_conv_chans_5to28 internal roar_conv_chans_5to216 internal roar_conv_chans_6to28 internal roar_conv_chans_6to216 internal roar_conv_rate broken roar_conv_rate_8 internal roar_conv_rate_16 internal roar_conv_rate_161zoh internal roar_conv_rate_162zoh internal roar_conv_rate_16nzoh internal roar_conv_rate_SRC internal roar_conv_rate2 ok roar_conv_poly3_32 internal roar_conv_poly3_16 internal roar_conv_poly3_8 internal roar_conv_codec ok roar_conv_signedness internal roar_conv_codec_s2u8 internal roar_conv_codec_s2u16 internal roar_conv_codec_s2u32 internal roar_conv_codec_u2s8 internal roar_conv_codec_u2s16 internal roar_conv_codec_u2s32 internal roar_conv_endian ok roar_conv_endian_16 internal roar_conv_endian_24 internal roar_conv_endian_32 internal roar_conv legacy broken in very bad way roar_conv2 ok roar_conv_poly4_16 internal roar_conv_poly4_16s internal # float.h: roar_conv_float_int32 ok roar_conv_float_int32_enint ok roar_conv_int32_float ok roar_conv_int32_float_deint ok # fader.h: roar_fader_init ok roar_fader_set_rate ok roar_fader_set_startstop ok roar_fader_has_started ok roar_fader_has_ended ok roar_fader_calcpcm_i16n ok roar_fader_calcpcm_i161 internal # filter.h: roardsp_filter_str2id ok roardsp_filter_id2str ok roardsp_filter_new ok roardsp_filter_init ok roardsp_filter_uninit ok roardsp_filter_calc ok roardsp_filter_ctl ok roardsp_filter_reset ok roardsp_lowp_init internal roardsp_lowp_uninit internal roardsp_lowp_calc8 internal roardsp_lowp_calc16 internal roardsp_lowp_calc32 internal roardsp_lowp_ctl internal roardsp_lowp_reset internal roardsp_highp_init internal roardsp_highp_uninit internal roardsp_highp_calc8 internal roardsp_highp_calc16 internal roardsp_highp_calc32 internal roardsp_highp_ctl internal roardsp_highp_reset internal roardsp_amp_init internal roardsp_amp_uninit internal roardsp_amp_calc32 internal roardsp_amp_calc16 internal roardsp_amp_calc8 internal roardsp_amp_ctl internal roardsp_amp_reset internal roardsp_add_init internal roardsp_add_calc8 internal roardsp_add_calc32 internal roardsp_add_calc16 internal roardsp_add_reset internal roardsp_quantify_init internal roardsp_quantify_uninit internal roardsp_quantify_calc8 internal roardsp_quantify_calc16 internal roardsp_quantify_calc32 internal roardsp_quantify_ctl internal roardsp_quantify_reset internal roardsp_clip_init internal roardsp_clip_uninit internal roardsp_clip_calc8 internal roardsp_clip_calc16 internal roardsp_clip_calc32 internal roardsp_clip_ctl internal roardsp_clip_reset internal roardsp_downmix_init internal roardsp_downmix_calc162 internal roardsp_downmix_ctl internal roardsp_downmix_reset internal roardsp_dcblock_init internal roardsp_dcblock_uninit internal roardsp_dcblock_calc16 internal roardsp_dcblock_reset internal roardsp_swap_init internal roardsp_swap_uninit internal roardsp_swap_calc82 internal roardsp_swap_calc162 internal roardsp_swap_calc322 internal roardsp_swap_ctl internal roardsp_swap_reset internal roardsp_agc_init internal roardsp_agc_uninit internal roardsp_agc_ctl internal roardsp_agc_reset internal roardsp_speex_prep_init internal roardsp_speex_prep_uninit internal roardsp_speex_prep_calc161 internal roardsp_speex_prep_ctl internal roardsp_speex_prep_reset internal __func_cos internal __func_icos internal __func_ilinear internal __func_isin internal __func_linear internal __func_pass internal __func_sin internal roardsp_responsecurve_calc16 internal roardsp_responsecurve_calc32 internal roardsp_responsecurve_calc8 internal roardsp_responsecurve_ctl internal roardsp_responsecurve_init internal roardsp_responsecurve_reset internal roardsp_responsecurve_uninit internal roardsp_goertzel_calc16 internal roardsp_goertzel_calc32 internal roardsp_goertzel_calc8 internal roardsp_goertzel_ctl internal roardsp_goertzel_init internal roardsp_goertzel_reset internal roardsp_goertzel_uninit internal # filterchain.h: roardsp_fchain_init ok roardsp_fchain_uninit ok roardsp_fchain_add ok roardsp_fchain_calc ok roardsp_fchain_reset ok roardsp_fchain_num ok # interleave.h: roar_interl_init ok roar_interl_uninit ok roar_interl_ctl ok roar_interl_encode_ext ok roar_interl_decode_ext ok # libroardsp.h: # why are those prototypes still here? roardsp_conv_alaw2pcm16 likely use roar_xcoder_* roardsp_conv_pcm162alaw likely use roar_xcoder_* roardsp_conv_mulaw2pcm16 likely use roar_xcoder_* roardsp_conv_pcm162mulaw likely use roar_xcoder_* roardsp_conv_pcm322autlaw wip roardsp_conv_autlaw2pcm32 wip provide_buffer internal # midi.h: # why isn't this in libroarmidi?: roar_midi_note2name ok roar_midi_name2note ok roar_midi_midi2note ok roar_midi_note2freq ok roar_midi_note_from_midiid ok roar_midi_find_octave ok roar_midi_add_octave ok roar_midi_notefill ok roar_midi_gen_tone legacy use roar_synth_* roar_midi_play_note legacy use roar_synth_* roar_midi_basic_init legacy use roar_synth_* roar_midi_basic_play legacy use roar_synth_* # midside.h: # where is the public part of this API?: roar_conv_s2ms_8 internal roar_conv_s2ms_16 internal roar_conv_s2ms_32 internal roar_conv_ms2s_8 internal roar_conv_ms2s_16 internal roar_conv_ms2s_32 internal # mixer.h: roar_mix_pcm ok roar_mix_pcm_8bit internal roar_mix_pcm_16bit internal roar_mix_pcm_24bit removed roar_mix_pcm_32bit internal # point.h: # this file contains no function prototypes. # poly.h (was math.h long ago): roar_math_mkpoly ok # we allow this public because this part is speed relevant: roar_math_mkpoly_2x2 ok roar_math_mkpoly_3x3 ok roar_math_mkpoly_4x4 ok roar_math_mkpoly_5x5 wip roar_math_cvpoly ok roar_math_cvpoly_4x4 ok # symbolic poly operations: roar_math_diffpoly ok roar_math_intpoly ok roar_math_numintpoly ok # remove.h: roar_remove_init ok roar_remove ok roar_remove_8 internal roar_remove_16 internal roar_remove_32 internal roar_remove_so ok roar_remove_so8 internal roar_remove_so16 internal roar_remove_so32 internal # rms.h: roar_rms2_1_8 ok roar_rms2_1_16 ok roar_rms2_1_32 ok roar_rms2_1_8_2 ok roar_rms2_1_16_2 ok roar_rms2_1_32_2 ok roar_rms2_1_8_n ok roar_rms2_1_16_n ok roar_rms2_1_32_n ok roar_rms2_1_b_n ok # synth.h: roar_synth_init ok roar_synth_set_offset ok roar_synth_set_func ok roar_synth_set_volume ok roar_synth_pcmout_i16n ok roar_synth_pcmout_i161 internal roar_synth_synf_rect fail you must not call this function directly roar_synth_synf_saw fail you must not call this function directly roar_synth_synf_tri fail you must not call this function directly roar_synth_synf_trap fail you must not call this function directly roar_synth_synf_s2s fail you must not call this function directly # transcode.h: roar_xcoder_init ok roar_xcoder_set_backend likely you should provide backend directly using roar_xcoder_init roar_xcoder_packet_size maybe roar_xcoder_close ok roar_xcoder_proc_header ok roar_xcoder_proc_packet ok roar_xcoder_proc ok roar_bixcoder_init ok roar_bixcoder_packet_size ok roar_bixcoder_close ok roar_bixcoder_read_header ok roar_bixcoder_read_packet ok roar_bixcoder_read ok roar_bixcoder_write_header ok roar_bixcoder_write_packet ok roar_bixcoder_write ok roar_xcoder_dummy_inituninit internal roar_xcoder_dummy_packet_size_any internal roar_xcoder_dummy_proc_header internal roar_xcoder_alaw_encode internal roar_xcoder_alaw_decode internal roar_xcoder_mulaw_encode internal roar_xcoder_mulaw_decode internal # transcode_celt.h: roar_xcoder_celt_init internal roar_xcoder_celt_uninit internal roar_xcoder_celt_packet_size internal roar_xcoder_celt_encode internal roar_xcoder_celt_decode internal # transocde_speex.h: roar_xcoder_speex_init internal roar_xcoder_speex_uninit internal roar_xcoder_speex_packet_size internal roar_xcoder_speex_proc_header internal roar_xcoder_speex_encode internal roar_xcoder_speex_decode internal # vio_transcode.h: roar_vio_open_xcode ok roar_vio_xcode_proc internal roar_vio_xcode_lseek internal roar_vio_xcode_nonblock internal roar_vio_xcode_sync internal roar_vio_xcode_ctl internal roar_vio_xcode_close internal roar_vio_open_bixcode ok roar_vio_bixcode_read internal roar_vio_bixcode_write internal roar_vio_bixcode_lseek internal roar_vio_bixcode_nonblock internal roar_vio_bixcode_sync internal roar_vio_bixcode_ctl internal roar_vio_bixcode_close internal # dtmf.h: roar_dtmf_break maybe roar_dtmf_tone is a more general interface roar_dtmf_freqs2char ok roar_dtmf_mus2samples ok roar_dtmf_tone ok !TARGET: libroareio2 # driver.h: roar_cdriver_open legacy Use roar_cdriver_open2 roar_cdriver_open2 ok roar_cdriver_list ok roar_cdriver_oss internal roar_cdriver_roar internal roar_cdriver_null internal # ff_ssdp.h: roar_ff_ssdp_init ok roar_ff_ssdp_free ok roar_ff_ssdp_write ok roar_ff_ssdp_read ok # httpd.h: roar_http_new ok roar_http_free ok roar_http_update ok # libroareio.h: # no function prototypes in this file. !TARGET: libroarlight2 # colors.h: roar_color_new ok roar_color_new_gray maybe has only 8 bit support roar_color_new_rgb maybe has only 24bit (8 bit per channel) RGB support roar_color_copy ok roar_color_conv wip roar_color_conv_gray internal roar_color_conv_rgb internal roar_color_to_string ok roar_color_to_blob fail not yet implemented roar_color_from_blob fail not yet implemented # laser.h: # no function prototypes in this file. # pwm.h: roar_light_pwm_new ok roar_light_pwm_set ok roar_light_pwm_send ok # roardmx.h: roar_roardmx_str2event ok roar_roardmx_event2str ok roar_roardmx_message_new likely This may not what you want, use roar_roardmx_message_new_* roar_roardmx_message_set_type likely roar_roardmx_message_get_flag maybe roar_roardmx_message_get_type maybe roar_roardmx_message_get_len maybe roar_roardmx_message_send ok roar_roardmx_message_recv ok roar_roardmx_message_new_sset ok roar_roardmx_message_add_chanval ok roar_roardmx_message_get_chanval ok roar_roardmx_message_numchannels ok roar_roardmx_message_new_event ok roar_roardmx_message_add_events ok roar_roardmx_message_get_events ok !TARGET: libroarmidi2 # libroarmidi.h: # no function prototypes in this file. #ll roaraudio-1.0beta11/symlinks.comp0000644000175000017500000000171111612654441015214 0ustar phiphilibroarartsc libartsc.so libroarartsc libartsc.so.0 libroarartsc libartsc.so.0.0 libroarartsc libartsc.so.0.0.0 libroaresd libesd.so libroaresd libesd.so.0 libroaresd libesd.so.0.2 libroaresd libesd.so.0.2.36 libroarpulse-simple libpulse-simple.so libroarpulse-simple libpulse-simple.so.0 libroarpulse-simple libpulse-simple.so.0.0 libroarpulse-simple libpulse-simple.so.0.0.0 libroarpulse-simple libpulse-simple.so.0.0.1 libroarpulse-simple libpulse-simple.so.0.0.2 libroarpulse-simple libpulse-simple.so.0.0.3 libroarpulse libpulse.so libroarpulse libpulse.so.0 libroarpulse libpulse.so.0.1 libroarpulse libpulse.so.0.1.0 libroarpulse libpulse.so.0.4 libroarpulse libpulse.so.0.4.1 libroarpulse libpulse.so.0.12.2 libroarsndio libsndio.so libroarsndio libsndio.so.0 libroaryiff libY2.so libroaryiff libY2.so.14 libroaross liboss.so libroaross libossaudio.so libroarrsound librsound.so libroarrsound librsound.so.0 libroarrsound librsound.so.1 roaraudio-1.0beta11/compbins/0000755000175000017500000000000012267553243014302 5ustar phiphiroaraudio-1.0beta11/compbins/Makefile0000644000175000017500000000162011372055662015737 0ustar phiphiTARGETS_ESD = esdcat$(SUFFIX) esdmon$(SUFFIX) esdfilt$(SUFFIX) esdplay$(SUFFIX) esd$(SUFFIX) esddsp$(SUFFIX) TARGETS_ARTS = artscat$(SUFFIX) artsd$(SUFFIX) artsplay$(SUFFIX) artsdsp$(SUFFIX) TARGETS_NAS = auplay$(SUFFIX) audial$(SUFFIX) audiooss$(SUFFIX) TARGETS_YIFF = yplay$(SUFFIX) yshutdown$(SUFFIX) yiff$(SUFFIX) TARGETS_PA = pacat$(SUFFIX) paplay$(SUFFIX) padsp$(SUFFIX) TARGETS_DTMFDIAL = dtmfdial$(SUFFIX) TARGETS_RSOUND = ross$(SUFFIX) rsd$(SUFFIX) rsdplay$(SUFFIX) TARGETS=$(TARGETS_ESD) $(TARGETS_ARTS) $(TARGETS_NAS) $(TARGETS_YIFF) $(TARGETS_PA) $(TARGETS_DTMFDIAL) $(TARGETS_RSOUND) include ../Makefile.conf include ../Makefile.inc SUFFIX = $(COMPBIN_SUFFIX) .SUFFIXES: .a .r .bat all: ${TARGETS} cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all .a.r: ./ast2roar $@ $< .a.bat: ./ast2roar --dos $@ $< roaraudio-1.0beta11/compbins/artscat.a0000644000175000017500000000033611262621402016072 0ustar phiphi#!/bin/sh NAME='artscat' RNAME='roarcat' ARGS_IGNORE_OPTS='' ARGS_PASS_OPTS='-h:false' ARGS_MAP_OPTS='-r:true:-R -b:true:-B -c:true:-C -v:false:--help' ARGS_PASS_NON_OPTS=true #-t set stream title #ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/artsd.a����������������������������������������������������������������0000644�0001750�0001750�00000001661�11262621402�015550� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='artsd' RNAME='roard' ARGS_IGNORE_OPTS='-n:false -u:false -d:false' ARGS_PASS_OPTS='-h:false' ARGS_MAP_OPTS='-a:true:-o -D:true:-O -r:true:-R -b:true:-B -p:true:--port -A:false:--list-driver -v:false:--help' ARGS_PASS_NON_OPTS=true #server/network options: #-N use larger network buffers #-w <n> increase network buffers by factor of <n> # -> can we ignore them? #audio options: #-V <volume>[dB] set output volume #-F <fragments> number of fragments #-S <size> fragment size in bytes # -> -oO #-s <seconds> auto-suspend time in seconds #-f force starting artsd (if no soundcard is there, uses the null output device) # -> -o sysclock #misc options: #-l <level> information level # 3: quiet, 2: warnings, 1: info, 0: debug #-m <appName> application to display messages #-c <appName> application to display crash dialogs #ll �������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/artsdsp.a��������������������������������������������������������������0000644�0001750�0001750�00000001425�11336071346�016121� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='artsdsp' RNAME='' ARGS_IGNORE_OPTS='-s:false --single-threaded:false' ARGS_ENV_OPTS='-n:ROAR_OSS_CLIENT_NAME --name:ROAR_OSS_CLIENT_NAME' ARGS_PASS_NON_OPTS=true ARGS_END_OPTS_ON_NON_OPT=true ast2roar_help -h --help <<__EOF__ artsdsp.r - attempt to reroute audio device to RoarAudio artsdsp.r [options] application arguments options: -h, --help show brief help -n, --name=NAME use name to identify player to artsd -s, --single-threaded use the single-threaded version __EOF__ #artsdsp - attempt to reroute audio device to artsd # #artsdsp [options] application arguments # #options: #-m, --mmap emulate memory mapping (i.e. for quake) #-v, --verbose show parameters #-V, --version show version #ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/artsplay.a�������������������������������������������������������������0000644�0001750�0001750�00000000152�11264346715�016301� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='artsplay' RNAME='roarcatplay' ARGS_ADD_OPTS='--background' ARGS_PASS_NON_OPTS=true #ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/ast2roar���������������������������������������������������������������0000755�0001750�0001750�00000011775�11561514762�015777� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh DOS=false SECTIONC=0 if [ "$1" = '--dos' ] then DOS=true; shift; fi OUT="$1" IN="$2" ret=`{ tempfile --help > /dev/null && echo ok; } 2> /dev/null` if [ "$ret" = 'ok' ] then HELPFILE=`tempfile -p $$- -s .help` else HELPFILE=tempfile-$$.help touch $HELPFILE fi HELPOPTS='' ARGS_END_OPTS_ON_NON_OPT=false ast2roar_help() { HELPOPTS="$*" cat > $HELPFILE } if [ -r $IN ] then . ./$IN else rm $HELPFILE exit 1; fi { $DOS && echo '@ECHO OFF' $DOS || echo '#!/bin/sh' echo $DOS && echo "SET _ARGS=$ARGS_ADD_OPTS" $DOS || echo "_args='$ARGS_ADD_OPTS';" if $DOS then cat <<_E_O_F_ :mloop IF "x%1" == "x" GOTO mloopend SET k=%1 SHIFT IF "%k%" == "--" GOTO mloopend _E_O_F_ else cat <<_E_O_F_ while [ -n "\$1" ] do k="\$1"; shift; case "\$k" in '--') break; ;; _E_O_F_ fi if [ "$HELPOPTS" != '' ] then if $DOS then for o in $HELPOPTS do echo "IF \"%k%\" == \"$o\" GOTO help" done else _opts=`echo "$HELPOPTS" | sed "s/^/\'/; s/$/\'/; s/ /\'\|\'/g"` echo " $_opts)"; echo ' cat <<__AST2ROAR__END_OF_HELP_TEXT__' cat $HELPFILE echo '__AST2ROAR__END_OF_HELP_TEXT__' echo ' exit 0;' echo ' ;;'; fi fi for o in $ARGS_IGNORE_OPTS do on=`echo $o | cut -d: -f1` oa=`echo $o | cut -d: -f2` if $DOS then if $oa then echo "IF \"%k%\" == \"$on\" GOTO nextshift" else echo "IF \"%k%\" == \"$on\" GOTO next" fi else echo " '$on')"; if $oa then echo ' shift;'; fi echo ' ;;'; fi done for o in $ARGS_PASS_OPTS do on=`echo $o | cut -d: -f1` oa=`echo $o | cut -d: -f2` if $DOS then if $oa then echo 'IF "%k%" == "'"$on"'" GOTO passval'; else echo 'IF "%k%" == "'"$on"'" GOTO pass'; fi else echo " '$on')"; if $oa then echo ' _args="$_args '"$on"' $1";'; echo ' shift;'; else echo ' _args="$_args '"$on"'";'; fi echo ' ;;'; fi done for o in $ARGS_MAP_OPTS do on=`echo $o | cut -d: -f1` oa=`echo $o | cut -d: -f2` or=`echo $o | cut -d: -f3 | sed 's/""/ /g'` if $DOS then sec=sec$SECTIONC SECTIONC=`expr $SECTIONC + 1` if $oa then cat <<_E_O_F_ IF NOT "%k%" == "$on" GOTO ${sec}end SET _ARGV=%_ARGV% $or %1 GOTO nextshift :${sec}end _E_O_F_ else cat <<_E_O_F_ IF NOT "%k%" == "$on" GOTO ${sec}end SET _ARGV=%_ARGV% $or GOTO next :${sec}end _E_O_F_ fi else echo " '$on')"; if $oa then echo ' _args="$_args '"$or"' $1";'; echo ' shift;'; else echo ' _args="$_args '"$or"'";'; fi echo ' ;;'; fi done for o in $ARGS_DEEQ_OPTS do if $DOS then echo "REM IGNORED DEEQ: $o"; echo "Warning: can not compile DEEQ as target does not support DEEQ: $o" >&2 else echo " '$o='*)"; echo ' _para=`echo "$k" | cut -d= -f2`;'; echo ' _args="$_args '"$o"' $_para";'; echo ' ;;'; fi done for o in $ARGS_ENV_OPTS do on=`echo $o | cut -d: -f1` or=`echo $o | cut -d: -f2` if $DOS then sec=sec$SECTIONC SECTIONC=`expr $SECTIONC + 1` cat <<_E_O_F_ IF NOT "%k%" == "$on" GOTO ${sec}end SET $or=%1 GOTO nextshift :${sec}end _E_O_F_ else echo " '$on')"; echo " export $or=\"\$1\""; echo ' shift;'; echo ' ;;'; echo " '$on='*)"; echo ' _para=`echo "$k" | cut -d= -f2`;'; echo " export $or=\"\$_para\""; echo ' ;;'; fi done if $DOS then : # we ignore this here and handle in the next section else cat <<_E_O_F_ '-'*) echo "Unknown option" >&2; exit 1; ;; *) _E_O_F_ fi if $ARGS_PASS_NON_OPTS then if $DOS then echo "Warning: can not compile unknown options check in as target does not support it" >&2 echo "REM IGNORED UNKNOWN OPTION CHECK" if $ARGS_END_OPTS_ON_NON_OPT then cat <<_E_O_F_ SET _ARGV=%_ARGV% %k% GOTO mloopend _E_O_F_ else echo 'GOTO addshift'; fi else echo ' _args="$_args $k";'; if $ARGS_END_OPTS_ON_NON_OPT then echo ' break;'; fi fi else if $DOS then echo 'GOTO erruopt' else echo ' echo "Unknown option" >&2;'; echo ' exit 1;'; fi fi if $DOS then cat <<_E_O_F_ GOTO next :pass SET _ARGV=%_ARGV% %k% GOTO next :passval SET _ARGV=%_ARGV% %k% :addshift SET _ARGV=%_ARGV% %1 :nextshift SHIFT :next GOTO mloop :mloopend _E_O_F_ else cat <<_E_O_F_ ;; esac; done _E_O_F_ fi if $ARGS_PASS_NON_OPTS then $DOS && echo "SET _ARGS=%_ARGS% %1 %2 %3 %4 %5 %6 %7 %8 %9" $DOS || echo '_args="$_args $*";'; else if $DOS then echo 'IF "%1%2%3%4%5%6%7%8%9" GOTO erruopt' else echo 'if [ "$*" != "" ]'; echo 'then'; echo ' echo "Unknown option" >&2;'; echo ' exit 1;'; echo 'fi'; fi fi if $DOS then cat <<_E_O_F_ $RNAME %_ARGS% GOTO end :erruopt ECHO Unknown option EXIT 1 GOTO end :help _E_O_F_ if [ "$HELPOPTS" != '' ] then sed 's/^$/./; s/^/echo /; s/</#/g; s/>/#/g;' $HELPFILE fi cat <<_E_O_F_ GOTO end :end _E_O_F_ else cat <<_E_O_F_ exec $RNAME \$_args _E_O_F_ fi echo $DOS && echo 'REM ll' $DOS || echo '#ll' } > $OUT chmod a+rx $OUT rm $HELPFILE exit 0; #ll ���roaraudio-1.0beta11/compbins/audial.a���������������������������������������������������������������0000644�0001750�0001750�00000001424�11345056520�015674� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='audial' RNAME='roardtmf' ARGS_MAP_OPTS='-a:true:--server' ARGS_PASS_NON_OPTS=true # usage: audial [-options] [dialing_string] # dialing options: # -s spacing spacing between digits in milliseconds (default 100) # -p pause duration of pause "," in milliseconds (default 400) # -d duration duration of digit in milliseconds (default 100) # -v volume output volume in percent (default 100) # legal digits in the dialing_string are: 0123456789abcd*#, # all others are ignored # recognition options: # -r enable recognition mode # -m use microphone line level # -g gain input gain in percent (default 95) # -t time how long to listen in seconds (default forever) #ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/audiooss.a�������������������������������������������������������������0000644�0001750�0001750�00000000264�11336071614�016265� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='audiooss' RNAME='' ARGS_PASS_NON_OPTS=true ARGS_END_OPTS_ON_NON_OPT=true ast2roar_help --help <<__EOF__ Usage: audiooss.r command [command_options] __EOF__ #ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/auplay.a���������������������������������������������������������������0000644�0001750�0001750�00000000160�11264350116�015722� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='auplay' RNAME='roarcatplay' ARGS_MAP_OPTS='-audio:true:--server' ARGS_PASS_NON_OPTS=true #ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/dtmfdial.a�������������������������������������������������������������0000644�0001750�0001750�00000001041�11345056520�016214� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='dtmfdial' RNAME='roardtmf' ARGS_MAP_OPTS='--output-dev:true:--server --speed:true:--rate' ARGS_PASS_NON_OPTS=true # usage: dial [options] number ... # Valid options with their default values are: # Duration options: # --tone-time 100 # --silent-time 50 # --sleep-time 500 # Audio output options: # --use-audio 1 # --bufsize 4096 # --bits 8 # Audio generation options: # --table-size 256 # --volume 100 # --left 0 # --right 0 #ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/esd.a������������������������������������������������������������������0000644�0001750�0001750�00000001213�11262621462�015205� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='esd' RNAME='roard' ARGS_IGNORE_OPTS='-noterminate:false -nobeeps:false -trust:false' ARGS_PASS_OPTS='' ARGS_MAP_OPTS='-d:true:-O -r:true:-R -unix:false:-u -tcp:false:-t -terminate:false:--terminate -port:true:--port -bind:true:--bind' ARGS_PASS_NON_OPTS=true # Still to do: # -v --version print version information # -b run server in 8 bit sound mode # -as SECS free audio device after SECS of inactivity (-1 to disable) # -public make tcp/ip access public (other than localhost) # -promiscuous start unlocked and owned (disable authenticaton) NOT RECOMMENDED # -beeps enable startup beeps #ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/esdcat.a���������������������������������������������������������������0000644�0001750�0001750�00000000226�11261770662�015706� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='esdcat' RNAME='roarcat' ARGS_IGNORE_OPTS='' ARGS_PASS_OPTS='-s:true -n:true -b:false -m:false -r:true' ARGS_PASS_NON_OPTS=true #ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/esddsp.a���������������������������������������������������������������0000644�0001750�0001750�00000001425�11336070203�015712� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='esddsp' RNAME='' ARGS_IGNORE_OPTS='-m:false --mixer:false' ARGS_ENV_OPTS='-s:ROAR_SERVER --server:ROAR_SERVER -n:ROAR_OSS_CLIENT_NAME --name:ROAR_OSS_CLIENT_NAME' ARGS_PASS_NON_OPTS=true ARGS_END_OPTS_ON_NON_OPT=true ast2roar_help -h --help <<__EOF__ esddsp.r - attempt to reroute audio device to RoarAudio esddsp.r [options] player arguments options: -h, --help show brief help -s, --server=HOST:PORT contact esd server on host at port -m, --mixer enable mixer support -n, --name=NAME use name to identify player to esd __EOF__ #esddsp [options] player arguments #-v, --verbose show parameters #--mmap use memory mapping emulation # (useful for games like quake) #ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/esdfilt.a��������������������������������������������������������������0000644�0001750�0001750�00000000253�11261773277�016102� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='esdfilt' RNAME='roarfilt' ARGS_IGNORE_OPTS='' ARGS_PASS_OPTS='-s:true -b:false -m:false -r:true -half:false -double:false' ARGS_PASS_NON_OPTS=false #ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/esdmon.a���������������������������������������������������������������0000644�0001750�0001750�00000000216�11261773277�015734� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='esdmon' RNAME='roarmon' ARGS_IGNORE_OPTS='' ARGS_PASS_OPTS='-s:true -b:false -m:false -r:true' ARGS_PASS_NON_OPTS=true #ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/esdplay.a��������������������������������������������������������������0000644�0001750�0001750�00000000171�11262622463�016077� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='esdplay' RNAME='roarcatplay' ARGS_IGNORE_OPTS='' ARGS_PASS_OPTS='-s:true' ARGS_PASS_NON_OPTS=true #ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/pacat.a����������������������������������������������������������������0000644�0001750�0001750�00000003173�11323120177�015524� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='pacat' RNAME='roarcat' ARGS_IGNORE_OPTS='-p:false --playback:false' ARGS_PASS_OPTS='-h:false --help:false -s:true' ARGS_MAP_OPTS='--version:false:--help' ARGS_DEEQ_OPTS='--server --rate --channels' ARGS_PASS_NON_OPTS=true cat <<COMMENT > /dev/null pacat [options] -r, --record Create a connection for recording -v, --verbose Enable verbose operations -d, --device=DEVICE The name of the sink/source to connect to -n, --client-name=NAME How to call this client on the server --stream-name=NAME How to call this stream on the server --volume=VOLUME Specify the initial (linear) volume in range 0...65536 --format=SAMPLEFORMAT The sample type, one of s16le, s16be, u8, float32le, float32be, ulaw, alaw (defaults to s16ne) --channel-map=CHANNELMAP Channel map to use instead of the default --fix-format Take the sample format from the sink the stream is being connected to. --fix-rate Take the sampling rate from the sink the stream is being connected to. --fix-channels Take the number of channels and the channel map from the sink the stream is being connected to. --no-remix Don't upmix or downmix channels. --no-remap Map channels by index instead of name. COMMENT #ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/padsp.a����������������������������������������������������������������0000644�0001750�0001750�00000001542�11371502073�015543� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='padsp' RNAME='' ARGS_ENV_OPTS='-s:ROAR_SERVER -n:ROAR_OSS_CLIENT_NAME' ARGS_PASS_NON_OPTS=true ARGS_END_OPTS_ON_NON_OPT=true ast2roar_help -h <<__EOF__ padsp.r - redirect OSS audio devices to RoarAudio padsp.r [options] application [arguments] options: -h show brief help -s <host>[:<port>] contact a specific RoarAudio server -n <name> client name to report to the server __EOF__ #/usr/bin/padsp - redirect OSS audio devices to PulseAudio # #/usr/bin/padsp [options] application [arguments] # #options: # -m <name> stream name to report to the server # -M disable /dev/mixer emulation # -S disable /dev/sndstat emulation # -D disable /dev/dsp emulation # -d enable debug output #ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/paplay.a���������������������������������������������������������������0000644�0001750�0001750�00000001246�11323121014�015710� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='paplay' RNAME='roarcatplay' ARGS_PASS_OPTS='-h:false --help:false -s:true --verbose:false' ARGS_MAP_OPTS='--version:false:--help -v:false:--verbose' ARGS_DEEQ_OPTS='--server' ARGS_PASS_NON_OPTS=true cat <<COMMENT > /dev/null paplay [options] [FILE] -d, --device=DEVICE The name of the sink to connect to -n, --client-name=NAME How to call this client on the server --stream-name=NAME How to call this stream on the server --volume=VOLUME Specify the initial (linear) volume in range 0...65536 --channel-map=CHANNELMAP Set the channel map to the use COMMENT #ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/ross.a�����������������������������������������������������������������0000644�0001750�0001750�00000000135�11371641176�015427� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='ross' RNAME='' ARGS_PASS_NON_OPTS=true ARGS_END_OPTS_ON_NON_OPT=true #ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/rsd.a������������������������������������������������������������������0000644�0001750�0001750�00000001766�11371643671�015246� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='rsd' RNAME='roard' ARGS_PASS_OPTS='-p:true --port:true --daemon:false --verbose:false -h:false --help:false' ARGS_MAP_OPTS='-d:true:-O --device:true:-O -b:true:-o --backend:true:-o -D:false:--daemon -v:false:--verbose --debug:false:--verbose --kill:false:--stop' ARGS_PASS_NON_OPTS=false #TODO: --single #--single: Only allows a single connection at a time. ast2roar_help -h --help <<__EOF__ roard ========================================================================== Usage: rsd [ -d/--device | -b/--backend | -p/--port | -D/--daemon | -v/--verbose | --debug | -h/--help | --kill ] -d/--device: Specifies an ALSA or OSS device to use. Examples: -d hw:1,0 -d /dev/audio -b/--backend: Specifies which audio backend to use. -D/--daemon: Runs as daemon. -p/--port: Defines which port to listen on. Example: -p 18453. -v/--verbose: Enables verbosity -h/--help: Prints this help --debug: Enable more verbosity --kill: Cleanly shuts downs the running rsd process. __EOF__ #ll ����������roaraudio-1.0beta11/compbins/rsdplay.a��������������������������������������������������������������0000644�0001750�0001750�00000002622�11372006426�016114� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='rsdplay' RNAME='roarcat' ARGS_ADD_OPTS='--codec riff_wave' ARGS_PASS_OPTS='--server:true --rate:true -B:true --bits:true' ARGS_MAP_OPTS='-s:true:--server -r:true:--rate -c:true:--chans --channels:true:--chans -f:true:"" --file:true:"" --raw:false:--codec""default' ARGS_PASS_NON_OPTS=false # TODO: -p/--port ast2roar_help -h --help <<__EOF__ roarcat (libroar) ========================================================================= Usage: rsdplay.r [ -h/--help | --raw | -r/--rate | -c/--channels | -B/--bits | -f/--file | -s/--server ] rsdplay.r reads PCM data only through stdin (default) or a file, and sends this data directly to an rsound server. Unless specified with --raw, rsdplay expects a valid WAV header to be present in the input stream. Examples: rsdplay.r -s foo.net < bar.wav cat bar.wav | rsdplay -s foo.net -p 4322 --raw -r 48000 -c 2 --raw: Enables raw PCM input. When using --raw, rsdplay will generate a fake WAV header -r/--rate: Defines input samplerate (raw PCM) Example: -r 48000. Defaults to 44100 -c/--channel: Specifies number of sound channels (raw PCM) Example: -c 1. Defaults to stereo (2) -B: Specifies sample format in raw PCM stream Supported formats are: S16LE, S16BE, U16LE, U16BE, S8, U8. -h/--help: Prints this help -f/--file: Uses file rather than stdin -s/--server: More explicit way of assigning hostname __EOF__ #ll ��������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/yiff.a�����������������������������������������������������������������0000644�0001750�0001750�00000001211�11272601255�015364� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='yiff' RNAME='roard' ARGS_MAP_OPTS='--version:false:--help --device:true:-O' ARGS_PASS_OPTS='--port:true --help:false' ARGS_PASS_NON_OPTS=false #Usage: yiff [config_file] [options] # # [config_file] specifies the configuration file to be used. # # [options] can be any of the following: # # --mixer <device> Specifies the mixer device. # --mixer_rc <file> Specifies alternate mixer settings file. # --path <path> Adds a sound path (can be used # more than once). # --foreground Run in foreground, do not fork into background. #ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/yplay.a����������������������������������������������������������������0000644�0001750�0001750�00000000202�11272600063�015560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='yplay' RNAME='roarcatplay' ARGS_MAP_OPTS='--recorder:true:--server -s:true:--rate' ARGS_PASS_NON_OPTS=true #ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/compbins/yshutdown.a������������������������������������������������������������0000644�0001750�0001750�00000000211�11272600063�016466� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh NAME='yshutdown' RNAME='roarctl' ARGS_ADD_OPTS='exit' ARGS_MAP_OPTS='--recorder:true:--server' ARGS_PASS_NON_OPTS=false #ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/���������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553167�013440� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/OpenSolaris/���������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553167�015676� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/OpenSolaris/RoarAudio.spec�������������������������������������������������0000644�0001750�0001750�00000002231�11203536524�020420� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # spec file for package: roaraudio # # This file and all modifications and additions to the pristine # package are under the same license as the package itself. # # includes module(s): [pkg module(s)] # %include Solaris.inc Name: roaraudio Summary: RoarAudio is a cross-platform sound system for both, home and professional use. Version: 0.2rc1 License: GPLv3, LGPLv3 Url: http://roaraudio.keep-cool.org/ Source: http://roaraudio.keep-cool.org/dl/%{name}-%{version}.tar.gz Group: [ips pkg classification] Distribution: OpenSolaris Vendor: OpenSolaris Community BuildRoot: %{_tmppath}/%{name}-%{version}-build SUNW_Basedir: %{_basedir} SUNW_Copyright: %{name}.copyright %include default-depend.inc # OpenSolaris IPS Package Manifest Fields Meta(info.upstream): [name email of open source project leader] Meta(info.maintainer): [name email of ips pkg porter/maintainer] Meta(info.repository_url): [open source code repository] %description [long description] %prep [pre-build commands] %build [build commands] %install [install commands] %clean [cleanup commands] %files [file groups and permissions] %changelog [change log entries] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/archlinux/�����������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553167�015435� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/archlinux/roard������������������������������������������������������������0000644�0001750�0001750�00000001333�11163212065�016446� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash # source application-specific settings ROARD_ARGS='--daemon' [ -f /etc/conf.d/roard ] && . /etc/conf.d/roard . /etc/rc.conf . /etc/rc.d/functions PID=`pidof -o %PPID /usr/bin/roard` case "$1" in start) stat_busy "Starting Roaraudio Daemon" [ -z "$PID" ] && /usr/bin/roard ${ROARD_ARGS} if [ $? -gt 0 ]; then stat_fail else add_daemon roard stat_done fi ;; stop) stat_busy "Stopping Roaraudio Daemon" [ ! -z "$PID" ] && kill $PID &> /dev/null if [ $? -gt 0 ]; then stat_fail else rm_daemon roard stat_done fi ;; restart) $0 stop sleep 1 $0 start ;; *) echo "usage: $0 {start|stop|restart}" esac exit 0 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/debian-like/���������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553167�015604� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/debian-like/defaults�������������������������������������������������������0000644�0001750�0001750�00000011337�11760674707�017344� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#RoarAudio Configuration # --- [ General Options ]--- # Start roard? YES or NO: ROARD='YES' # Additionl Options to pass to roard, should normally be empty ROARD_OPTS='' # Should we run roard in realtime mode: # NO - Don't run in realtime mode # YES - Run in realtime mode # DOUBLE - Try to run in a 'very realtime mode' ROARD_REALTIME='YES' # PIDFile for roard: # Default is enabled, at /var/run/roard.pid # Set to empty string to disable. #PIDFILE='/var/run/roard.pid' # Location of roard: # This is a lion readable location of the roard used # for Zero Conf locating of a RoarAudio server on the # Network. To use Zero Conf enable SLP (see below). #ROARD_LOCATION='' # Description for roard: # This is a lion readable description for the server. # It is used for Zero Conf like the location above. #ROARD_DESCRIPTION='' # Contact for roard: # This lion is a contact info for the server. # It is in format: # first ["']nick["'] last (comment) <email>/OpenPGPkey/Phone/Room #ROARD_CONTACT='' # Serial for roard: # This is the serial numer for the device this roard runs on. # This is only useful if this runs on an embedded device. #ROARD_SERIAL='' # User interface URL for roard: # This is an url to a user interface used to control this roard or system. # This can also be a telnet://, llogin:// or ssh:// url. #ROARD_UIURL='' # Default location for roard: # Set this to a remote address and disable local roard # to run a network only setup. # ROARAUDIO_DEFAULT_SOCKET='server.local' # --- [ Network ] --- # Listening socket's address family: # UNIX - Local connections only # TCP - Connections via TCP/IP # DECnet - Connections via DECnet ROARD_AF='UNIX' # Socket to listen on (UNIX): ROARD_SOCKET='/tmp/roar' # Port to listen on (TCP): # ROARD_PORT=16002 # Host/Nodename to listen on (TCP, DECnet): # use a value of '0.0.0.0' to listen publicly for TCP. # ROARD_HOST='0.0.0.0' # Object to listen on (DECnet): # ROARD_OBJECT='roar' # Annouce us via OpenSLP: # Set to YES or NO. # In case of YES roarclients can autolocat this server # on the network. ROARD_SLP='NO' # --- [ EsounD Emulation ] --- # Listen socket for server side EsounD emulation: # NONE - Disable EsounD emulation # UNIX - Local connections only # TCP - Connections via TCP/IP ROARD_EMUL_ESD_AF='NONE' # --- [ RSound Emulation ] --- # Listen socket for server side RSound emulation: # NONE - Disable RSound emulation # UNIX - Local connections only # TCP - Connections via TCP/IP # DECnet - Connections via DECnet ROARD_EMUL_RSOUND_AF='NONE' # --- [ Other listen sockets ] --- # List of additional listen profiles to enable: # To get a list run: roard --list-profiles # Default: (empty) #ROARD_PROFILES='' # --- [ Audio and Devices ] --- # Samplerate, number of channels and bits per sample: # ROARD_RATE=44100 # ROARD_CHANNELS=2 # ROARD_BITS=32 # Alternatively setting samplerate, channels and bits by AI Profile: # ROARD_AIPROFILE='default-server' # Sound Driver and Device: # To get a list run: roard --list-driver # Don't forget to include 'sync' in the options unless # you REALLY, REALLY know what you are doing # ROARD_DRIVER='oss' # ROARD_DEVICE='/dev/dsp' # ROARD_DRIVER_OPTIONS='sync,autoconf' # The Mixer Driver and Device: # To get a list run: roard --list-mixers # ROARD_MIXERDRV='oss' # ROARD_MIXERDEV='/dev/mixer' # ROARD_MIXER_OPTIONS='' # --- [ Sources ] --- # Radionoise source: # The radionoise source is a noise source at -102dB. # This is used to avoid icecast to timeout on silence. # See Docs for more infos. # ROARD_SOURCE_RADIONOISE='NO' # --- [ RoleStack ] --- # Push entries to the RoleStack: # See Docs on RoleStack for more infos. # Defaults to roard's internal defaults. # ROARD_ROLESTACK='' # --- [ Plugins ] --- # Plugins to load: # This lists the plugins to load. If no path is given (recommended) # they are loaded from the plugin search path. # Both, roard and universal (/multi-host) plugins can be loaded. # ROARD_PLUGINS='' # --- [ Auth Options ] --- # Access levels: # Those options set the access level for clients. # The guest option sets the access level for guest connections. # The trust option sets the access level for connections # successfully used the TRUST auth. # ROARD_ACCLEV_GUEST='' # ROARD_ACCLEV_TRUST='' # Authfile: # This can be used to generate an authfile. # This may be needed for example by the ESD protocol emulation. # ROARD_AUTHFILE_FILENAME='' # ROARD_AUTHFILE_TYPE='' # ROARD_AUTHFILE_ACCLEV='' # --- [ Permitions ] --- # User and Group to run roard with: # Note: Users in the same group my access roard # if runnung in UNIX mode. # ROARD_USER='roard' # ROARD_GROUP='audio' # --- [ Security ] --- # Directory to chroot to: # Use empty value to disable. # Directory may/should be completly empty. #ROARD_CHROOT='' #ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/dist/debian-like/roaraudio������������������������������������������������������0000755�0001750�0001750�00000017670�11760674707�017533� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # roaraudio initscript # # Copyright (c) 2008-2012 Philipp 'ph3-der-loewe' Schafft <lion@lion.leolix.org> # Copyright (c) 2007 Javier Fernandez-Sanguino <jfs@debian.org> # # This is free software; you may redistribute it and/or modify # it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 3, # or (at your option) any later version. # # This is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License with # the Debian operating system, in /usr/share/common-licenses/GPL; if # not, write to the Free Software Foundation, Inc., 59 Temple Place, # Suite 330, Boston, MA 02111-1307 USA # ### BEGIN INIT INFO # Provides: roaraudio # Required-Start: $network $local_fs $remote_fs $syslog # Required-Stop: $network $local_fs $remote_fs $syslog # Should-Start: # Should-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: sound server for audio mixing # Description: RoarAudio is a server for audio mixing. Its main purpose is to mix audio from # different clients before sending it to its outputs (for example a soundcard). # It is completely network transparent (UNIX sockets, TCP/IP, DECnet) and # supports many common codecs like Ogg Vorbis, Speex or FLAC. ### END INIT INFO #set -e PATH=/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/bin/roard ROARCTL=/usr/bin/roarctl NAME=roaraudio DESC="RoarAudio" DAEMON_BN=`basename $DAEMON` PIDFILE=/var/run/$DAEMON_BN.pid SCRIPTNAME=/etc/init.d/$NAME USER_LIST="$DAEMON_BN roard roar nobody"; # List of files to chown to the daemon user CHOWN_LIST='' # Gracefully exit if the package has been removed. test -x $DAEMON || exit 0; # Read config file if it is present. if [ -r /etc/default/$NAME ] then . /etc/default/$NAME fi if [ "$ROARAUDIO_DEFAULT_SOCKET" != '' ] then ln -s "$ROARAUDIO_DEFAULT_SOCKET" /etc/roarserver fi ROARD_OPTS="--log-syslog --daemon $ROARD_OPTS" [ "$PIDFILE" = '' ] || ROARD_OPTS="--pidfile $PIDFILE $ROARD_OPTS" [ "$ROARD_REALTIME" = 'YES' ] && ROARD_OPTS="--realtime $ROARD_OPTS" [ "$ROARD_REALTIME" = 'DOUBLE' ] && ROARD_OPTS="--realtime --realtime $ROARD_OPTS" [ "$ROARD_LOCATION" = '' ] || ROARD_OPTS="--location '$ROARD_LOCATION' $ROARD_OPTS" [ "$ROARD_DESCRIPTION" = '' ] || ROARD_OPTS="--description '$ROARD_DESCRIPTION' $ROARD_OPTS" [ "$ROARD_CONTACT" = '' ] || ROARD_OPTS="--contact '$ROARD_CONTACT' $ROARD_OPTS" [ "$ROARD_SERIAL" = '' ] || ROARD_OPTS="--serial '$ROARD_SERIAL' $ROARD_OPTS" [ "$ROARD_UIURL" = '' ] || ROARD_OPTS="--uiurl '$ROARD_UIURL' $ROARD_OPTS" [ "$ROARD_SOCKET" = '' ] || ROARD_OPTS="--sock $ROARD_SOCKET $ROARD_OPTS" [ "$ROARD_PORT" = '' ] || ROARD_OPTS="--port $ROARD_PORT $ROARD_OPTS" if [ "$ROARD_OBJECT" = '' ] then [ "$ROARD_HOST" = '' ] || ROARD_OPTS="--bind $ROARD_HOST $ROARD_OPTS" else ROARD_OPTS="--sock $ROARD_HOST::$ROARD_OBJECT $ROARD_OPTS" fi case "$ROARD_AF" in UNIX|unix) ROARD_OPTS="-u $ROARD_OPTS" ;; TCP|tcp) ROARD_OPTS="-t $ROARD_OPTS" ;; DECnet|DECNET|decnet) ROARD_OPTS="-n $ROARD_OPTS" ;; esac ESD_OPTS='' case "$ROARD_EMUL_ESD_AF" in UNIX|unix) ROARD_PROFILES="esd-unix $ROARD_PROFILES" mkdir /tmp/.esd/ 2> /dev/null; CHOWN_LIST="$CHOWN_LIST /tmp/.esd/" ;; TCP|tcp) _host='localhost'; [ "$ROARD_HOST" = '' ] || _host="$ROARD_HOST" ESD_OPTS="--new-sock --proto esd -t -b $_host -p 16001" ;; esac RSOUND_OPTS='' case "$ROARD_EMUL_RSOUND_AF" in UNIX|unix) ROARD_PROFILES="rsound-unix $ROARD_PROFILES" ;; TCP|tcp) _host='localhost'; [ "$ROARD_HOST" = '' ] || _host="$ROARD_HOST" RSOUND_OPTS="--new-sock --proto rsound -t -b $_host -p 12345" ;; DECnet|DECNET|decnet) ROARD_PROFILES="rsound-dnet $ROARD_PROFILES" ;; esac if [ "$ROARD_PROFILES" != '' ] then _p=`echo "$ROARD_PROFILES" | sed 's/ */ --new-sock --proto-profile /g'` ROARD_OPTS="$ROARD_OPTS --new-sock --proto-profile $_p" fi [ "$ROARD_SLP" = 'YES' ] && ROARD_OPTS="--slp $ROARD_OPTS" [ "$ROARD_RATE" = '' ] || ROARD_OPTS="-R $ROARD_RATE $ROARD_OPTS" [ "$ROARD_CHANNEL" = '' ] || ROARD_OPTS="-C $ROARD_CHANNEL $ROARD_OPTS" [ "$ROARD_BITS" = '' ] || ROARD_OPTS="-B $ROARD_BITS $ROARD_OPTS" [ "$ROARD_AIPROFILE" = '' ] || ROARD_OPTS="--aiprofile $ROARD_AIPROFILE $ROARD_OPTS" [ "$ROARD_DRIVER" = '' ] || ROARD_OPTS="-o $ROARD_DRIVER $ROARD_OPTS" [ "$ROARD_DEVICE" = '' ] || ROARD_OPTS="-O $ROARD_DEVICE $ROARD_OPTS" [ "$ROARD_DRIVER_OPTIONS" = '' ] && ROARD_DRIVER_OPTIONS='sync,autoconf' ROARD_OPTS="-oP -oO $ROARD_DRIVER_OPTIONS $ROARD_OPTS" [ "$ROARD_MIXERDRV" = '' ] || ROARD_OPTS="-m $ROARD_MIXERDRV $ROARD_OPTS" [ "$ROARD_MIXERDEV" = '' ] || ROARD_OPTS="-M $ROARD_MIXERDEV $ROARD_OPTS" [ "$ROARD_MIXER_OPTIONS" = '' ] || ROARD_OPTS="-mO $ROARD_MIXER_OPTIONS $ROARD_OPTS" [ "$ROARD_SOURCE_RADIONOISE" = 'YES' ] && ROARD_OPTS="-s radionoise $ROARD_OPTS" for _p in $ROARD_ROLESTACK do ROARD_OPTS="--rolestack-push $_p $ROARD_OPTS" done for _p in $ROARD_PLUGINS do ROARD_OPTS="--plugin-load $_p $ROARD_OPTS" done [ "$ROARD_ACCLEV_GUEST" = '' ] || ROARD_OPTS="--guest-acclev $ROARD_ACCLEV_GUEST $ROARD_OPTS" [ "$ROARD_ACCLEV_TRUST" = '' ] || ROARD_OPTS="--trust-acclev $ROARD_ACCLEV_TRUST $ROARD_OPTS" [ "$ROARD_AUTHFILE_FILENAME" = '' ] || ROARD_OPTS="--authfile-gen $ROARD_AUTHFILE_FILENAME $ROARD_OPTS" [ "$ROARD_AUTHFILE_TYPE" = '' ] || ROARD_OPTS="--authfile-type $ROARD_AUTHFILE_TYPE $ROARD_OPTS" [ "$ROARD_AUTHFILE_ACCLEV" = '' ] || ROARD_OPTS="--authfile-acclev $ROARD_AUTHFILE_ACCLEV $ROARD_OPTS" if [ "$ROARD_USER" = '' ] then for _u in $USER_LIST do _r=`id -un $_u 2> /dev/null` if [ "$_u" = "$_r" ] then ROARD_USER="$_u"; break; fi done else _r=`id -un "$ROARD_USER" 2> /dev/null` if [ "$_r" != "$ROARD_USER" ] then echo "Error starting RoarAudio: can not find configured user $ROARD_USER" >&2 echo "Hint: re-configure user in /etc/default/$NAME (see ROARD_USER)" >&2 exit 1; fi fi if [ "$ROARD_USER" = '' ] then echo "Error starting RoarAudio: can not find any user to run roard as." >&2 echo "Hint: configure user in /etc/default/$NAME explicitly (see ROARD_USER)" >&2 exit 1; else ROARD_OPTS="--setuid -U $ROARD_USER $ROARD_OPTS" fi ROARD_OPTS="--setgid $ROARD_OPTS" [ "$ROARD_GROUP" = '' ] || ROARD_OPTS="-G $ROARD_GROUP $ROARD_OPTS" [ "$ROARD_CHROOT" = '' ] || ROARD_OPTS="--chroot $ROARD_CHROOT $ROARD_OPTS" ROARD_OPTS="$ROARD_OPTS $ESD_OPTS $RSOUND_OPTS" for _p in $CHOWN_LIST do chown "$ROARD_USER":"$ROARD_GROUP" "$_p" done set -e case "$1" in start) [ "$ROARD" = 'YES' ] || exit 0; echo -n "Starting $DESC: " $DAEMON --start $ROARD_OPTS echo "$NAME." ;; stop) echo -n "Stopping $DESC: " set +e if [ "$PIDFILE" != '' ] then PID=`cat $PIDFILE 2> /dev/null` if [ "$PID" != '' ] then kill -0 $PID 2> /dev/null if [ "$?" != '0' ] then exit 0; fi else exit 0; fi fi $DAEMON --stop $ROARD_OPTS echo "$NAME." set -e ;; status) echo -n "Status of $DESC: " set +e if [ "$PIDFILE" != '' ] then PID=`cat $PIDFILE 2> /dev/null` if [ "$PID" != '' ] then kill -0 $PID 2> /dev/null if [ "$?" = '0' ] then echo "running." exit 0; else echo "dead (stale pid file)." exit 1; fi else echo "not running." exit 3; fi fi set -e echo "unknown (no pid file configured)." exit 4 ;; restart|force-reload) [ "$ROARD" = 'YES' ] || exec $0 stop echo -n "Restarting $DESC: " $DAEMON --restart $ROARD_OPTS echo "$NAME." ;; terminate|shutdown) echo -n "Terminating $DESC: " $DAEMON --shutdown $ROARD_OPTS echo "$NAME." ;; *) echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|terminate|shutdown|status}" >&2 exit 1 ;; esac exit 0 ������������������������������������������������������������������������roaraudio-1.0beta11/dist/debian-like/sndio.h��������������������������������������������������������0000644�0001750�0001750�00000000255�11414075241�017054� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//sndio.h: #define _ROAR_EMUL_LIBSNDIO #ifdef ROAR_HAVE_LIBSNDIO #undef ROAR_HAVE_LIBSNDIO #endif #include <libroarsndio/libroarsndio.h> #define ROAR_HAVE_LIBSNDIO //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553170�013234� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/html/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�014201� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553244�014072� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roar-config.1����������������������������������������������������������0000644�0001750�0001750�00000004333�12100227470�016346� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar-config.1: .TH "roar-config" "1" "January 2010" "RoarAudio" "System User's Manual: roar-config" .SH NAME roar-config \- get information of installed RoarAudio libraries .SH SYNOPSIS roar-config \-\-version roar-config \-\-compare-versions VERSIONA OPERATOR VERSIONB roar-config [{\-\-output-pc|\-\-output-normal}] [\-\-libs] [\-\-cflags] [LIB] roar-config [\-\-product PRODUCT] [\-\-provider PROVIDER] [\-\-universal] {\-\-path PATH|\-\-list\-path} roar-config \-\-render\-path PATH .SH DESCRIPTION This small tool prints information about installed versions and needed flags to work with the RoarAudio libraries. .SH "OPTIONS" .TP \fB--help\fR Show a brief help. .TP \fB--version\fR Show version of library .TP \fB--compare-versions VERSIONA OPERATOR VERSIONB\fR Compares version VERSIONA against version VERSIONB using operator OPERATOR. Both versions must be in dotted format (e.g. 1.0.8) or the special keyword "current". This keyword represents the current used version. Operator may be "eq" (equal), "ne" (not equal), "gt" (greater than), "ge" (greater than or equal), "lt" (less than) or "le" (less than or equal). This function is mostly useful to check for minimum required or maximum supported versions of libroar in configure scripts. .TP \fB--path NAME\fR Print path NAME. Examples for NAME include prefix-plugins. .TP \fB--list-path\fR List all known paths with corresponding values. .TP \fB--product PRODUCT\fR Product string for \-\-path and \-\-list\-path. .TP \fB--provider PROVIDER\fR Provider string for \-\-path and \-\-list\-path. .TP \fB--universal\fR Use universal path for \-\-path and \-\-list\-path. .TP \fB--render-path PATH\fR Render the given path. The path can be any absolute path, a path relative to the user's home directory (prefixed with ~/) or a path relative to a path as used by \-\-path (prefixed with $ and path name). .TP \fB--libs\fR Show linker flags (\-lxxx) needed to link library .TP \fB--cflags\fR Show compiler flags needed to link library .TP \fB--output-pc\fR Output in PC format. .TP \fB--output-normal\fR Output in "classical" format. .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarbaseclients.1������������������������������������������������������0000644�0001750�0001750�00000004057�11413145155�017330� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roard.1: .TH "roarbaseclients" "1" "July 2008" "RoarAudio" "System Manager's Manual: roard" .SH NAME roarcat, roarmon \- RoarAudio sound server base clients .SH SYNOPSIS roarcat [OPTIONS]... [FILE] roarmon [OPTIONS]... .SH "DESCRIPTION" This are some basic clients for RoarAuido. Some more complex are listen in the \fbSEE ALSO\fR block. For controlling \fBroard\fR take a look at \fBroarctl\fR(1). For a simple Ogg Vorbis player take a look at \fBroarvorbis\fR(1) (ogg123 supportes RoarAudio via libao plugin). .TP \fBroarcat\fR Sends raw PCM audio data from a file or stdin (pipe) to the sound server. .TP \fBroarmon\fR Gets a copy of the audio data the server sends to the soundcard. This is useful for streaming to a server like \fBicecast2\fR(1). .SH "GENERAL OPTIONS" \fBNOTE: This list is incomplete!\fR In addition to this list all three programs provide compatible options for esdcat, esdmon. You can just replace the "esd" in the name with "roar" or use symlinks. This options are for compatibly only and should not used in new programs. .TP \fB--help\fR Print some help text. .SH "AUDIO OPTIONS" .TP \fB--rate RATE\fR, \fB-R RATE\fR Set server sample rate. .TP \fB--bits BITS\fR, \fB-B BITS\fR Set server bits. .TP \fB--chans CHANNELS\fR, \fB-C CHANNELS\fR Set server channels. .SH "NETWORK OPTIONS" .TP \fB--server SERVER\fR The server to connect to. .SH "ENVIRONMENT VARIABLES" Bellow only the basic environment varibales are listend. For a complete list see \fBlibroar\fR(7). .TP \fBHOME\fR The users home directory. .TP \fBROAR_SERVER\fR The address of the listening server. This may be in form of host:port for TCP/IP connections and /path/to/sock for UNIX Domain Sockets or any other supported format. See \fBroartips\fR(7) for a full list. This is the same as the \fB--server\fR option. .SH "BUGS" There are a lot of bugs... .SH "SEE ALSO" \fBroarctl\fR(1), \fBroarvorbis\fR(1), \fBroarfish\fR(1), \fBroartestclients\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarbidir.1������������������������������������������������������������0000644�0001750�0001750�00000001431�11322141610�016105� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarbidir.1: .TH "roarbidir" "1" "January 2010" "RoarAudio" "System User's Manual: roarbidir" .SH NAME roarbidir \- Opens a bidirectional stream to RoarAudio's sound server .SH SYNOPSIS roarbidir [OPTIONS]... [IN_FILE] .SH DESCRIPTION Opens a bidirectional stream to RoarAudio's sound server. The data is read from stdin or the provideded file and send to stdout. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarcatpassfh.1��������������������������������������������������������0000644�0001750�0001750�00000001352�11413160755�017006� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarcatpassfh.1: .TH "roarcatpassfh" "1" "July 2010" "RoarAudio" "System User's Manual: roarcatpassfh" .SH NAME roarcatpassfh \- Send audio data to RoarAudio sound server using PASSFH .SH SYNOPSIS roarcatpassfh [OPTIONS]... .SH DESCRIPTION Send audio data to RoarAudio sound server using the PASSFH protocol command. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarcatplay.1����������������������������������������������������������0000644�0001750�0001750�00000001747�12230741753�016500� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarcatplay.1: .TH "roarcatplay" "1" "October 2013" "RoarAudio" "System User's Manual: roarcatplay" .SH NAME roarcatplay \- play files via RoarAudio .SH SYNOPSIS roarcatplay [OPTIONS]... [FILE] .SH DESCRIPTION This tool plays files using RoarAudio doing client side auto detecting of file type. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--simple\fR Use the simple interface (default) .TP \fB--verbose\fR Use verbose output .TP \fB--help\fR Show this help .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB--aiprofile PROFILE\fR Use a predefined audio profile. .SH "REMOVED OPTIONS" The following options has been removed: \fB--passive\fR, \fB--background\fR .SH "SEE ALSO" \fBroarcat\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �������������������������roaraudio-1.0beta11/doc/man1/roarcatsendfile.1������������������������������������������������������0000644�0001750�0001750�00000001412�11413160755�017310� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarcatsendfile.1: .TH "roarcatsendfile" "1" "July 2010" "RoarAudio" "System User's Manual: roarcatsendfile" .SH NAME roarcatsendfile \- Send audio data to RoarAudio sound server using old kernel land sendfile .SH SYNOPSIS roarcatsendfile [OPTIONS]... [FILE] .SH DESCRIPTION Send audio data to RoarAudio sound server using old kernel land sendfile. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarcatvio.1�����������������������������������������������������������0000644�0001750�0001750�00000001664�12230741753�016326� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarcatvio.1: .TH "roarcatvio" "1" "October 2013" "RoarAudio" "System User's Manual: roarcatvio" .SH NAME roarcatvio \- send files to RoarAudio using VIO API .SH SYNOPSIS roarcatvio [OPTIONS]... [FILE] .SH DESCRIPTION This tool is now marked as obsolete and will soon be removed. You should switch to \fBroarcatplay\fR(1). This tool sends files to roard using the RoarAudio VIO API. It uses RoarAudio's DSTR to open the file so it also supports HTTP and other network protocol. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroarcat\fR(1), \fBroarcatplay\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarclientpass.1�������������������������������������������������������0000644�0001750�0001750�00000003177�11417701202�017176� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarclientpass.1: .TH "roarclientpass" "1" "July 2010" "RoarAudio" "System User's Manual: roarclientpass" .SH NAME roarclientpass \- Passing clients to and creating new listen sockets on RoarAudio sound server .SH SYNOPSIS roarclientpass [OPTIONS]... .SH DESCRIPTION This program let you pass new clients to a RoarAudio sound server as as a proxy and let you add new listen sockets to a running server. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname. .TP \fB--stdin\fR Client is on stdin. .TP \fB--stdout\fR Client is on stdout. .TP \fB--stdio\fR Same as \-\-stdin \-\-stdout. This option may for example be used in case of being runed from a inetd. .TP \fB--stderr\fR Client is on stderr. Beside to make stderr known as client fh it will disable error output on stderr. This \fBmust\fR be used in case this program is used from inetd or simular tools. .TP \fB--client-fh FH\fR Client is on FH. This is basicly the same as \-\-client-fh on roard(1). .TP \fB--proto PROTO\fR Set the protocol used by the client. Defaults to RoarAudio. .TP \fB--byteorder BO\fR Sets the byteorder used by the client. Defaults to network byte order. .TP \fB--listen\fR Client is a listen connection. This is not the same as \-\-mode listen. .TP \fB--mode MODE\fR Set mode of operation: none, listen or connect Defaults to none. .TP \fB--bind BIND\fR Set host/node/path for mode listen and connect. .TP \fB--port PORT\fR Set port for mode listen and connect. .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarctl.1��������������������������������������������������������������0000644�0001750�0001750�00000013723�12072423201�015607� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roard.1: .TH "roarctl" "1" "July 2008" "RoarAudio" "System Manager's Manual: roard" .SH NAME roarctl \- RoarAudio sound server controll tool .SH SYNOPSIS roarcat [OPTIONS]... COMMAND [OPTS] [COMMAND [OPTS] [COMMAND [OPTS] [...]]] .SH "DESCRIPTION" This tool controlls the RoarAudio's sound server. This is done by sending commands to the server. See \fBCOMMANDS\fR for a list. .SH "GENERAL OPTIONS" .TP \fB--help\fR Print some help text. .TP \fB--verbose\fR, \fB\-v\fR Be verbose. May be used multiple times. .TP \fB--list-libstandards\fR Similar to serverstandards, reports the list of standard libroar supports. .TP \fB--list-aiprofiles\fR Show audio info profiles and exit. .TP \fB--enum-servers\fR List servers found on the network. Depending on the build options of libroar this includes results from many tests like standard server locations, OpenSLP located servers, X11 located servers, DECnet's neighbor and IP's ARP table and other sources. .SH "NETWORK OPTIONS" .TP \fB--server SERVER\fR The server to connect to .SH "BASIC COMMANDS" .TP \fBhelp\fR Same as \fB--help\fR. .TP \fBlistaiprofiles\fR List audio info profiles. .TP \fBaiprofileget PROFILE\fR Display a the given audio info profile. .TP \fBsleep TIME\fR Sleeps for TIME seconds. .TP \fBping NUM\fR Pings the server NUM times. This is done by sending NOOP commands to the server. The response time as well as as a small statistics section is printed. This is not supported on all platforms. .TP \fBservername\fR This command shows the server address of the server currently connected to. This can be diffrent from what has given e.g. in case of special server names like +fork. .TP \fBwhoami\fR Report client ID of roarctl on the current server. .TP \fBstandby\fR, \fBoff\fR, \fBresume\fR, \fBon\fR Brings the server into standby mode or back into achtive (operating mode). .TP \fBstandbymode\fR Tells if the server is in standby mode or not. .TP \fBexit\fR Quits the server. .TP \fBterminate\fR Terminates the server as soon as all clients disconnected and all streams reaches EOF. .SH "STREAM COMMANDS" .TP \fBvolume STREAMID CHANNELS VOL0 VOL1 VOL2...\fR Sets the mixing level for a stream with id \fISTREAMID\fR. \fICHANNELS\fR is the nummber of channels to set volume. This should be the number of channels of the stream or a symbolic name. Currently the symbolic names \fBmono\fR and \fBstereo\fR are allowed. If you use \fBmono\fR all channels will get the level you give as \fIVOL0\fR. If you use \fBstereo\fR it will try to set the mixing levels as you are used from stereo setups even if the setup is not in stereo. The parameters \fIVOL0\fR ... \fIVOLn\fR and the number of them depends on what you gave as \fICHANNELS\fR. You have to give exactly \fICHANNELS\fR parameters. If you give a numerical (not symbolic) value for \fICHANNELS\fR and the stream does have a diffrent number of channels the behavor is undefined. In the current implementation only the first \fICHANNELS\fR channels will be updated. This behavor may change in the future. .TP \fBkick TYPE ID\fR Kicks an object of \fITYPE\fR with id \fIID\fR. Possible types are: \fBclient stream sample source\fR You can get the \fIID\fR via \fBlist*\fR (see bellow). .TP \fBnewvirtual P D E R B C\fR Adds a new virtual (child) stream. This is used with container formats such as RAUM, Ogg and Matroska. Parameters: .RS .TP \fBP\fR Stream ID of \fBP\fRarent stream. .TP \fBD\fR Stream \fBD\fRirection. .TP \fBE\fR Stream cod\fBE\fRc. .TP \fBR\fR Sample \fBR\fRate. .TP \fBB\fR \fBB\fRits per sample. .TP \fBC\fR Number of \fBC\fRhannels. .RE .TP \fBflag ID FLAGS\fR, \fBunflag ID FLAGS\fR, \fBtoogleflag ID FLAGS\fR Sets, removes or toggles flags on a stream. ID is the stream id. FLAGS is a comma separated list of flags. It is not possible to set all kinds of flags at runtime. .TP \fBprotectflag ID FLAGS\fR Protects flags on a stream. ID is the stream id. FLAGS is a comma separated list of flags. Protected flags can not be changed anymore after the they got protected. .SH "META DATA COMMANDS" .TP \fBrole ID ROLE\fR Set stream role ROLE on stream ID. .TP \fBmetaget ID TYPE\fR Read meta date of type TYPE from stream ID. .TP \fBmetasave ID FILE\fR Saves the meta data of stream ID to file FILE. The Format is one KEY=Value pair per line. The same format is used by Xiph's tools. .TP \fBmetaload ID FILE\fR Load meta data from file FILE into stream ID. The format is the same as for \fBmetasave\fR. .SH "SERVER INFO COMMANDS" .TP \fBserverinfo\fR Gets general information about the server. This includes software vendor and version. .TP \fBservertime\fR Reports the server's system time. .TP \fBserverstandards\fR Report a list of standards the server supports. .TP \fBlibstandards\fR Similar to serverstandards, reports the list of standard libroar supports. Same as \fB--list-libstandards\fR. .TP \fBserveroinfo\fR Gets Information about server output. .TP \fBserveroinfo2 DIR\fR Gets Information about server output for a given direction. .SH "LISTING COMMANDS" .TP \fBlistclients\fR Gets Information about clients. .TP \fBclientinfo ID\fR Gets Information about client ID. .TP \fBliststreams\fR Gets Information about streams. .TP \fBstreaminfo ID\fR Gets Information about stream ID. .TP \fBallinfo\fR Same as "\fBserveroinfo\fR \fBlistclients\fR \fBliststreams\fR". .SH "ENVIRONMENT VARIABLES" Bellow only the basic environment varibales are listend. For a complete list see \fBlibroar\fR(7). .TP \fBHOME\fR The users home directory. .TP \fBROAR_SERVER\fR The address of the listening server. This may be in form of host:port for TCP/IP connections and /path/to/sock for UNIX Domain Sockets. This is the same as the \fB--server\fR option. .SH "BUGS" 1) Make the meta data commands api-fixed and list them here. 2) more often check if the user gave us enough arguments. .SH "SEE ALSO" \fBroarvorbis\fR(1), \fBroarfish\fR(1), \fBroarbaseclients\fR(1), \fBroartestclients\fR(1), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ���������������������������������������������roaraudio-1.0beta11/doc/man1/roard.1����������������������������������������������������������������0000644�0001750�0001750�00000031562�12023624310�015251� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roard.1: .TH "ROARD" "1" "October 2010" "RoarAudio" "System Manager's Manual: roard" .SH NAME roard \- RoarAudio sound server .SH SYNOPSIS \fBroard\fR [OPTIONS]... .SH "DESCRIPTION" \fBroard\fR is the most common RoarAudio sound server. The RoarAudio sound server is the central component in a RoarAudio setup. It mixes up diffrent audio streams from it's clients to send them to it's outputs. Such outputs include soundcards, monitoring clients, streaming servers and more. .SH "GENERAL OPTIONS" \fBNOTE: This list is incomplete!\fR .TP \fB--help\fR Print some help text. .TP \fB--daemon\fR Go into background after startup. .TP \fB--realtime\fR Ask for higher priority. May be used multiple times. .TP \fB--memlock LEVEL\fR Sets default memory locking level to LEVEL. Valid levels are: .RS .TP \fBnone\fR No memory is locked at all. .TP \fBlow\fR Only very few (important) objects are locked in memory. .TP \fBmedium\fR Few (important) objects are locked in memory. .TP \fBhigh\fR Many objects are locked in memory. .TP \fBnearlyall\fR All known objects are locked in memory. .TP \fBnearlyallsys\fR All known objects are locked in memory but also pages provided by the system like stack and heap. .TP \fBallcur\fR All currently used pages are locked in memory. .TP \fBall\fR All pages (including future allocated pages) are locked in memory. .TP \fBdefault\fR Use defaults (the default). .RE A higher memlock level may result in memory allocations problems at runtime and even segfauls on some systems. (VM killed processes). Check your current system limits before altering this value. .TP \fB--watchdog\fR Enable watchdog. This will terminate the daemon if something bad happened and it halted. .TP \fB--watchdog-time TIME\fR Set watchdog time to TIME (in ms). .TP \fB--pidfile PIDFILE\fR Asks the server to use the given pidfile. This is recommended. .TP \fB--sysclocksync\fR Messure exact audio clock frequency based on system time. obsolete. .SH "SERVER INFO" .TP \fB\-\-location LOC\fR Sets lion-readable location of server. Examples: livingroom, room 32 .TP \fB\-\-description DESC\fR Sets lion-readable description of server. Examples: Stereo, UKW Transmitter .TP \fB\-\-contact CONTACT\fR Sets contact information for the server. .TP \fB\-\-serial SERIAL\fR Sets the serial number for this device or server. This is normally only used by embedded systems. .TP \fB\-\-uiurl UIURL\fR Sets the URL of the user interface for this device or server. This is normally only used by embedded systems. It is common to set this to a URL of type HTTP but all protocols are considered valid. This includes ssh, telnet and others. .SH "STARTUP AND SHUTDOWN" .TP \fB--start\fR Start a new server. .TP \fB--stop\fR Stop the currently running server. See also \fB--shutdown\fR. .TP \fB--restart\fR Stop the currently running server and start up a new server. .TP \fB--shutdown\fR Terminates the currently running server after last client has quit. This is the most clean way to shutdown a running server as it does not kick any clients. This option must not be confused with \fB--terminate\fR. .TP \fB--terminate\fR Auto terminates the new server after last client has quit. This option must not be confused with \fB--shutdown\fR. .TP \fB--script-postdown S\fR Run script S after server shutdown. The script is passed to a shell. Any shell feature can be used within the string. .SH "STANDBY MODE" .TP \fB--standby\fR Start in standby mode. .TP \fB--auto-standby\fR Go into standby mode if no streams are active. .SH "LOGGING" .TP \fB--verbose\fR Increment the verbosity level. Can be used multiple times. .TP \fB--log-syslog\fR Log to syslog. .SH "PLUGINS" .TP \fB--plugin-load FILENAME\fR Load the given plugin. .TP \fB--plugin-args ARGS\fR Arguments for the plugin. (must be given before the \-\-plugin-load). .TP \fB--list-plugins\fR List loaded plugins. .SH "SECURITY" .TP \fB--chroot DIR\fR Chroots to the given directory. This improves the security. This normally needs root privileg's. .SH "USER AND GROUPS" .TP \fB--setgid\fR Sets GroupID to the audio group as specified via \fB-G\fR. .TP \fB--setuid\fR Sets UserID to the audio user as specified via \fB-U\fR. .TP \fB-G GROUP\fR Sets the group for the UNIX Domain Socket, (default: audio) You need the permittions to change the GID. .TP \fB-U USER\fR Sets the user for the UNIX Domain Socket, (default: do not set) You need the permittions to change the UID (normaly only root has). .SH "AUTH OPTIONS" The following options control the access rights of connections. Some of them take an access level. The access level is one from the following list: .RS .TP \fBnone\fR This is used to disable an authentication method. .TP \fBidented\fR Used internally. Should not be used. .TP \fBconctl\fR The client is only allowed to do some basic operations only affecting it's own connection. .TP \fBguest\fR Guest access (read only). The client may list resources but not alter them. .TP \fBuser\fR Normal user. The client may create and alter most resources. .TP \fBpwruser\fR Power User. The client can create and alter all resources and do all operation but operations which would break the POSIX right system. The user is not allowed to control the server itself like terminating it or alter (system) resources with the rights of the user runnung roard. This is the access level a fully trusted user in a multi user setup should have. .TP \fBall\fR The client can do everything. This includes operations which may alter system resources (like files) with the rights of the user running roard. This accesslevel should be given to the user in case of a single user setup or root or some administrator in a multi user setup. .RE .TP \fB--guest-acclev ACCESSLEVEL\fR Sets the access level for guest connections. Set to "none" to disable guest access. .TP \fB--trust-acclev ACCESSLEVEL\fR Sets the access level for clients authenticated by trust auth. Set to "none" to disable trust auth. .TP \fB--trust-root\fR Trust root user. .TP \fB--no-trust-root\fR Do not trust root user. .TP \fB--authfile-gen FILE\fR Generate a new authfile with a fresh cookie. .TP \fB--authfile-load FILE\fR Load all keys from a given authfile. .TP \fB--authfile-type TYPE\fR Sets the type for the authfile. .TP \fB--authfile-acclev ACCLEV\fR Sets the access level for the given authfile. .TP \fB--new-authfile\fR Add another authfile. .SH "AUDIO OPTIONS" .TP \fB--rate RATE\fR, \fB-R RATE\fR Set server sample rate. .TP \fB--bits BITS\fR, \fB-B BITS\fR Set server bits. .TP \fB--chans CHANNELS\fR, \fB-C CHANNELS\fR Set server channels. .TP \fB--aiprofile PROFILE\fR Use a existing audio profile. .SH "GENERAL STREAM OPTIONS" .TP \fB--stream-flags\fR Sets default flags for a given stream directions. Examples: play=-meta, bidir=+antiecho .SH "DRIVER OPTIONS" .TP \fB--list-driver\fR Shows a list of all available drivers. .TP \fB--driver\fR, \fB-d\fR .\"Set the output driver. To get a list of all drivers use \fB--list-driver\fR. This option is obsolete. Use \fB-o\fR instead. .TP \fB--device\fR, \fB-D\fR .\"Set the device for the output driver. Possible devices depends on the driver. .\"They may be a path to a device node or a hostname. .\"Use \fB--list-driver\fR to get a hint. .\"This option will obsolete soon. This option is obsolete. Use \fB-O\fR instead. .TP \fB--odriver\fR, \fB-o\fR Set the output driver. To get a list of all drivers use \fB--list-driver\fR. .TP \fB--odevice\fR, \fB-O\fR Set the device for the output driver. Possible devices depends on the driver. They may be a path to a device node or a hostname. Use \fB--list-driver\fR to get a hint. .TP \fB-oO\fR Sets options for the new stream. See STREAM OPTIONS. .TP \fB-oN\fR Adds another output. .TP \fB-oP\fR Marks the output primary. .SH "SOURCE OPTIONS" .TP \fB--list-sources\fR List all supported sources. .TP \fB--source\fR, \fB-s\fR Adds a source of the given type. .TP \fB-S\fR Sets the device or filename for the source. Type may depend on the source type. .TP \fB-sO\fR Sets options for the current source. .TP \fB-sN\fR Adds another source. .TP \fB-sP\fR Marks the source as primary. If the source reaches EOF roard will quit automatically. .SH "HARDWARE MIXER OPTIONS" .TP \fB--list-mixers\fR List all supported hardware mixers. .TP \fB--mixer\fR, \fB-m\fR Add a hardware mixer of given type. .TP \fB-M\fR Sets the device used for the hardware mixer. .TP \fB-mO\fR Sets options for the hardware mixer. See MIXER OPTIONS. .TP \fB-mN\fR Adds another hardware mixer. .TP \fB-mP\fR Marks the mixer primary. .SH "CODEC FILTER" .TP \fB--list-cf\fR List all supported codecfilters and codecs. .SH "MIDI OPTIONS" .TP \fB--midi-no-console\fR Disable console based MIDI synth. .TP \fB--midi-console-enable\fR Enables console based MIDI synth. .TP \fB--midi-console\fR Sets device for MIDI console. Example: /dev/console .TP \fB--ssynth-enable\fR Enables simple software synth. .TP \fB--ssynth-disable\fR Disables simple software synth. .SH "LIGHT CONTROL OPTIONS" .TP \fB--light-channels\fR Sets the number of light channels. Examples: 512, 1024 .SH "RADIO DATA SYSTEM OPTIONS" .TP \fB--rds-pi\fR Sets the Programme Identification (PI). .TP \fB--rds-ps\fR Sets the Programme Service Name (PS). .TP \fB--rds-pty\fR Sets the Programme Type (PTY). .TP \fB--rds-tp\fR Sets the Traffic Programme (TP) flag .TP \fB--rds-ct\fR Enables sending of RDS Clock Time (CT). .SH "X11 OPTIONS" .TP \fB--x11-display\fR, \fB--display\fR Sets the display to use. .TP \fB--x11\fR Enable X11 support. .SH "NETWORK OPTIONS" .TP \fB--tcp\fR, \fB-t\fR Sets defaults for TCP/IP Socket. .TP \fB-4\fR, \fB-6\fR Use IPv4 or IPv6 mode. .TP \fB-64\fR Try to downgrade IPv6 sockets into IPv4 sockets. .TP \fB--unix\fR, \fB-u\fR Sets defaults for UNIX Domain Socket. .TP \fB--decnet\fR, \fB-n\fR Sets defaults for DECnet Socket. .TP \fB--port\fR, \fB-p\fR Sets the port the server should listen on. .TP \fB--bind\fR, \fB-b\fR, \fB--sock\fR Sets the hostname or path the server should listen on. .TP \fB--list-proto\fR List supported protocols. .TP \fB--proto\fR Sets the protocol used for the listening socket. .TP \fB--proto-dir\fR, \fB--proto-rate\fR, \fB--proto-bits\fR, \fB--proto-codec\fR, \fB--proto-chans\fR, \fB--proto-aiprofile\fR Set stream parameters for protocols needing stream options. Defaults to server defaults. .TP \fB--list-profiles\fR List supported profiles. \fB--proto-profile\fR Use the given profile for the listening socket. .TP \fB--new-sock\fR Adds a new listening socket. .TP \fB--no-listen\fR Do not listen for new clients (only useful for relaing, impleys \-\-terminate). .TP \fB--client-fh FH\fR Expects a client on the given FH. This may be useful with \fB--no-listen\fR. .TP \fB--close-fh FH\fR Close the given FH. This is not useful for endusers but used internaly. .TP \fB--jumbo-mtu\fR Sets the MTU for Jambo Packets. .SH "OPENSLP OPTIONS" .TP \fB--slp\fR Enable OpenSLP support. .SH "STREAM OPTIONS" .TP \fBrate\fR Sets the sample rate. .TP \fBchannels\fR Sets the number of channels. .TP \fBbits\fR Sets the number of bits per sample. .TP \fBcodec\fR Sets the codec. .TP \fBblocks\fR Sets the number of memory blocks that sould be used by the devices. Most devices only support a few values or don't support this option at all. If this option or the specifyed value is not supported by the device this is not handled as fatal error. .TP \fBblocksize\fR Sets the size of the memory blocks used by the device. Most devices only support a few values or don't support this option at all. If this option or the specifyed value is not supported by the device this is not handled as fatal error. .TP \fBmeta\fR Sets the meta flag. .TP \fBsync\fR Sets the sync flag. .TP \fBprimary\fR Marks this stream as primary. .TP \fBcleanmeta\fR Sets the cleanmeta flag. .TP \fBautoconf\fR Sets the autoconf flag. This flag is not supported by all drivers. If the flag is set and the devices does not support this there is no fatal error if the device could be opend with defaults. .TP Example: rate=44100,bits=16,channels=2,codec=pcm,sync .SH "MIXER OPTIONS" .TP \fRprimary\fR Makes this stream as primary. .TP \fBautoconf\fR Sets the autoconf flag. .TP \fBpassmixer\fR Sets the passmixer flag. .TP \fBname\fR Sets the name for the device. .TP \fBsubs\fR Sets list of subdevices. This is driver specific. .SH "ENVIRONMENT VARIABLES" .TP \fBHOME\fR The users home directory. .TP \fBROAR_SERVER\fR The address of the listening server. This may be in form of host:port for TCP/IP connections and /path/to/sock for UNIX Domain Sockets. .TP \fBROAR_DRIVER\fR The driver to select. Same as \fB-d\fR. .TP \fBROAR_DEVICE\fR The device to select. Same as \fB-D\fR. .SH "BUGS" There are lots of bugs... .SH "SEE ALSO" \fBroar-config\fR(1), \fBroarcat\fR(1), \fBroarcat2sock\fR(1), \fBroarcatad\fR(1), \fBroarctl\fR(1), \fBroarfilt\fR(1), \fBroarfish\fR(1), \fBroarmon\fR(1), \fBroarsockconnect\fR(1), \fBroartypes\fR(1), \fBroarvorbis\fR(1), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roardtmf.1�������������������������������������������������������������0000644�0001750�0001750�00000001442�11336122013�015751� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roardtmf.1: .TH "roardtmf" "1" "February 2010" "RoarAudio" "System User's Manual: roardtmf" .SH NAME roardtmf \- Generate DTMF (telephone touch tones) for RoarAudio .SH SYNOPSIS roardtmf [OPTIONS]... PHONE NUMBER .SH DESCRIPTION This tool generates DTMF (telephone touch tones) signals and send them to the RoarAudio sound server. In addition to the DTMF digits (0-9, A-D, * and #) space, period (.) and plus (+) are accepted and ignored so you can copy and past the phone number from any application easily. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarfctest.1�����������������������������������������������������������0000644�0001750�0001750�00000001536�11414142524�016321� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarfctest.1: .TH "roarfctest" "1" "July 2010" "RoarAudio" "System User's Manual: roarfctest" .SH NAME roarfctest \- Test frequency behavior of filters in discrete time domain .SH SYNOPSIS roarfctest [OPTIONS]... .SH DESCRIPTION This program tests libroardsp filters in discrete time domain. .SH "OPTIONS" .TP \fB--rate RATE\fR Set sample rate .TP \fB--sfreq SFREQ\fR Start frequency .TP \fB--efreq EFREQ\fR End frequency .TP \fB--engage ENGAGE\fR This option is not documented .TP \fB--tmax TMAX\fR This option is not documented .TP \fB--gnuplot\fR Output data using gnuplot(1) .TP \fB--rmsout RMSOUT\fR Set output file for RMS data .TP \fB--help \-h\fR Show this help .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarfilt.1�������������������������������������������������������������0000644�0001750�0001750�00000004461�12230741754�015776� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roard.1: .TH "roarfilt" "1" "October 2013" "RoarAudio" "System Manager's Manual: roarfilt" .SH NAME roarfilt \- RoarAudio sound server audio filter client .SH SYNOPSIS roarfilt [OPTIONS]... .SH "DESCRIPTION" This filters the audio data before they are send to the soundcard. .SH "GENERAL OPTIONS" \fBNOTE: This list is incomplete!\fR In addition to this list this program provides compatible options for esdfilt. You can just replace the "esd" in the name with "roar" or use symlinks. This options are for compatibly only and should not used in new programs. .TP \fB--help\fR Print some help text. .SH "AUDIO OPTIONS" .TP \fB--rate RATE\fR, \fB-R RATE\fR Set server sample rate. .TP \fB--bits BITS\fR, \fB-B BITS\fR Set server bits. .TP \fB--chans CHANNELS\fR, \fB-C CHANNELS\fR Set server channels. .SH "NETWORK OPTIONS" .TP \fB--server SERVER\fR The server to connect to. .SH "OLD ROARFILT OPTIONS" .TP \fB--half\fR Half the volume. .TP \fB--double\fR Double the volume. .TP \fB--amp n\fR, \fB--mul n\fR Amplify volume by n. .TP \fB--div n\fR Divide volume by n. .SH "FILTER OPTIONS" .TP \fB--filter name\fR This adds a new filter of name \fIname\fR. .TP \fB--ffreq freq\fR This sets a frequency for the filter. .TP \fB--fmul mult\fR This sets a multiplier for the filter. .TP \fB--fdiv div\fR This sets a divider for the filter. .TP \fB--fn N\fR This sets the filter's N value. .TP \fB--flimit limit\fR This sets the filter's limit value. .TP \fB--fmode mode\fR set filter mode parameter This sets the filter mode. Symbolic values are currently not supported. .TP \fB--fq Q\fR This sets the filter quality. .SH "ENVIRONMENT VARIABLES" Bellow only the basic environment varibales are listend. For a complete list see \fBlibroar\fR(7). .TP \fBHOME\fR The users home directory. .TP \fBROAR_SERVER\fR The address of the listening server. This may be in form of host:port for TCP/IP connections and /path/to/sock for UNIX Domain Sockets or any other supported format. See \fBroartips\fR(7) for a full list. This is the same as the \fB--server\fR option. .SH "BUGS" There are a lot of bugs... .SH "SEE ALSO" \fBroarctl\fR(1), \fBroarvorbis\fR(1), \fBroarfish\fR(1), \fBroartestclients\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarify.1��������������������������������������������������������������0000644�0001750�0001750�00000001634�11477262274�015635� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roard.1: .TH "roarify" "1" "October 2010" "RoarAudio" "User Commands" .SH NAME roarify \- roarify an application that does not have RoarAudio support .SH SYNOPSIS roarify [OPTIONS...] PROGRAM [ARGS...] .SH "DESCRIPTION" This command sets up a environment that enables all RoarAudio compatibility librarys. Audio data from applications should automatically be redirected to the RoarAudio server. .SH "OPTIONS" .TP \fB--help\fR Print usage information. .TP \fB--print-env-bash\fR Print ENVs used in bash format. .TP \fB--server\fR Set server address to connect to. .TP \fB--load\fR Force loading of a given module. .TP \fB--no-load-roar\fR Do not preload libroar. .TP \fB--no-load-oss\fR DO not load OSS emulation (libroaross). .SH "SEE ALSO" \fBroarctl\fR(1), \fBroarcat\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarinterconnect.1�����������������������������������������������������0000644�0001750�0001750�00000002372�11413146746�017534� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarinterconnect.1: .TH "roarinterconnect" "1" "January 2010" "RoarAudio" "System User's Manual: roarinterconnect" .SH NAME roarinterconnect \- interconnect two audio servers .SH SYNOPSIS roarinterconnect [OPTIONS]... .SH DESCRIPTION This program can interconnect two audio servers bi- (default) or uni-directional. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--remote SERVER\fR Set remote server .TP \fB--type TYPE\fR Set type of remote server .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB--help\fR Show this help .TP \fB--verbose \-v\fR Be verbose .SH "POSSIBLE TYPES" .TP \fBroar\fR RoarAudio Server .TP \fBesd\fR EsounD Server .TP \fBsimple\fR PulseAudio simple protocol .TP \fBoss\fR Open Sound System (OSS) device .TP \fBbidir\fR Connect bidirectional .TP \fBfilter\fR Use local server as filter for remote server .TP \fBtransmit\fR Transmit data from local server to remote server .TP \fBreceive\fR Receive data from remote server .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarlight.1������������������������������������������������������������0000644�0001750�0001750�00000001724�12227224526�016145� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarlight.1: .TH "roarlight" "1" "January 2010" "RoarAudio" "System User's Manual: roarlight" .SH NAME roarlight \- controls the Light Control subsystem of RoarAudio .SH SYNOPSIS roarlight [OPTIONS]... command [command...] .SH DESCRIPTION This command works simular to \fBroarctl\fR but controls actual data on the Light Control subsystem. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname. .TP \fB--mixer MIXERID\fR ID of the light mixer to use. .TP \fB--help\fR Show this help .SH "COMMANDS" .TP \fBhelp\fR Show this help .TP \fBsleep TIME\fR Sleeps for TIME seconds .TP \fBsset chan=val\fR Set a DMX Channel .TP \fBset chan=val\fR Same as sset command. .TP \fBevent EVENT\fR Send event EVENT to the server. .TP \fB@FILE\fR Read commands from FILE or stdin in case of @-. .SH "SEE ALSO" \fBroarctl\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ��������������������������������������������roaraudio-1.0beta11/doc/man1/roarmonhttp.1����������������������������������������������������������0000644�0001750�0001750�00000002562�11430637705�016532� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarmonhttp.1: .TH "roarmonhttp" "1" "January 2010" "RoarAudio" "System User's Manual: roarmonhttp" .SH NAME roarmonhttp \- CGI and inetd based streaming server emulation for RoarAudio .SH SYNOPSIS roarmonhttp [\-\-inetd] .SH DESCRIPTION This program emulates a streaming server using RoarAudio. It can be run from via a webserver as CGI or via inetd in inetd mode. IN CGI mode it is limited to client (listener) HTTP connections. In inetd mode it can handle source clients and gopher, too. There is no need for a specal port for gopher. The protocol is detected per client at runtime. .SH "OPTIONS" .TP \fB--inetd\fR Enables inetd mode. .TP \fB--server SERVER\fR Set Server to connect to. This may be usfull in inetd mode. .TP \fB--rate\fR, \fB--bits\fR, \fB--channels\fR, \fB--codec\fR Sets the default rate, bits, channels or codec. Those option taking a argument for the given option. Codec names may be used. .TP \fB--rel-id SID\fR Set the stream ID for the stream this stream is relative to. .TP \fB--help\fR Show a brief help. .SH "EXAMPLES" Here is an example of a roarmonhttp listening on port 8000 using inetd: 8000 stream tcp nowait roard /usr/bin/roarmonhttp roarmonhttp \-\-inetd .SH "SEE ALSO" \fBinetd\fR(8), \fBinetd.conf\fR(5), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarphone.1������������������������������������������������������������0000644�0001750�0001750�00000003651�11321777227�016155� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarphone.1: .TH "roarphone" "1" "January 2010" "RoarAudio" "System User's Manual: roarphone" .SH NAME roarphone \- Roar over Network (RoN) VoIP like application .SH SYNOPSIS roarphone [OPTIONS]... .SH DESCRIPTION This program let you talk in realtime with other people connected to a roard. .SH "SERVER OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--jumbo-mtu MTU\fR Sets the MTU for Jumbo Packets .TP \fB--io-flush INTERVAL\fR Flushs output every INTERVAL packets .SH "AUDIO OPTIONS" .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .SH "AUDIO FILTER OPTIONS" .TP \fB--afi-downmix\fR Enable input downmixing .TP \fB--afi-lowpass FREQ\fR Enable input lowpass at FREQ (in Hz) .TP \fB--afi-speex-prep\fR Enable speex preprocessor .TP \fB--afi-speex-denoise\fR Enable speex denoiser .TP \fB--afi-speex-agc\fR Enable speex AGC .TP \fB--afi-speex-vad\fR Enable speex VAD .SH "CODEC OPTIONS" .TP \fB--codec CODEC\fR Set the codec .TP \fB--transcode\fR Use local transcodeing .SH "DRIVER OPTIONS" .TP \fB--driver DRIVER\fR Set the driver .TP \fB--device DEVICE\fR Set the device .SH "GENERAL OPTIONS" .TP \fB--antiecho AEMODE\fR Set the anti echo mode .TP \fB--threshold DTXTHRES\fR Set the DTX threshold, disabled by default .TP \fB--help\fR Show this help .SH "META DATA OPTIONS" .TP \fB--m-rn REALNAME\fR Sets the real name .TP \fB--m-nick NICK\fR Sets the nick name .TP \fB--m-email EMAIL\fR Sets the email address .TP \fB--m-hp HOMEPAGE\fR Sets the homepage URL .TP \fB--m-thumbn THUMBNAIL\fR Sets a URL to a thumbnail .TP \fB--m-loc LOCATION\fR Sets the location (room number) .TP \fB--m-org ORGANIZATION\fR Sets the organization/company name .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarpluginapplication.1������������������������������������������������0000644�0001750�0001750�00000001513�11751201777�020560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarpluginapplication.1: .TH "roarpluginapplication" "1" "May 2012" "RoarAudio" "System User's Manual: roarpluginapplication" .SH NAME roarpluginapplication \- Run plugins like applications .SH SYNOPSIS plugin [OPTIONS...] .SH DESCRIPTION roarpluginapplication executes roarpluginrunner in the application mode with it's own name as plugin name. This allows a plugin to be executed with like a application with it's own binary name (within $PATH). For example with a plugin called "myapp" the package can provide a symlink from /usr/bin/myapp to roarpluginapplication. This will enable the user to start the plugin by just typing "myapp" at the command line. .SH "SEE ALSO" \fBroarpluginrunner\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarpluginrunner.1�����������������������������������������������������0000644�0001750�0001750�00000007536�12072351303�017565� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarpluginrunner.1: .TH "roarpluginrunner" "1" "FIXME(DATE)" "RoarAudio" "System User's Manual: roarpluginrunner" .SH NAME roarpluginrunner \- Run RoarAudio plugins .SH SYNOPSIS roarpluginrunner [OPTIONS]... PLUGIN .SH DESCRIPTION This tool can be used to run RoarAudio plugins or report information about the plugin. roarpluginrunner loads the plugins in a plugin container with the given parameters passed. This allows you to run all universal plugins as well as some other plugins out side a specific host. It can also be used for Testing the plugins. There are three modes of operation: Running, Running as application and Explaining. The first mode (Running) is what most host applications will do. Running as application is different in the way that all parameters left on the command line after the plugin name are parsed and passed to the plugin as plugin arguments. In this mode parameters passed after the plugin name are split into key-value-pairs. An option (beginning with two dashes) are passed as pair with the option name (the dashes) removed as key and no value. If it contains a equality sign the part after it is passed as value. Options with a single dash are split each letter into an own key-value-pair with only the key set. Non-option arguments (with no dashes) are passed as value-only pairs. After a pure double dash all parameters are passed as non-options with the double dash completely removed from the key-value-array. In the explain mode the plugin is loaded but not run. The meta information about the plugin are reported. This includes true meta data like the name, authors and copyright but also technical meta data like the host application's name the plugin is written for. When the plugin uses symbols from the host directly the plugin may not be loaded into roarpluginrunner because of the system's library loader limits. On GNU/Linux (and other POSIX like implementations) this is only true if the plugin uses global variables of the host. Plugins using functions of the host can still be loaded in this mode. .SH "OPTIONS" .TP \fB-h \-\-help\fR Prints a help message. .TP \fB-v \-\-verbose\fR Be verbose. Can be used multiple times. .TP \fB--server SERVER\fR Set default server to SERVER. .TP \fB--run\fR Run plugin. .TP \fB--run-as-application\fR Same as \-\-run except all tailing arguments are passed to the plugin. This is also used by \fBroarpluginapplication\fR(1). .TP \fB--explain\fR Explain plugin. This lists all details about the plugin without actually running it. .TP \fB--appname NAME\fR Sets the appname. .TP \fB--abiversion ABI\fR Set the ABI version. .TP \fB--args ARGS\fR Set plugin arguments. .SH "RUNNER OPTIONS" .TP \fB--option-touch\fR Do not keep the plugin running: Do a single UPDATE cycle. .TP \fB--option-no-touch\fR Disable touch option. .TP \fB--option-about\fR Show an about dialog after startup. .TP \fB--option-no-about\fR Disable about option. .TP \fB--option-help\fR Show onlion help after startup. .TP \fB--option-no-help\fR Disable help option. .TP \fB--option-preferences\fR Show preferences dialog after startup. .TP \fB--option-no-preferences\fR Disable preferences option. .SH "CPI OPTIONS" .TP \fB-t \-\-tcp\fR Use TCP listen socket. .TP \fB-u \-\-unix\fR Use UNIX Domain listen socket (default). .TP \fB-n \-\-decnet\fR use DECnet listen socket. .TP \fB--port PORT\fR TCP Port to bind to. Only in case of TCP listen sockets. .TP \fB--bind ADDR\fR Node/Hostname/Path to bind to. .TP \fB--proto PROTO\fR Use PROTO as protocol on listen or client socket. .TP \fB--new-sock\fR Parameters for new socket follow. .TP \fB--client-fh FH\fR Comunicate with a client over this handle. .SH "BUGS" \fB--client-fh\fR may not work as expected. .SH "SEE ALSO" \fBroarpluginapplication\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarradio.1������������������������������������������������������������0000644�0001750�0001750�00000001543�11322000407�016114� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarradio.1: .TH "roarradio" "1" "January 2010" "RoarAudio" "System User's Manual: roarradio" .SH NAME roarradio \- program to play web radio streams in background with RoarAudio .SH SYNOPSIS roarradio [OPTIONS]... [FILE|URL] .SH DESCRIPTION This program plays a webradio stream in background using RoarAudio. It exits as soon as everything is set up. You need to use \fBroarctl\fR to kill the stream or set the volume. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroarctl\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarshout.1������������������������������������������������������������0000644�0001750�0001750�00000002531�11523364044�016173� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarshout.1: .TH "roarshout" "1" "January 2010" "RoarAudio" "System User's Manual: roarshout" .SH NAME roarshout \- stream data to streaming server .SH SYNOPSIS roarshout [OPTIONS]... [address [port [password [mountpoint]]] .SH DESCRIPTION This tool sends data to (audio) streaming servers like icecast using libshout. The options and command lion syntax is compatible with the one used by \fBoggfwd\fR(1). .SH "ROARAUDIO OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--codec CODEC\fR Set the codec .TP \fB-h \-\-help\fR Show this help .TP \fB\-\-pw\-arg\fR Password is supplied as argument (default). .TP \fB\-\-pw\-ask\fR Ask user for password interactively. .TP \fB\-\-pw\-dstr\fR Read password from file. Filename is supplied as normal password argument. .SH "LIBSHOUT OPTIONS" .TP \fB-p \-\-public\fR Allow listing in stream directory .TP \fB-d DESC\fR Set stream description .TP \fB-g GENRE\fR Set stream genre .TP \fB-n NAME\fR Set stream name .TP \fB-u URL\fR Set stream URL/homepage .SH "SEE ALSO" \fBoggfwd\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarsocktypes.1��������������������������������������������������������0000644�0001750�0001750�00000000663�11322001102�017035� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarsocktypes.1: .TH "roarsocktypes" "1" "January 2010" "RoarAudio" "System User's Manual: roarsocktypes" .SH NAME roarsocktypes \- List socket types supported by RoarAudio .SH SYNOPSIS roarsocktypes .SH DESCRIPTION List socket types that are supported and test them at runtime. .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roartestclients.1������������������������������������������������������0000644�0001750�0001750�00000004143�11413145155�017371� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roard.1: .TH "roartestclients" "1" "July 2008" "RoarAudio" "System Manager's Manual: roard" .SH NAME roarcat2sock, roarcatad, roarsin, roarsockconnect \- RoarAudio sound server test clients .SH SYNOPSIS roarcat2sock [OPTIONS]... roarcatad [OPTIONS]... roarsin roarsockconnect HOST PORT .SH "DESCRIPTION" This clients are primary for test perpose but may be useful for someone or can be used as examples. .TP \fBroarcat2sock\fR This is the same as \fBroarcat\fR(1) but uses \fBroar_simple_new_stream\fR(3) to open the audio stream. .TP \fBroarcatad\fR This is also the same as \fBroarcat\fR(1) but uses \fBroar_stream_add_data\fR(3) to fill the server's input buffer. .TP \fBroarsin\fR This is the complete version of the sinus generator from \fBroartut\fR(7). It plays a 5 second middle C (523.2Hz) sine. .TP \fBroarsockconnect\fB This is just a test tool connecting somewhere via \fBroar_socket_connect\fR(3). First the data of stdin is copied to the socket than the data from the socket to stdout. It's a very simlple semi-bi-directional version of \fBnetcat\fR(1). .SH "GENERAL OPTIONS" \fBNOTE: This list is incomplete!\fR .TP \fB--help\fR Print some help text. .SH "AUDIO OPTIONS" .TP \fB--rate RATE\fR, \fB-R RATE\fR Set server sample rate. .TP \fB--bits BITS\fR, \fB-B BITS\fR Set server bits. .TP \fB--chans CHANNELS\fR, \fB-C CHANNELS\fR Set server channels. .SH "NETWORK OPTIONS" .TP \fB--server SERVER\fR The server to connect to .SH "ENVIRONMENT VARIABLES" Bellow only the basic environment varibales are listend. For a complete list see \fBlibroar\fR(7). .TP \fBHOME\fR The users home directory. .TP \fBROAR_SERVER\fR The address of the listening server. This may be in form of host:port for TCP/IP connections and /path/to/sock for UNIX Domain Sockets. See \fBroartips\fR(7) for a full list. This is the same as the \fB--server\fR option. .SH "BUGS" There are a lot of bugs... .SH "SEE ALSO" \fBroarctl\fR(1), \fBroarvorbis\fR(1), \fBroarfish\fR(1), \fBroarbaseclients\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roartypes.1������������������������������������������������������������0000644�0001750�0001750�00000000616�11322001102�016153� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roartypes.1: .TH "roartypes" "1" "January 2010" "RoarAudio" "System User's Manual: roartypes" .SH NAME roartypes \- List sizes of well known RoarAudio C types .SH SYNOPSIS roartypes .SH DESCRIPTION List sizes of well known RoarAudio C types. .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarvio.1��������������������������������������������������������������0000644�0001750�0001750�00000001450�11561461202�015621� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarvio.1: .TH "roarvio" "1" "FIXME(DATE)" "RoarAudio" "System User's Manual: roarvio" .SH NAME roarvio \- FIXME(PROGNAME) .SH SYNOPSIS roarvio [OPTIONS]... FILE [FILE] .SH DESCRIPTION FIXME(DESCRIPTION) .SH "OPTIONS" .TP \fB-h \-\-help\fR Print a short help. .TP \fB--verbose\fR Be verbose. Can be used multiple times. .TP \fB--read\fR Reading mode (like 'cat file'). .TP \fB--write\fR Writing mode (like 'cat > file'). .TP \fB--pass\fR Pass mode (like 'cat infile > outfile'). .TP \fB--explain\fR Explain VIO object. This will report some information on the internal data structure of the VIO object. Use \fB--verbose\fR for more information. .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarvorbis.1�����������������������������������������������������������0000644�0001750�0001750�00000001051�11322141430�016316� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarvorbis.1: .TH "roarvorbis" "1" "January 2010" "RoarAudio" "System User's Manual: roarvorbis" .SH NAME roarvorbis \- Ogg Vorbis player for RoarAudio .SH SYNOPSIS roarvorbis [OPTIONS]... FILE .SH DESCRIPTION Plays an Ogg Vorbis file showing it's metadata. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--help\fR Show this help .TP \fB--vclt-out FILE\fR Writes VCLT file .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man1/roarvumeter.1����������������������������������������������������������0000644�0001750�0001750�00000001772�11413146746�016533� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roarvumeter.1: .TH "roarvumeter" "1" "January 2010" "RoarAudio" "System User's Manual: roarvumeter" .SH NAME roarvumeter \- display current audio level of RoarAudio's waveform mixer .SH SYNOPSIS roarvumeter [OPTIONS]... .SH DESCRIPTION This tool can be used to view the current audio levels of RoarAudio's sound servers' waveform mixer. In Addition it implements a simple beat detection. .SH "OPTIONS" .TP \fB--server SERVER\fR Set server hostname .TP \fB--rate RATE\fR Set sample rate .TP \fB--bits BITS\fR Set bits per sample .TP \fB--chans CHANNELS\fR Set number of channels .TP \fB--samples SAMPLES\fR Set number of input samples per block .TP \fB--pc\fR Use percent scale .TP \fB--db\fR Use dB scale .TP \fB--beat\fR Enable beat detection .TP \fB--lowpass FREQ\fR Use lowpass to filter input (\-20dB/dec) .TP \fB--help\fR Show this help .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll ������roaraudio-1.0beta11/doc/Makefile��������������������������������������������������������������������0000644�0001750�0001750�00000002047�11322074351�014665� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf all: symlinks clean: while read fn fc tn tc; do rm man$$fc/$$fn.$$fc 2> /dev/null; done < symlinks.src; true while read fn fc tn tc; do rm html/man$$fc/$$fn.$$fc.html 2> /dev/null; done < symlinks.src; true rm -fr html/man? symlinks: while read fn fc tn tc; do ln -s ../man$$tc/$$tn.$$tc man$$fc/$$fn.$$fc 2> /dev/null; done < symlinks.src; true symlinks-html: man2html while read fn fc tn tc; do ln -s ../../html/man$$tc/$$tn.$$tc.html html/man$$fc/$$fn.$$fc.html 2> /dev/null; done < symlinks.src; true man2html: sh -c 'for dir in man*; do (cd $$dir; mkdir ../html/$$dir 2>/dev/null; for file in *.?; do man2html -r $$file > ../html/$$dir/$$file.html; done); done' prep-install-dirs: sh -c 'for dir in man*; do mkdir -p $(DESTDIR)$(PREFIX_MAN)/$$dir; done' install: prep-install-dirs sh -c 'for dir in man*; do cp $(cp_v) $$dir/*.?* $(DESTDIR)$(PREFIX_MAN)/$$dir/; done' semi-install: prep-install-dirs sh -c 'for dir in man*; do for file in $$dir/*.?*; do ln -fs `pwd`/$$file $(DESTDIR)$(PREFIX_MAN)/$$dir/; done; done' �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/env�������������������������������������������������������������������������0000644�0001750�0001750�00000000765�11323072334�013745� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Server: ROAR_DRIVER by server init ROAR_DEVICE by server init DMX by dmx driver Client: ROAR_PROXY by sockets socks_proxy by sockets http_proxy by sockets https_proxy by sockets ssh_proxy by sockets TERM by password API DISPLAY by password API CDDA_DEVICE by CDDA API Both: HOME by basic API, autodetection ROAR_SERVER by basic API, server init ROAR_OPTIONS by config API USER by sockets, autodetection Compatibility layers: AUDIODEVICE by sndio MIDIDEVICE by sndio PULSE_SERVER by pulseaudio �����������roaraudio-1.0beta11/doc/fixed-api�������������������������������������������������������������������0000644�0001750�0001750�00000002133�11161035214�015006� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roar_connect roar_connect_fh roar_disconnect roar_send_message roar_recv_message roar_req roar_buffer_new roar_buffer_free roar_buffer_delete roar_buffer_add roar_buffer_get_next roar_buffer_get_data roar_buffer_set_offset roar_buffer_shift_out roar_buffer_set_meta roar_buffer_get_meta roar_buffer_set_len roar_buffer_get_len roar_buffer_duplicate roar_buffer_ring_stats roar_get_standby roar_set_standby roar_exit roar_terminate roar_server_oinfo roar_meta_strtype roar_meta_inttype roar_simple_connect roar_simple_stream roar_simple_new_stream roar_simple_new_stream_obj roar_simple_play roar_simple_monitor roar_simple_record roar_simple_filter roar_simple_close roar_simple_get_standby roar_socket_listen roar_socket_nonblock roar_stream_connect roar_stream_new roar_stream_new_by_id roar_stream_new_empty roar_stream_set_id roar_stream_get_id roar_stream_set_fh roar_stream_get_fh roar_stream_exec roar_stream_connect_to roar_stream_add_data roar_str2codec roar_codec2str roar_vio_read roar_vio_write roar_vio_lseek roar_vio_nonblock roar_vio_sync roar_vio_close roar_vio_open_file roar_vio_open_fh �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/new-cmds��������������������������������������������������������������������0000644�0001750�0001750�00000026611�11720474414�014676� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#($Revision: 1.40 $) !SECTION: Commands +DEVCTL = 33 +:version (uint8) +:type (uint8) +DEVCTL_TYPE_GET = 0x01 +DEVCTL_TYPE_SET = 0x02 +DEVCTL_TYPE_RUN = 0x03 +DEVCTL_TYPE_SYSCONF = 0x04 #(System config) +DEVCTL_TYPE_SYSCONF_GET = DEVCTL_TYPE_SYSCONF + DEVCTL_TYPE_GET +DEVCTL_TYPE_SYSCONF_SET = DEVCTL_TYPE_SYSCONF + DEVCTL_TYPE_SET +DEVCTL_TYPE_SYSCONF_RUN = DEVCTL_TYPE_SYSCONF + DEVCTL_TYPE_RUN +DEVCTL_TYPE_CONFIG = 0x08 #(Application config) +DEVCTL_TYPE_CONFIG_GET = DEVCTL_TYPE_CONFIG + DEVCTL_TYPE_GET +DEVCTL_TYPE_CONFIG_SET = DEVCTL_TYPE_CONFIG + DEVCTL_TYPE_SET +DEVCTL_TYPE_CONFIG_RUN = DEVCTL_TYPE_CONFIG + DEVCTL_TYPE_RUN +DEVCTL_TYPE_OPMODE = 0x0c #(Mode of operation) +DEVCTL_TYPE_OPMODE_GET = DEVCTL_TYPE_OPMODE + DEVCTL_TYPE_GET +DEVCTL_TYPE_OPMODE_SET = DEVCTL_TYPE_OPMODE + DEVCTL_TYPE_SET +DEVCTL_TYPE_OPMODE_RUN = DEVCTL_TYPE_OPMODE + DEVCTL_TYPE_RUN +DEVCTL_TYPE_UI = 0x10 #(User Interface) +DEVCTL_TYPE_UI_GET = DEVCTL_TYPE_UI + DEVCTL_TYPE_GET +DEVCTL_TYPE_UI_SET = DEVCTL_TYPE_UI + DEVCTL_TYPE_SET +DEVCTL_TYPE_UI_RUN = DEVCTL_TYPE_UI + DEVCTL_TYPE_RUN +DEVCTL_TYPE_POWER = 0x14 #(Power management) +DEVCTL_TYPE_POWER_GET = DEVCTL_TYPE_POWER + DEVCTL_TYPE_GET +DEVCTL_TYPE_POWER_SET = DEVCTL_TYPE_POWER + DEVCTL_TYPE_SET +DEVCTL_TYPE_POWER_RUN = DEVCTL_TYPE_POWER + DEVCTL_TYPE_RUN +DEVCTL_TYPE_DATA = 0x18 #(Runtime data) +DEVCTL_TYPE_DATA_GET = DEVCTL_TYPE_DATA + DEVCTL_TYPE_GET +DEVCTL_TYPE_DATA_SET = DEVCTL_TYPE_DATA + DEVCTL_TYPE_SET +DEVCTL_TYPE_DATA_RUN = DEVCTL_TYPE_DATA + DEVCTL_TYPE_RUN +DEVCTL_TYPE_USER0 = 0xf0 #(User defined commands Assigned by DeviceVendor) +DEVCTL_TYPE_USER0_GET = DEVCTL_TYPE_USER0 + DEVCTL_TYPE_GET +DEVCTL_TYPE_USER0_SET = DEVCTL_TYPE_USER0 + DEVCTL_TYPE_SET +DEVCTL_TYPE_USER0_RUN = DEVCTL_TYPE_USER0 + DEVCTL_TYPE_RUN +DEVCTL_TYPE_USER1 = 0xf4 #(User defined commands Assigned by DeviceVendor) +DEVCTL_TYPE_USER1_GET = DEVCTL_TYPE_USER1 + DEVCTL_TYPE_GET +DEVCTL_TYPE_USER1_SET = DEVCTL_TYPE_USER1 + DEVCTL_TYPE_SET +DEVCTL_TYPE_USER1_RUN = DEVCTL_TYPE_USER1 + DEVCTL_TYPE_RUN +DEVCTL_TYPE_USER2 = 0xf8 #(User defined commands Assigned by DeviceVendor) +DEVCTL_TYPE_USER2_GET = DEVCTL_TYPE_USER2 + DEVCTL_TYPE_GET +DEVCTL_TYPE_USER2_SET = DEVCTL_TYPE_USER2 + DEVCTL_TYPE_SET +DEVCTL_TYPE_USER2_RUN = DEVCTL_TYPE_USER2 + DEVCTL_TYPE_RUN +DEVCTL_TYPE_USER3 = 0xfc #(User defined commands Assigned by DeviceVendor) +DEVCTL_TYPE_USER3_GET = DEVCTL_TYPE_USER3 + DEVCTL_TYPE_GET +DEVCTL_TYPE_USER3_SET = DEVCTL_TYPE_USER3 + DEVCTL_TYPE_SET +DEVCTL_TYPE_USER3_RUN = DEVCTL_TYPE_USER3 + DEVCTL_TYPE_RUN +:vendor (uint8) +VENDOR_ROARAUDIO = 0 +VENDOR_BASICDEV = 1 +:subtype (uint8) +:flags (uint8) +:ot (uint8) +:(id) (uint16) #(if not UNIID or SID) +:data... (vardata) +CAPS = 34 +:version (uint8) +:type (uint8) +:flags (uint16) +CF_REQUEST = 0x0001 +CT_CAPS = 0 +::data... (dataarray) +:::captype (TODO) +:::... (TODO) +CT_STANDARDS = 1 +::data... (dataarray) +:::stdvendor (uint8) +STDV_ROARAUDIO = 0 +STDV_PROTO = 1 +STDV_RFC = 2 +:::standard (uint16) +:::stdversion (uint8) +WAIT = 35 +:version (TODO) +:flags (TODO) :(TODO) +NOTIFY = 36 #(+=structof(WAIT)) #(Notify Types) +NT_PROTO = NEEDS_CONST +NT_SOCKET = NEEDS_CONST +NT_SIGNAL = NEEDS_CONST +NT_MSGQUEUE = NEEDS_CONST +NT_FLOCK = NEEDS_CONST +NT_FUTEX = NEEDS_CONST +SEEK = 37 +:version (TODO) +:flags (TODO) +:destination position (TODO) +:destination position whence (TODO) +:destination position quality (TODO) +:hint pos (TODO) +:hint whence (TODO) +:hint quality (TODO) +:seek at (TODO) +:seek to (TODO) +:seek whence (TODO) +SF_CONT_WHILE_SEEK = 0x01 +SF_CONT_ON_ERROR = 0x02 +SF_HINT = 0x04 +SF_SEEK = 0x08 +HQ_BAD = 0 +HQ_BAD_NB = 1 #(bad, not before this position) +HQ_NEAR = 2 +HQ_NEAR_NB = 3 #(Near, not before this position) +HQ_GOOD = 4 +HQ_GOOD_NB = 5 #(good, not before this position) +HQ_EXACT = HQ_EXACT_NB #(ID 6 is skiped here) +HQ_EXACT_NB = 7 +WHENCE_BEGIN = 0 +WHENCE_CUR = 1 +WHENCE_END = 2 +CLIENTCTL = 38 +:version (uint8) +:subcmd (uint8) +:flags (uint16) +:data (vardata) +CC_HASHTABLE = PARA_HASHTABLE +CC_WININFO = PARA_WININFO +CC_PROPTABLE = PARA_PROPTABLE +LOOKUP = 39 +:version (uint8) +:flags (uint8) +:extflags (uint8) +:ot (uint8) +:ht (uint32) #(hash type) +:hash... (vardata) +CONCTL = 40 +:version (uint8) +:flags (uint8) +:session (uint8) +:type (uint8) +:stdvendor (uint8) +:standard (uint16) +:stdversion (uint8) +CCT_NONE = 0 #(This is the same like a NOOP-Command) +CCT_CRYPTMSG = 1 #(This request contains zero or more crypto packages according to given standard) +CCT_OPENSESS = 2 #(This opens a crypto session) +:hash (uint32) +:comp (uint16) +COMPT_NONE = 0 +COMPT_ZLIB = 1 +COMPT_GZIP = 2 +COMPT_BZIP2 = 3 +:complevel (uint8) +:compflags (uint8) +:data... (dataarray) +CCT_CLOSESESS = 3 #(This closes a opend cryto session) +:hashlen (uint16) +:hash (dataarray(:hashlen)) +:data... (dataarray) +CCT_SESSDATA = 4 #(This is some kind of data used in the session) +:data... (dataarray) +LIST = NEEDS_CONST +GET_OBJ = NEEDS_CONST +OBJCTL = NEEDS_CONST *SERVER_INFO +IT_SERVER = 1 +:version (uint8) +:reserved (uint8) +:indexlen (uint16) +::reserved (uint8) +::type (uint8) +ITST_VERSION = 0 #(Format: Product/Version <VendorID/VendorName> (comments)) #(Example: roard/0.4 <0/RoarAudio> (Debian build)) +ITST_LOCATION = 1 #(freeform) +ITST_DESCRIPTION = 2 #(freeform) +ITST_CONTACT = 3 #(Format: first ["']nick["'] last (comment) <email>/OpenPGPkey/Phone/Room) +ITST_UN_SYSNAME = 4 #(uname -s) +ITST_UN_NODENAME = 5 #(uname -n) +ITST_UN_RELEASE = 6 #(uname -r) +ITST_UN_MACHINE = 7 #(uname -m) +ITST_SERIAL = 8 +ITST_ADDRESS = 9 +ITST_UIURL = 10 +ITST_HOSTID = 11 #(UNIX hostid in hex (%.8x), with leading zeros (8 or 16 hex-digits), This is returned by gethostid()) +ITST_LICENSE = 12 #(Format: LicenseName-Version (options)) #(Example: GPL-3.0, LGPL-2.1, LGPL-3.0 (or later)) +ITST_BUILD = 13 #(Manufacturing/compiling date and worker, all times in UTC) #(Format: YYYY-MM-DD HH:MM:SS (worker)) #(Example: 2011-12-01 (build cluster 3)) +::len (uint16) +:strings (dataarray) +IT_COUNTERS = 2 +:version (uint8) +:reserved (uint24) +:data... (dataarray) +::type (uint8) +::flags (uint8) +::reserved (uint16) +::counter (uint32) +CF_CURRENT = 0x01 #(Current value if set, sum if unset) +CF_OTTYPE = 0x02 #(Type is a OT_* type if set, or other if unset) +IT_LISTEN = 3 +:version (uint8) +:reserved (uint24) +:listensocks... (dataarray) +::id (uint16) +::flags (uint8) +::socktype (uint8) +::proto (uint16) +::byteorder (uint16) +::dir (uint32) +::auinfo (packed-audioinfo) #(4*4*8 = 128bit) +::addrlen (uint16) +::addr (padded-string(:addrlen)) +LF_HAVEDIR = 0x01 +LF_HAVEAI = 0x02 *[GS]ET_STREAM_PARA *PARA_INFO +STREAMSTATE_ERROR = 5 #(Stream is in some error condition, parent client should close or kick it) +STREAMSTATE_NEEDSEEK = 6 #(like Error but stream can become usable again if you do a seek) *PARA_FLAGS +FLAG_SINGLESINK = 0x00040000 +TOGGLE_FLAG = 2 +NOOP_FLAG = 3 +PROTECT_FLAG = 0x8000 #(flag to mark flags in changed by this protected) +PARA_HASHTABLE = 6 #(GTN, UUID, ...) +:htsettertype (uint32) +:htsettersize (uint16) +:htsetterdata (vardata) +:hashtable... (dataarray) +::httype (uint32) +::htsize (uint16) +::htfunction (uint16) +::htdata (vardata) +HT_NONE = 0 +HT_MD5 = 1 +HT_SHA1 = 2 +HT_RIPEMD160 = 3 +HT_MD2 = 5 +HT_TIGER = 6 +HT_HAVAL = 7 +HT_SHA256 = 8 +HT_SHA384 = 9 +HT_SHA512 = 10 +HT_SHA224 = 11 +HT_MD4 = 301 +HT_CRC32 = 302 #(ISO 3309, ITU-T V.42, IEEE 802.3) +HT_RFC1510 = 303 #(HT_CRC32 as modified by RFC 1510) +HT_RFC2440 = 304 #(poly=0x1864CFBL, init=0xB704CEL, OpenPGP) +HT_WHIRLPOOL = 305 +HT_UUID = 70000 #(GTN is the Global Track Number as used by for example the RoarAudio PlayList Daemon (rpld)) #(It is a creator-runtime-unique number to identify the object.) +HT_GTN8 = 70001 +HT_GTN16 = 70002 +HT_GTN32 = 70004 #("Short Global Track Number") +HT_GTN64 = 70008 #("Long Global Track Number") +HT_CLIENTID = 71000 + OT_CLIENT = 71001 +HT_STREAMID = 71000 + OT_STREAM = 71002 +HT_SOURCEID = 71000 + OT_SOURCE = 71003 +HT_SAMPLEID = 71000 + OT_SAMPLE = 71004 +HT_MIXERID = 71000 + OT_MIXER = 71005 +HT_BRIDGEID = 71000 + OT_BRIDGE = 71006 +HT_LISTENID = 71000 + OT_LISTEN = 71007 +HT_ACTIONID = 71000 + OT_ACTION = 71008 +HT_MSGQUEUEID = 71000 + OT_MSGQUEUE = 71009 +HT_MSGBUSID = 71000 + OT_MSGBUS = 71010 #(Next are article and book numers. They may be ued with HF_DISK and HF_WORK) +HT_GTIN8 = 72001 +HT_GTIN13 = 72002 +HT_ISBN10 = 72003 +HT_ISBN13 = HT_GTIN13 #(ISBN-13 and GTIN/EAN-13 are the same) +HT_ADLER32 = 73001 #(RFC1950) +HF_NONE = 0 #(This entry does not have anything to do with the object...) +HF_OBJECT = 1 #(This is an entry for exacltly this object) +HF_PARENT = 2 #(This is the parent object) +HF_LOGIC = 3 #(This is a logic group of this object) +HF_PERMANENT = 4 #(This can be used to acces exactly this object with a premanent address) +HF_DEVICE = 5 #(The device this is on or the device itself if this is a device) +HF_DISK = 6 #(The disk this is on, if this is a disk the same as HF_DEVICE) +HF_SONG = 7 #(This identifys the Song. This may for example be used with Tantalos) +HF_APP = 8 #(The application, device or other source generating this object) +HF_FILE = 9 #(The source file for this object) +HF_ARTIST = 10 #(This identifies any kind of artist/composer/interpret, to be used with Tantalos) +HF_WORK = 11 #(This identifies any kind of work/album/compilation, to be used with Tantalos) +PARA_WININFO = 7 +:wsystype (uint8) +:socktype (uint8) +:display (uint8) +:screen (uint8) +:addrlen (uint16) +:addr (padded-string(:addrlen)) +:wins (dataarray) +::window (uint32) +PARA_PROPTABLE = 8 :(TODO) +PARA_LTM = 9 +PARA_USAGE = 10 #(Used by RAUM) +PARA_RADIO = 11 #(Used by RDTCS) *KICK,... +OT_OUTPUT = 5 +OT_MIXER = 6 +OT_BRIDGE = 7 +OT_LISTEN = 8 +OT_ACTION = 9 +OT_MSGQUEUE = 10 #(Message queue, message is gone as soon as one client took it) +OT_MSGBUS = 11 #(Message bus, message is gone as soon as all listening clients got it) *ATTACH *ATTACH_SOURCE :(TODO) *ATTACH_OUTPUT :(TODO) +ATTACH_MIXER = 4 :(TODO) +ATTACH_BRIDGE = 5 :(TODO) *SET_VOL +SET_VOL_MS = 3 +SET_VOL_UNMAPPED = 4 #(like roarctls mono/stereo...) *AUTHCTL = GET_ACL *ACLCTL = SET_ACL -GET_ACL #(reasignmened) -SET_ACL #(reasignmened) +SHIFT_DATA = 40 #(get data from a stream) +RAUM_PICTURE = 202 #(Used by RAUM to store pictures) +RAUM_SYNC = 203 #(Used by RAUM for raw seeking) !SECTIONEND !SECTION: Codecs +AUTLAW_LE = 0x31 +AUTLAW_BE = 0x32 +AUTLAW = AUTLAW_BE +MUUTLAW_LE = 0x35 +MUUTLAW_BE = 0x36 +MUUTLAW = MUUTLAW_BE +BRR = 0x3c +OGG_OPUS = 0x18 +ROAR_OPUS = 0x19 !SECTIONEND !SECTION: Network +SOCKET_TYPE_LAT_SERVICE = 12 +SOCKET_TYPE_LAT_REVERSE_PORT = 13 !SECTIONEND �����������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/proto�����������������������������������������������������������������������0000644�0001750�0001750�00000003204�11201043607�014303� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������RoarAudio Protocol Version 0: Message = Header | Data Request = Message Respone = Message Command = Request | Resonse Version 0 Header: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version | Command | Stream ID | 0-3 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream Possition | 4-7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Message Data Length |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX| 8-9 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---- DRAFT ---- Version 1 Header: Byte Oriented Protocol: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version | Command | Flags | Stream ID | 0- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream ID | Stream POS | Stream POS | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream POS | Msg Data Len | Msg Data Len |XXXXXXXXXXXXXXX| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Flags: 0 Stream ID field exists 1 Stream POS field exists 2 Message Length field exists 3 Stream ID field is one byte long 4 Stream POS field is one byte long and does not represent abselut but increment values 5 Message Data Length field is one byte long 6 7 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/standards�������������������������������������������������������������������0000644�0001750�0001750�00000003457�11455572224�015152� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Vendor Std. Ver. Short Name Name -------------------------------------------------------------------------------- RoarAudio 0 0 ra-msg-v0 RoarAudio Message format v. 0 RoarAudio 1 0 ra-msg-v1 RoarAudio Message format v. 1 RoarAudio 2 0 ra-msg-v2 RoarAudio Message format v. 2 RoarAudio 3 0 ra-msg-v3 RoarAudio Message format v. 3 RoarAudio 4 0 ra-cmdset RoarAudio basic Commandset RoarAudio 5 0 ra-cmdadv RoarAudio Advanced Commands RoarAudio 6 0 ra-cmddev RoarAudio Device Control Commands RoarAudio 7 0 ra-cmdasync RoarAudio Async, Notify and Wait Commands RoarAudio 8 0 ra-cmdsadv RoarAudio Advanced Stream control Commands RoarAudio 9 0 ra-cmdcadv RoarAudio Advanced Client control Commands RoarAudio 10 0 ra-cmdcrypt RoarAudio Crypto Commandset RoarAudio 11 0 ra-comnums RoarAudio Common Numbers RoarAudio 12 0 ra-codecs RoarAudio Codec IDs RoarAudio 13 0 ra-cert-base RoarAudio Base Certificate Spec RoarAudio 14 0 ra-cert-a RoarAudio Base Certificate A RoarAudio 15 0 ra-cert-b RoarAudio Base Certificate B RoarAudio 16 0 ra-cert-c RoarAudio Base Certificate C RoarAudio 17 0 ra-cert-d RoarAudio Base Certificate D RoarAudio 18 0 ra-cert-e RoarAudio Base Certificate E RoarAudio 19 0 ra-cert-f RoarAudio Base Certificate F RoarAudio 20 0 ra-raum-v0 RAUM v0 Spec RoarAudio 21 0 ra-raum-v1 RAUM v1 Spec RoarAudio 22 0 ra-raum-v2 RAUM v2 Spec RoarAudio 23 0 ra-trans-unix RoarAudio Transport UNIX RoarAudio 24 0 ra-trans-decnet RoarAudio Transport DECnet RoarAudio 25 0 ra-trans-tcp RoarAudio Transport TCP RoarAudio 26 0 ra-trans-spx RoarAudio Transport SPX RoarAudio 27 0 ra-trans-tcp6 RoarAudio Transport TCP v6 RoarAudio 28 0 ra-trans-rs232 RoarAudio Transport RS-232 RoarAudio 29 0 ra-trans-i2c RoarAudio Transport I^2C RoarAudio 30 0 ra-trans-can RoarAudio Transport CAN RoarAudio 31 0 ra-float RoarAudio standard float �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/standards-proto�������������������������������������������������������������0000644�0001750�0001750�00000000555�11502016516�016275� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Vendor Std. Ver. Short Name Name -------------------------------------------------------------------------------- Proto 0 0 proto-tantalos Tantalos Proto 1 0 proto-tantslp Announcing Tantalos using OpenSLP Proto 2 0 proto-tanturl URL Schema for Tantalos Proto 3 0 proto-tantidx Tantalos Document Index Proto 4 0 proto-metauuid Metadata based UUID calculation ���������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/symlinks.src����������������������������������������������������������������0000644�0001750�0001750�00000002365�11663567357�015637� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roarcat 1 roarbaseclients 1 roarmon 1 roarbaseclients 1 roarcat2sock 1 roartestclients 1 roarcatad 1 roartestclients 1 roarsin 1 roartestclients 1 roarsockconnect 1 roartestclients 1 roar_set_standby 3 roar_get_standby 3 roar_set_vol 3 roar_get_vol 3 roar_simple_filter 3 roar_simple_play 3 roar_simple_monitor 3 roar_simple_play 3 roar_simple_new_stream_obj 3 roar_simple_new_stream 3 roar_simple_record 3 roar_simple_play 3 roar_codec2str 3 roar_str2codec 3 roar_terminate 3 roar_exit 3 roar_vs_write 3 roar_vs_read 3 roar_vs_stream_obj 3 roar_vs_connection_obj 3 roar_vs_vio_obj 3 roar_vs_connection_obj 3 roar_vs_volume_mono 3 roar_vs_volume_get 3 roar_vs_volume_stereo 3 roar_vs_volume_get 3 roar_vs_mute 3 roar_vs_pause 3 roar_vs_run 3 roar_vs_iterate 3 roar_vs_get_avail_read 3 roar_vs_buffer 3 roar_vs_get_avail_write 3 roar_vs_buffer 3 roar_vs_reset_buffer 3 roar_vs_buffer 3 roar_vs_new_from_con 3 roar_vs_new 3 roar_vs_new_playback 3 roar_vs_new_simple 3 roar_vs_file_simple 3 roar_vs_stream 3 roar_vs_new_from_file 3 roar_vs_stream 3 roar_vs_latency 3 roar_vs_position 3 roar_vs_latency2 3 roar_vs_position 3 roar_connectionref 3 roar_disconnect 3 roar_connectionunref 3 roar_disconnect 3 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/magics/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553167�014505� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/magics/codecs.tsv�����������������������������������������������������������0000644�0001750�0001750�00000003606�11263406302�016467� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0x01 pcm_s_le waveform (none) 0x02 pcm_s_be waveform (none) 0x03 pcm_s_pdp waveform (none) 0x05 pcm_u_le waveform (none) 0x06 pcm_u_be waveform (none) 0x07 pcm_u_pdp waveform (none) 0x08 midi_file midi, waveform (none) 0x10 ogg_vorbis waveform Ogg Vorbis 0x11 flac waveform native FLAC 0x12 ogg_speex waveform (none) 0x14 ogg_flac waveform (none) 0x15 ogg_general (?) Ogg data of unknown type (should not be used) 0x16 ogg_celt waveform (none) 0x17 ogg complex (none) 0x1a roar_celt waveform (none) 0x1b roar_speex waveform (none) 0x1c raum complex (none) 0x1d raum_vorbis waveform (none) 0x1e raum_flac waveform (none) 0x20 riff_wave waveform (none) 0x30 alaw waveform (none) 0x34 mulaw waveform (none) 0x40 meta_vclt (?) Vorbis Comment Like Text 0x44 meta_ralt (?) RoarAudio Like Text 0x4c meta_ralb (?) RoarAudio Like Binary (should not be used) 0x4d meta_ralb_le (?) RoarAudio Like Binary in little endian 0x4e meta_ralb_be (?) RoarAudio Like Binary in big endian 0x4f meta_ralb_pdp (?) RoarAudio Like Binary in PDP (middle) endian 0x50 cont_null (?) (none) 0x51 cont_gzip (?) (none) 0x52 cont_bzip2 (?) (none) 0x53 cont_opgpbin (?) (none) 0x54 cont_opgpasc (?) (none) 0x55 cont_tar (?) (none) 0x60 midi midi (none) 0x70 dmx512 light (none) 0x71 roardmx light (none) 0x80 rds rdtcs (none) 0x90 user0 (ALL) (none) 0x91 user1 (ALL) (none) 0x92 user2 (ALL) (none) 0x93 user3 (ALL) (none) 0x94 user4 (ALL) (none) 0x95 user5 (ALL) (none) 0x96 user6 (ALL) (none) 0x97 user7 (ALL) (none) 0x98 user8 (ALL) (none) 0x99 user9 (ALL) (none) 0x9a user10 (ALL) (none) 0x9b user11 (ALL) (none) 0x9c user12 (ALL) (none) 0x9d user13 (ALL) (none) 0x9e user14 (ALL) (none) 0x9f user15 (ALL) (none) ��������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/magics/dir.tsv��������������������������������������������������������������0000644�0001750�0001750�00000001255�11263404153�016005� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1 play waveform in (none) 2 record waveform out (none) 3 monitor waveform out (none) 4 filter waveform bidir (none) 5 output waveform out (none) 6 mixing (?) (?) (none) 8 meta (?) (?) (none) 9 bidir waveform bidir (none) 10 thru (dep) out (none) 11 bridge (multi) (?) (none) 12 midi_in midi in (none) 13 midi_out midi out (none) 14 light_in light in (none) 15 light_out light out (none) 16 raw_in raw in (none) 17 raw_out raw out (none) 18 complex_in complex in (none) 19 complex_out complex out (none) 20 rdtcs_in rdtcs in (none) 21 rdtcs_out rdtcs out (none) 22 dirids (max) (none) (none) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553170�014072� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_connect.3���������������������������������������������������������0000644�0001750�0001750�00000002563�11570211566�016634� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_connect" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_connect, roar_connect2 \- connects to RoarAudio's sound server .SH SYNOPSIS #include <roaraudio.h> int roar_connect(struct roar_connection * con, char * server); int roar_connect2 (struct roar_connection * con, char * server, int flags, uint_least32_t timeout); .SH "DESCRIPTION" Connects to RoarAudio's sound server. This calls just connects to the sound server without any authentication or identify. Do not use this from end user applications. Use \fBroar_simple_connect\fR(3) or \fBroar_simple_connect2\fR(3). .SH "PARAMETERS" .TP \fBcon\fR The connection object to be filled with the data needed to talk to the server used by nearly all other calls. .TP \fBserver\fR The server to connect to. .TP \fBflags\fR Flags used to connect to the server. Currently only ROAR_ENUM_FLAG_NONE and ROAR_ENUM_FLAG_NONBLOCK are supported. ROAR_ENUM_FLAG_NONBLOCK disables some of the server location features. .TP \fBtimeout\fR Timeout for the connection. A value of zero means no timeout. Currently timeouts are not supported. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" See libroar/simple.c, \fBroar_simple_connect\fR(3). .SH "SEE ALSO" \fBroar_simple_connect\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_disconnect.3������������������������������������������������������0000644�0001750�0001750�00000002072�11663567360�017340� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_connectionref" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_connectionref, roar_connectionunref \- change reference counter for RoarAudio connections .SH SYNOPSIS #include <roaraudio.h> int roar_connectionref(struct roar_connection * con); int roar_connectionunref(struct roar_connection * con); #define roar_disconnect(x) roar_connectionunref((x)) .SH "DESCRIPTION" Those functions change the reference counter for connection objects previously opend via \fBroar_connect\fR(3), \fBroar_connect_fh\fR(3) or \fBroar_simple_connect\fR(3). If the reference counter hints zero the connection is closed and the object is destroyed. .PP The \fBroar_disconnect\fR(3) macro is provided to be source compatible (recompile needed) with RoarAudio 0.4 or older. .SH "PARAMETERS" .TP \fBcon\fR The connection to be altered. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_simple_connect\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_error.3�����������������������������������������������������������0000644�0001750�0001750�00000002211�12003760404�016312� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_error" "3" "July 2012" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_error \- RoarAudio error code .SH SYNOPSIS #include <roaraudio.h> .SH "DESCRIPTION" This is a variable or macro expanded to an read-write able variable storing the current RoarAudio error value. The data type of this variable or macro is int. When supported by the host environment this is thread local. All function calls within libroar are allowed to set this value (exceptions are noted here or in documentation of functions). Some will also clear it in case of no error. Application and other librarys may also alter the value. This means that usage will require the caller to save the value before calling other functions if the value is still needed after the call. .SH "EXCEPTIONS" The following functions will not alter this value: \fBROAR_DBG\fR(3), \fBROAR_WARN\fR(3), \fBROAR_ERR\fR(3), \fBROAR_INFO\fR(3) as well as \fBroar_err_store\fR(3) and \fBroar_err_restore\fR(3) and \fBroar_err_convert\fR(3). .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBerrno\fR(3), \fBroar_error2str\fR(3), \fBroar_vs_strerr\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_error2str.3�������������������������������������������������������0000644�0001750�0001750�00000001627�12003756173�017147� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_error2str" "3" "July 2012" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_error2str \- Convert an error code into a lion readable string .SH SYNOPSIS #include <roaraudio.h> const char * roar_error2str(const int error); .SH "DESCRIPTION" This function returns a lion readable error message for the given error code. If the error code is unknown or invalid it returns NULL. This is unlike \fBroar_vs_strerr\fR(3) which returns an string representing an unknown error. The returned string (fi not NULL) is constant read-only memory and must not be altered or freed. This function is thread safe. .SH "PARAMETERS" .TP \fBerror\fR The error code which should be translated into a string. .SH "RETURN VALUE" Returns a constant string descripting the error \fBerror\fR or NULL on error. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_vs_strerr\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_errorstring.3�����������������������������������������������������0000644�0001750�0001750�00000001140�12003756173�017551� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_errorstring" "3" "July 2012" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_errorstring \- Lion readable error string for current RoarAudio error value .SH SYNOPSIS #include <roaraudio.h> .SH "DESCRIPTION" This variable is a read-only string of the current RoarAudio error code. It may be defined as variable or macro. It is equivalent to "roar_error2str(roar_error)". .SH "VALUE" Constants a string descripting the error \fBerror\fR or NULL on error. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_error2str\fR(3), \fBroar_error\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_exit.3������������������������������������������������������������0000644�0001750�0001750�00000002412�11570211566�016145� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_exit" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_exit \- let RoarAudio's sound server quit roar_terminate \- let RoarAudio's sound server quit as soon as all clients quit .SH SYNOPSIS #include <roaraudio.h> int roar_exit(struct roar_connection * con); int roar_terminate(struct roar_connection * con, int terminate); .SH "DESCRIPTION" Ask the sound server to quit. roar_exit() let the server quit without waiting for any clients. All streams and client connections will be closed cleanly. roar_terminate() will let the server quit as soon as all clients disconnects and all input streams ended. The listening socket will be closed. This is useful in case of restarting roard. .SH "PARAMETERS" .TP \fBcon\fR An open controll connection to the server. .TP \fBterminate\fR Wait for all clients to disconnect and all streams to EOF in case of 1. In case of 0 roar_terminate() is equal to roar_exit(). .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "NOTES" Even when the call was successfull you have to use \fBroar_disconnect\fR(3) to disconnect from the server. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_disconnect\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_get_standby.3�����������������������������������������������������0000644�0001750�0001750�00000002060�11570211566�017476� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_get_standby" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_get_standby, roar_set_standby \- Get and set RoarAudio's sound servers standby state .SH SYNOPSIS #include <roaraudio.h> int roar_get_standby(struct roar_connection * con); int roar_set_standby(struct roar_connection * con, int state); .SH "DESCRIPTION" Get or set the standby state of the server. If the server is in standby no audio is played. The audio device may be released depending on configuration. .SH "PARAMETERS" .TP \fBcon\fR The connection to the server. .TP \fBstate\fR The new state. This may be \fBROAR_STANDBY_ACTIVE\fR for standby to be set active or \fBROAR_STANDBY_INACTIVE\fR for normal operating mode. .SH "RETURN VALUE" \fBroar_get_standby\fR returns \fBROAR_STANDBY_ACTIVE\fR, \fBROAR_STANDBY_INACTIVE\fR or \-1 on error. \fBroar_set_standby\fR returns on success 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_simple_get_standby\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_get_vol.3���������������������������������������������������������0000644�0001750�0001750�00000002460�11570211566�016636� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_get_vol" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_get_vol, roar_set_vol, roar_set_vol2 \- Set mixer levels or RoarAudio streams .SH SYNOPSIS #include <roaraudio.h> int roar_set_vol(struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int channels); int roar_set_vol2 (struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int channels, int mode); int roar_get_vol(struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int * channels); .SH "DESCRIPTION" This call gets or sets the mixing levels for a stream. roar_set_vol() is marked obsolete and will be removed soon, use roar_set_vol2(). .SH "PARAMETERS" .TP \fBcon\fR The connection to the roar audio server. .TP \fBid\fR The ID of the stream to change. .TP \fBmixer\fR The mixer state for the stream. .TP \fBchannels\fR The number of channels to set mixer data for or the number of channels mixer data is returned. .TP \fBmode\fR The mode of operating. Currently the following modes are supported: ROAR_SET_VOL_ALL, ROAR_SET_VOL_MS, ROAR_SET_VOL_UNMAPPED. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_server_oinfo.3����������������������������������������������������0000644�0001750�0001750�00000002057�11570211566�017701� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_server_oinfo2" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_server_oinfo, roar_server_oinfo2 \- Gets information on the output stream of RoarAudio's sound server .SH SYNOPSIS #include <roaraudio.h> int roar_server_oinfo(struct roar_connection * con, struct roar_stream * s); int roar_server_oinfo2(struct roar_connection * con, struct roar_stream * s, int dir); .SH "DESCRIPTION" Gets information about the default mixer stream for the given stream direction. This can be used to get optimal parameters for all operations so the server don't need to resample. roar_server_oinfo() is marked as obsolete and will be removed soon. .SH "PARAMETERS" .TP \fBcon\fR The connection to the server. .TP \fBs\fR A stream object to be filled with information on the output stream. .TP \fBdir\fR The stream direction to query mixer data for. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_simple_close.3����������������������������������������������������0000644�0001750�0001750�00000002077�12003754115�017653� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_simple_close" "3" "July 2012" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_simple_close \- close a simple RoarAudio connection .SH SYNOPSIS #include <roaraudio.h> int roar_simple_close(int fh); .SH "DESCRIPTION" Closes a filehandle opened via \fBroar_simple_play\fR(3), \fBroar_simple_monitor\fR(3), \fBroar_simple_record\fR(3), \fBroar_simple_filter\fR(3) or \fBroar_simple_new_stream\fR(3). This function was removed in version 1.0beta0-pr0. Use \fBroar_vs_close\fR(3). .SH "PARAMETERS" .TP \fBfh\fR The filehandle to be closed. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" Examples of these calls are the tools \fBroarcat\fR(1), \fBroarmon\fR(1), \fBroarrec\fR(1) and \fBroarfilt\fR(1). Just look at there code. They aren't that complex. .SH "SEE ALSO" \fBroar_vs_close\fR(3), \fBroar_simple_play\fR(3), \fBroar_simple_monitor\fR(3), \fBroar_simple_record\fR(3), \fBroar_simple_filter\fR(3), \fBroar_simple_new_stream\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_simple_connect.3��������������������������������������������������0000644�0001750�0001750�00000002746�11570211566�020210� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_simple_connect" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_simple_connect, roar_simple_connect2 \- Opens a connection to RoarAudio's sound server .SH SYNOPSIS #include <roaraudio.h> int roar_simple_connect (struct roar_connection * con, char * server, char * name); int roar_simple_connect2(struct roar_connection * con, char * server, char * name, int flags, uint_least32_t timeout); .SH "DESCRIPTION" This calls opens a connection to the RoarAudio's sound server. To disconnect use \fBroar_disconnect\fR(3). .SH "PARAMETERS" .TP \fBcon\fR The roar_connection object to be filled on success with all data needed for comunicating with the server. This is used by nearly all other functions. .TP \fBserver\fR The host or filename of the socket of the server. Should normaly be \fBNULL\fR to try default locations. .TP \fBname\fR The name of this client. Should be the name of the player without any paths or filenames. .TP \fBflags\fR Flags used to connect to the server. Currently only ROAR_ENUM_FLAG_NONE and ROAR_ENUM_FLAG_NONBLOCK are supported. ROAR_ENUM_FLAG_NONBLOCK disables some of the server location features. .TP \fBtimeout\fR Timeout for the connection. A value of zero means no timeout. Currently timeouts are not supported. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_disconnect\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������roaraudio-1.0beta11/doc/man3/roar_simple_get_standby.3����������������������������������������������0000644�0001750�0001750�00000001266�11570211566�021056� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_simple_get_standby" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_simple_get_standby \- Get RoarAudio's standby state .SH SYNOPSIS #include <roaraudio.h> int roar_simple_get_standby(int fh); .SH "DESCRIPTION" Asks the server for it's standby state. This function is marked obsolete and will be removed soon. Use \fRroar_get_standby\fR(3). .SH "PARAMETERS" .TP \fBfh\fR FIXME .SH "RETURN VALUE" On success this call return \fBROAR_STANDBY_ACTIVE\fR or \fBROAR_STANDBY_INACTIVE\fR. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fRroar_get_standby\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_simple_new_stream.3�����������������������������������������������0000644�0001750�0001750�00000003376�11570211566�020723� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_simple_new_stream" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_simple_new_stream, roar_simple_new_stream_obj \- Create a new stream via RoarAudio .SH SYNOPSIS #include <roaraudio.h> int roar_simple_new_stream(struct roar_connection * con, int rate, int channels, int bits, int codec, int dir); int roar_simple_new_stream_obj(struct roar_connection * con, struct roar_stream * s, int rate, int channels, int bits, int codec, int dir); .SH "DESCRIPTION" Opens a new stream to the sound server as a independet file handle (not an execed one). This is useful if you still want some meta data or the volume to be updated after the stream is open. This functions are marked obsolete and will be removed in later releases. Please upgrade to VS API. See \fBroar_vs_new_simple\fR(3). .SH "PARAMETERS" .TP \fBcon\fR The "parent" connection. This is a valid open control connection as opend via \fBroar_simple_connect\fR(3). .TP \fBs\fR The stream object to be updated to corresponde to the new stream. This is useful if use want to update some meta data after the stream has be opened as you can use all controll commands on this object. .TP \fBrate, channels, bits, codec\fR For an explanation on these parameters see \fBroar_simple_play\fR(3). .TP \fBdir\fR For an explanation on this parameter see \fBroar_simple_stream\fR(3). .SH "RETURN VALUE" On success these calls return a new filehandle. On error, \-1 is returned. .SH "EXAMPLES" An example of the use of \fBroar_simple_new_stream_obj()\fR can be found on \fBroarvorbis\fR(1) code. .SH "SEE ALSO" \fBroar_vs_new_simple\fR(3), \fBroar_simple_connect\fR(3), \fBroar_simple_play\fR(3), \fBroar_simple_close\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_simple_play.3�����������������������������������������������������0000644�0001750�0001750�00000005201�12003754115�017503� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_simple_play" "3" "July 2012" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_simple_play, roar_simple_monitor, roar_simple_record, roar_simple_filter \- Simple playback, monetoring, recording or filtering via RoarAudio .SH SYNOPSIS #include <roaraudio.h> int roar_simple_play(int rate, int channels, int bits, int codec, char * server, char * name); int roar_simple_monitor(int rate, int channels, int bits, int codec, char * server, char * name); int roar_simple_record(int rate, int channels, int bits, int codec, char * server, char * name); int roar_simple_filter(int rate, int channels, int bits, int codec, char * server, char * name); .SH "DESCRIPTION" Open a connection to the \fBroard\fR(1) and creates a new stream for playback, monetoring, recording or filtering. After you are done you need to close the connection via \fBroar_simple_close\fR(3). In case you just don't do anything with the stream the server will kick your connection, or, in case of playback warns the user about underruns. Those functions was removed in version 1.0beta0-pr0. Please upgrade to VS API. See \fBroar_vs_new_simple\fR(3). .SH "PARAMETERS" .TP \fBrate\fR The sample rate of the stream. .TP \fBchannels\fR The nummber of channels in the stream. .TP \fBbits\fR The number of bits per sample of the stream. Commen values are 8 and 16. .TP \fBcodec\fR The Codec of the data you stream to the server. This has nothing to do with codec of the file you are playing back or encoding. Default (\fBROAR_CODEC_DEFAULT\fR) is \fBROAR_CODEC_PCM_S_BE\fR for signed PCM in big endian. .TP \fBserver\fR The name of the server. A value of \fBNULL\fR (common case) is used to try default locations. .TP \fBname\fR The name of the process opening this stream to be listend in the servers meta data. Should normaly be the name of the player without any path or filename being played. If \fBNULL\fR an internal default is used. .SH "NOTES ON FILTER STREAMS" Filtering streams should not expected to work with diffrent audio data than the server works with. You should get the values via \fBroar_server_oinfo\fR(3) before opening the stream. .SH "RETURN VALUE" On success these calls return a filehandle for the stream. On error, \-1 is returned. .SH "EXAMPLES" Examples of these calls are the tools \fBroarcat\fR(1), \fBroarmon\fR(1), \fBroarrec\fR(1) and \fBroarfilt\fR(1). Just look at there code. They aren't that complex. .SH "SEE ALSO" \fBroar_vs_new_simple\fR(3), \fBroarcat\fR(1), \fBroarmon\fR(1), \fBroarrec\fR(1), \fBroarfilt\fR(1), \fBroar_server_oinfo\fR(3), \fBroar_simple_close\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_simple_stream.3���������������������������������������������������0000644�0001750�0001750�00000004171�11570211566�020044� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_simple_stream" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_simple_stream \- Opens a stream to RoarAudio's sound server .SH SYNOPSIS #include <roaraudio.h> int roar_simple_stream(int rate, int channels, int bits, int codec, char * server, int dir, char * name); .SH "DESCRIPTION" This creates a new stream to RoarAudio. Normally you want to use one of \fBroar_simple_play\fR(3), \fBroar_simple_monitor\fR(3), \fBroar_simple_record\fR(3) or \fBroar_simple_filter\fR(3). his functions are marked obsolete and will be removed very soon. Please upgrade to VS API. See \fBroar_vs_new_simple\fR(3). .SH "PARAMETERS" .TP \fBrate, channels, bits, codec, server, name\fR For an explanation on these parameters see \fBroar_simple_play\fR(3). .TP \fBdir\fR The direction of the new stream. See below for a list of valid directions. .SH "STREAM DIRECTIONS" .TP \fBROAR_DIR_PLAY\fR This stream directions meens that a player streams data to the server in order to play it back. .TP \fBROAR_DIR_RECORD\fR This direction is to record audio from the soundcard. This is used if for example you want to get data from your microphon or line in. .TP \fBROAR_DIR_MONITOR\fR This direction is used to get a copy of what the server sends to the soundcard. This can for example be used to stream the fully mixed data to Icecast (see \fBicecast2\fR(1)). .TP \fBROAR_DIR_FILTER\fR This is used to crate a filter stream: A filter stream is a stream used to filter the output of the sound server by some tool. This can for example be used for an software equalizer. The filter stream is the only bi-directional stream. You have to read some data and write back data of exactly the same size. .TP \fBROAR_DIR_OUTPUT\fR This is the type of the stream the server sends to the soundcard. You can not create such a stream. It's only listend for completeness. .SH "RETURN VALUE" On success these calls return a filehandle. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_vs_new_simple\fR(3), \fBroar_simple_play\fR(3), \fBroar_simple_close\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_socket_listen.3���������������������������������������������������0000644�0001750�0001750�00000003714�11570211566�020050� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_socket_listen" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_socket_listen \- Opens a new listen socket .SH SYNOPSIS #include <roaraudio.h> int roar_socket_listen(int type, char * host, int port); .SH "DESCRIPTION" Opens a new listening socket for network clients to connect to. You may accept new connections via \fBaccept\fR(2). .SH "PARAMETERS" .TP \fBtype\fR The type of the Socket. See the list below. .TP \fBhost\fR The host or path name to listen on. This depends on the type argument. For TCP/IP to listen on any interface use a value of "0.0.0.0". .TP \fBport\fR The port number to listen on. This may be ignored by types not supporting port numbers. .SH "SOCKET TYPES" .TP \fBROAR_SOCKET_TYPE_UNKNOWN\fR The type will be auto detected. Don't use this if you know the type. Only use this to support user given addresses and enable auto detection. .TP \fBROAR_SOCKET_TYPE_TCP\fR Use a TCP/IP connection. This is standard mode for networking. \fBhost\fR is the hostname or IP to listen on and \fBport\fR is the port number to use. .TP \fBROAR_SOCKET_TYPE_INET\fR Same as above but deprecated. Use \fBROAR_SOCKET_TYPE_TCP\fR. .TP \fBROAR_SOCKET_TYPE_UNIX\fR UNIX Domain Socket. This should be default for local connections. \fBhost\fR is the filename of the socket. .TP \fBROAR_SOCKET_TYPE_DECNET\fR DECnet socket. .TP \fBROAR_SOCKET_TYPE_FORK\fR This is to fork a roard to communicate with. Can't be use to listen on, just to connect to. \fBhost\fR and \fBport\fR is ignored at the moment. .TP \fBROAR_SOCKET_TYPE_FILE\fR This is used to open a plain file. Can't be use to listen on, just to connect to. \fBhost\fR is the filename to connect to. .SH "RETURN VALUE" On success these calls return filehandle. On error, \-1 is returned. .SH "BUGS" Listening on UDP sockets is not supported at the moment. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBaccept\fR(2), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_socket_nonblock.3�������������������������������������������������0000644�0001750�0001750�00000001575�11570211566�020362� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_socket_nonblock" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_socket_nonblock \- Sets blocking state of a socket .SH SYNOPSIS #include <roaraudio.h> int roar_socket_nonblock(int fh, int state); .SH "DESCRIPTION" Sets the blocking mode of a given filehandle. For information on nonblocking IO see \fBopen\fR(2) an look for \fBO_NONBLOCK\fR. .SH "PARAMETERS" .TP \fBfh\fR The filehandle to set the new state on. .TP \fBstate\fR The new state. This may be \fBROAR_SOCKET_BLOCK\fR to sett blocking or \fBROAR_SOCKET_NONBLOCK\fR to set nonblocking mode. \fBROAR_SOCKET_NONBLOCK\fR is the same as setting \fBO_NONBLOCK\fR within \fBopen\fR(2). .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBopen\fR(2), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_str2codec.3�������������������������������������������������������0000644�0001750�0001750�00000002223�11570211566�017064� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_str2codec" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_str2codec \- Get codec ID by codec name roar_codec2str \- Get codec name by ID .SH SYNOPSIS #include <roaraudio.h> int roar_str2codec (char * codec); char * roar_codec2str (int codec); .SH "DESCRIPTION" \fBroar_str2codec\fR converts a string to a RoarAudio Codec ID. It also supports some common aliases. \fBroar_codec2str\fR is the reverse operation of \fBroar_str2codec\fR: It get's a name by the ID given. If a \fBcodec\fR is valid the following should be true: roar_str2codec(roar_codec2str(codec)) == codec Note that because of aliasing and case insensitivity the revers operation needs not to be true. .SH "THREAD SAFETY" Because \fBroar_codec2str\fR returns a static unique pointer for each codec it is fully thread safe. .SH "RETURN VALUE" On success \fBroar_str2codec\fR returns a codec ID. On error, \-1 is returned. \fBroar_codec2str\fR returns the name of the codec or NULL on error. You must not free this pointer or write to it. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_stream_add_data.3�������������������������������������������������0000644�0001750�0001750�00000002072�11570211566�020272� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_stream_add_data" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_stream_add_data \- Adds data to a stream's input buffer using the controll connection .SH SYNOPSIS #include <roaraudio.h> int roar_stream_add_data(struct roar_connection * con, struct roar_stream * s, char * data, size_t len); .SH "DESCRIPTION" This adds data to the input buffer of a stream. It's like doing some thing like this: write(stream_fh, data, len); but uses the controll channel to add the data. .SH "PARAMETERS" .TP \fBcon\fR The connection to the server. .TP \fBs\fR The stream to add data to it's input buffer. .TP \fBdata\fR The data to add to the buffer. .TP \fBlen\fR The length of the data to be added. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "BUGS" This call doesn't work with the current roard. The server does not use all of the buffer size and complains about unterruns. .SH "SEE ALSO" \fBwrite\fR(2), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_stream_connect.3��������������������������������������������������0000644�0001750�0001750�00000001514�11570211566�020202� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_stream_connect" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_stream_connect \- Connect a stream to RoarAudio's sound server .SH SYNOPSIS #include <roaraudio.h> int roar_stream_connect(struct roar_connection * con, struct roar_stream * s, int dir); .SH "DESCRIPTION" This connects a new stream as created by \fBroar_stream_new\fR(3) to the server. .SH "PARAMETERS" .TP \fBcon\fR The connection to the sound server .TP \fBs\fR The stream object to connect. .TP \fBdir\fR The direction of the new stream. See \fBroar_simple_stream\fR(3) for details. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_stream_new\fR(3), \fBroar_simple_stream\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_stream_connect_to.3�����������������������������������������������0000644�0001750�0001750�00000002722�11570211566�020706� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_stream_connect_to" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_stream_connect_to \- Connects a stream to some listening socket .SH SYNOPSIS #include <roaraudio.h> int roar_stream_connect_to(struct roar_connection * con, struct roar_stream * s, int type, char * host, int port); .SH "DESCRIPTION" This let the sound server connect to some remote end to get it's data for a stream. This is used internaly to open additional streams for \fBroar_simple_new_stream\fR(3). \fBNOTE:\fR This is not an alternative version of \fBroar_stream_connect\fR(3). You still need to connect the stream to the server via \fBroar_stream_connect\fR(3) before you can use this call. .SH "PARAMETERS" .TP \fBcon\fR The connection to the server. .TP \fBs\fR The stream to connect. .TP \fBtype\fR, \fBhost\fR, \fBport\fR Where the stream should be connected to. For a description of all these parameters see \fBroar_socket_listen\fR(3). .SH "NOTES" This call will block untill the server process to connect to has accepted the connection. This makes this call unusable to connect back to us if we are not threaded. For a nonblocking call see \fBroar_stream_connect_to_ask\fR(3). .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_simple_new_stream\fR(3), \fBroar_stream_connect\fR(3), \fBroar_socket_listen\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������roaraudio-1.0beta11/doc/man3/roar_stream_exec.3�����������������������������������������������������0000644�0001750�0001750�00000002031�11570211566�017470� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_stream_exec" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_stream_exec \- Set a stream as master stream of a client .SH SYNOPSIS #include <roaraudio.h> int roar_stream_exec(struct roar_connection * con, struct roar_stream * s); .SH "DESCRIPTION" This sets a stream to be the master stream of a client. A master stream is a stream send via the client's controll channel. If a master stream is closed the client and all it's streams are closed. Setting a master stream can not be undone nor can any controll commands be send anymore. This is used mainly for opening a connection for just playback without need to change things later like \fBroar_simple_play\fR(3) does it. .SH "PARAMETERS" .TP \fBcon\fR The connection to the server. .TP \fBs\fR The stream to be set as master stream. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_simple_play\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_stream_new.3������������������������������������������������������0000644�0001750�0001750�00000001337�11570211566�017345� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_stream_new" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_stream_new \- creates a new stream object .SH SYNOPSIS #include <roaraudio.h> int roar_stream_new(struct roar_stream * s, unsigned int rate, unsigned int channels, unsigned int bits, unsigned int codec); .SH "DESCRIPTION" This call create a new stream object. .SH "PARAMETERS" The parameter \fBs\fR is a pointer to the new stream object. For a description of the other parameters see \fBroar_simple_play\fR(3). .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_simple_play\fR(3), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vio_close.3�������������������������������������������������������0000644�0001750�0001750�00000001600�11570211566�017154� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_vio_close" "3" "May 2011" "RoarAudio" "System Manager's Manual: RoarAudio" .SH NAME roar_vio_close.3 \- close a RoarAudio virtual IO object .SH SYNOPSIS #include <roaraudio.h> int roar_vio_close (struct roar_vio_calls * vio); .SH "DESCRIPTION" Closes a VIO object. Also ensures all data to be fushed to disk or send via sockets. The given vio object itself is not freed as normaly located in the applications stack. if you want it to be freed you need to call \fBfree\fR(3) yourself. .SH "PARAMETERS" .TP \fBvio\fR The VIO object to be closed. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" struct roar_vio_calls obj; roar_vio_open_fh(&obj, ROAR_STDOUT); roar_vio_puts(&obj, "Hello World!\\n"); roar_vio_close(&obj); .SH "SEE ALSO" \fBroarvio\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_blocking.3�����������������������������������������������������0000644�0001750�0001750�00000002025�11570417406�017475� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_blocking" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_blocking \- Change blocking mode of VS object .SH SYNOPSIS #include <roaraudio.h> int roar_vs_blocking (roar_vs_t * vss, int val, int * error); .SH "DESCRIPTION" Changes blocking mode of VS object or ask for the current mode if \fBval\fR is set to ROAR_VS_ASK. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be altered. .TP \fBval\fR Specifies the new state. Value must be ROAR_VS_TRUE, ROAR_VS_FALSE, ROAR_VS_TOGGLE or ROAR_VS_ASK. ROAR_VS_TOGGLE should be avoided. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return the old (current if ROAR_VS_ASK is used) state of the blocking mode\. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_buffer.3�������������������������������������������������������0000644�0001750�0001750�00000003545�11572214725�017167� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_buffer" "3" "June 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_buffer \- Use buffered mode streams .SH SYNOPSIS #include <roaraudio.h> int roar_vs_buffer(roar_vs_t * vss, size_t buffer, int * error); ssize_t roar_vs_get_avail_read(roar_vs_t * vss, int * error); ssize_t roar_vs_get_avail_write(roar_vs_t * vss, int * error); int roar_vs_reset_buffer(roar_vs_t * vss, int writering, int readring, int * error); .SH "DESCRIPTION" These functions controls the buffered mode of the VS object. Using this mode is not recommended. \fBroar_vs_buffer()\fR initializes the buffered mode. It takes the size for the buffer as argument. The size should be a power of two. Common values include 2048 and 4096. \fBroar_vs_get_avail_read()\fR and \fBroar_vs_get_avail_write()\fR return the amount of free space in the read and write buffer. \fBroar_vs_reset_buffer()\fR resets the read and/or write buffer. This means the data in the buffers is discarded. This does not happen frame aligned and may result in broken audio. Buffers are not flushed automaically. To do this use \fBroar_vs_iterate\fR(3) or \fBroar_vs_run\fR(3). .SH "PARAMETERS" .TP \fBvss\fR The VS object to be used. .TP \fBbuffer\fR The size of the buffer to be used in bytes. .TP \fBwritering\fR, \fBreadring\fR Selects the buffer to reset. Must be ROAR_VS_TRUE or ROAR_VS_FALSE. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. roar_vs_get_avail_read() and roar_vs_get_avail_write() return the free space in the corresponding buffer. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_close.3��������������������������������������������������������0000644�0001750�0001750�00000002027�11570417406�017014� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_close" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_close \- Closes a VS object .SH SYNOPSIS #include <roaraudio.h> int roar_vs_close(roar_vs_t * vss, int killit, int * error); .SH "DESCRIPTION" This function closes a open VS object. The object can be closed and pending data (mainly network and server side buffers) is played or killed so no pending data is played. The later one is useful in case of handling errors. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be closed. .TP \fBkillit\fR Specifies if the stream should be killed on the server side. Must be ROAR_VS_TRUE or ROAR_VS_FALSE. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_connection_obj.3�����������������������������������������������0000644�0001750�0001750�00000003320�11570417406�020675� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_connection_obj" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_connection_obj, roar_vs_stream_obj, roar_vs_vio_obj \- VS API interface for use of main API .SH SYNOPSIS #include <roaraudio.h> struct roar_connection * roar_vs_connection_obj(roar_vs_t * vss, int * error); struct roar_stream * roar_vs_stream_obj (roar_vs_t * vss, int * error); struct roar_vio_calls * roar_vs_vio_obj (roar_vs_t * vss, int * error); .SH "DESCRIPTION" Those functions return internal connection, stream and VIO object of the VS object. They are used to use the main API with a VS opened stream. \fBroar_vs_connection_obj()\fR returns the connection object used for the control connection to the server. \fBroar_vs_stream_obj()\fR returns the stream object storing information about the stream. \fBroar_vs_vio_obj()\fR returns the VIO object used to read data from or send data to the server. Returned objects are freed as soon as the VS object is closed. If the VS object was created using \fBroar_vs_new_from_con\fR(3) the connection is not closed by the VS object and stay valid after close until it is closed by the program or library. The VIO object MUST NOT be used while in buffered mode. .SH "PARAMETERS" .TP \fBvss\fR The VS object to return internal objects from. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return the described object. On error, NULL is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_ctl.3����������������������������������������������������������0000644�0001750�0001750�00000002220�11570417406�016464� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_ctl" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_ctl \- Interface to private interals of VS object .SH SYNOPSIS #include <roaraudio.h> int roar_vs_ctl (roar_vs_t * vss, roar_vs_ctlcmd cmd, void * argp, int * error); .SH "DESCRIPTION" This function is used to access internals of the VS object. It is generally to be avoided to use this function. Valid commands depend on library version. Commands are defined in a way suitable for #ifdef checking. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be altered. .TP \fBcmd\fR Specifies the command to use on object. .TP \fBargp\fR A pointer to the operant for the given command. Type depends on command. Must be NULL for commads not taking any argument. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_file.3���������������������������������������������������������0000644�0001750�0001750�00000005635�11612656446�016644� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_file" "3" "June 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_file, roar_vs_file_simple, roar_vs_new_from_file \- File mode for VS API .SH SYNOPSIS #include <roaraudio.h> int roar_vs_file(roar_vs_t * vss, struct roar_vio_calls * vio, int closefile, int * error); int roar_vs_file_simple(roar_vs_t * vss, char * filename, int * error); roar_vs_t * roar_vs_new_from_file(const char * server, const char * name, char * filename, int * error); .SH "DESCRIPTION" These functions are used to open the VS object in file mode. In the file mode the VS API reads or writes the data from or to the file itself. The file mode uses normal VIO/DSTR so it supports streams as well. Just pass the stream URL as filename. \fBroar_vs_file()\fR sets up the file mode for a already opened object using the open VIO handle \fBvio\fR. This function requires the use of \fBroar_vs_stream\fR(3). \fBroar_vs_file_simple()\fR sets up the file mode using a given filename (or URL). It opens the file using DSTR API. By default the function assumes playback mode and tries to auto detect the audio parameters. To override the auto detection or use a diffrent stream direction use \fBroar_vs_stream\fR(3). \fBroar_vs_new_from_file()\fR creates a new VS object and enters file mode using the file (or URL) given as \fBfilename\fR. To send data to or read data from use \fBroar_vs_iterate\fR(3) or \fBroar_vs_run\fR(3). .SH "PARAMETERS" .TP \fBserver\fR The server to connect to. NULL for defaults. .TP \fBname\fR The application name. This should be something the user can use to identify the application. It MUST NOT be the application's binary name or the value of argv[0]. .TP \fBvio\fR The VIO handle to be used by the file mode. .TP \fBclosefile\fR This parameter tells the file mode if the file should be closed on roar_vio_close(3). Must be ROAR_VS_TRUE (common) or ROAR_VS_FALSE. .TP \fBfilename\fR The filename used to open the file for file mode. The file is opend using DSTR API. All kinds of files supported by DSTR are supported. This includes HTTP streams. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success roar_vs_new_from_file() return a new VS object. On error, NULL is returned. roar_vs_file() and roar_vs_file_simple() returns 0 on success and \-1 on error. .SH "EXAMPLES" roar_vs_t * vss; int err; vss = roar_vs_new_from_file(NULL, "MyApp", "http://...", &err); if ( vss == NULL ) { //handle error. } if ( roar_vs_run(vss, &err) == \-1 ) { //handle error. } if ( roar_vs_close(vss, ROAR_VS_FALSE, &err) == \-1 ) { //handle error. } .SH "SEE ALSO" \fBroar_vs_new_simple\fR(3), \fBroar_vs_iterate\fR(3), \fBroar_vs_run\fR(3), \fBroar_vs_close\fR(3), \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_iterate.3������������������������������������������������������0000644�0001750�0001750�00000002507�11572063213�017342� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_iterate" "3" "June 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_iterate, roar_vs_run \- Iterate streams .SH SYNOPSIS #include <roaraudio.h> int roar_vs_iterate (roar_vs_t * vss, int wait, int * error); int roar_vs_run (roar_vs_t * vss, int * error); .SH "DESCRIPTION" \fBroar_vs_iterate()\fR sends a block of data from the local buffer to the server or reads data from the server into the local buffer in blocking mode, or pushes or pulls data to or from server in file mode. \fBroar_vs_run()\fR does the same as roar_vs_iterate() but loops until EOF or error. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be used. .TP \fBwait\fR If ROAR_VS_WAIT roar_vs_iterate() will block until data has been synced with the server. If ROAR_VS_NOWAIT roar_vs_iterate() will not block if no data can be send to or read from the server. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On EOF these calls return 0. roar_vs_iterate() returns a positive value on non-EOF success. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_meta.3���������������������������������������������������������0000644�0001750�0001750�00000002200�11570721250�016621� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_meta" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_meta \- Update meta data for a stream .SH SYNOPSIS #include <roaraudio.h> int roar_vs_meta (roar_vs_t * vss, struct roar_keyval * kv, size_t len, int * error); .SH "DESCRIPTION" This function updates meta data of the stream. This should be done before any read or write operation and can be used at any time to update the meta data. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be updated. .TP \fBkv\fR An array of meta data elements. .TP \fBlen\fR Length of array \fBkv\fR. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" struct roar_keyval kv[2] = { {.key = "TITLE", .value = "Some title"}, {.key = "ARTIST", .value = "Some artist"} }; ret = roar_vs_meta(vss, &kv, 2, &err); .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_new.3����������������������������������������������������������0000644�0001750�0001750�00000003614�11572214725�016504� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_new" "3" "June 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_stream, roar_vs_new_from_con \- Create new VS objects .SH SYNOPSIS #include <roaraudio.h> roar_vs_t * roar_vs_new(const char * server, const char * name, int * error); roar_vs_t * roar_vs_new_from_con(struct roar_connection * con, int * error); .SH "DESCRIPTION" These calls are used to create new VS objects without a yet connected data connection. They are only helpful if there you want to share a control connection between multiple streams (generally recommended if using multiple streams to the same server) or need to use some extended parts of the VS API. If you look for a easy way to open a stream see \fBroar_vs_new_simple\fR(3) and \fBroar_vs_new_from_file\fR(3). \fBroar_vs_new()\fR opens a new control connection to server \fBserver\fR. \fBname\fR is used as application name. \fBroar_vs_new_from_con()\fR creates a new VS object from the extsing control connection \fBcon\fR. VS objects created via roar_vs_new_from_con() will not close the control connection on roar_vs_close(3). .SH "PARAMETERS" .TP \fBserver\fR The server to connect to. NULL for defaults. .TP \fBname\fR The application name. This should be something the user can use to identify the application. It MUST NOT be the application's binary name or the value of argv[0]. .TP \fBcon\fR The already existing and open control connection to use. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return a new VS object. On error, NULL is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_vs_new_simple\fR(3), \fBroar_vs_new_from_file\fR(3), \fBroar_vs_close\fR(3), \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_new_simple.3���������������������������������������������������0000644�0001750�0001750�00000004243�11572214725�020054� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_new_simple" "3" "June 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_new_simple, roar_vs_new_playback \- Create new VS objects .SH SYNOPSIS #include <roaraudio.h> roar_vs_t * roar_vs_new_simple(const char * server, const char * name, int rate, int channels, int codec, int bits, int dir, int * error); roar_vs_t * roar_vs_new_playback(const char * server, const char * name, int rate, int channels, int codec, int bits, int * error); .SH "DESCRIPTION" These functions create a new VS object with a already connected data connection. The functions connect to the server \fBserver\fR with application name \fBname\fR. They take the audio parameters as arguments \fBrate\fR, \fBchannels\fR, \fBcodec\fR, \fBbits\fR. \fBroar_vs_new_simple()\fR takes the stream direction as parameter \fBdir\fR. \fBroar_vs_new_playback()\fR is equivalent to roar_vs_new_simple() expect that it does not take the direction parameter but uses ROAR_DIR_PLAY (waveform playback). It may be implemented as a macro. .SH "PARAMETERS" .TP \fBserver\fR The server to connect to. NULL for defaults. .TP \fBname\fR The application name. This should be something the user can use to identify the application. It MUST NOT be the application's binary name or the value of argv[0]. .TP \fBrate\fR, \fBchannels\fR, \fBcodec\fR, \fBbits\fR The audio parameters for the new stream: sampling rate, number of channels per frame, used codec and number of bits per sample. .TP \fBdir\fR This is the stream direction. Common values include ROAR_DIR_PLAY for waveform playback, ROAR_DIR_MONITOR for waveform monitoring, ROAR_DIR_RECORD for waveform recording. For MIDI ROAR_DIR_MIDI_IN and ROAR_DIR_MIDI_OUT is used. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return a new VS object. On error, NULL is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_vs_new\fR(3), \fBroar_vs_new_from_file\fR(3), \fBroar_vs_close\fR(3), \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_noop.3���������������������������������������������������������0000644�0001750�0001750�00000001606�11570326341�016661� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_vs_noop" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_noop \- Send NOOP command to server .SH SYNOPSIS #include <roaraudio.h> int roar_vs_noop(roar_vs_t * vss, int * error); .SH "DESCRIPTION" This function sends a NOOP command to the server. This is useful to ping the server or to be used as keep-alive. This function may be implemented as a macro. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be used as server connection. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_pause.3��������������������������������������������������������0000644�0001750�0001750�00000002102�11570637057�017024� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_pause" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_pause, roar_vs_mute \- Alter stream flags .SH SYNOPSIS #include <roaraudio.h> int roar_vs_pause(roar_vs_t * vss, int val, int * error); int roar_vs_mute (roar_vs_t * vss, int val, int * error); .SH "DESCRIPTION" roar_vs_pause() and roar_vs_mute() alters the stream flags PAUSE and MUTE, respectively. .SH "PARAMETERS" .TP \fBvss\fR The VS object pointing to the stream which flags should be altered. .TP \fBval\fR Specifies the new state. Value must be ROAR_VS_TRUE, ROAR_VS_FALSE, ROAR_VS_TOGGLE or ROAR_VS_ASK. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return the old (current if ROAR_VS_ASK is used) state of the stream flag\. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_position.3�����������������������������������������������������0000644�0001750�0001750�00000006013�11577664154�017565� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_position" "3" "June 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_position, roar_vs_latency, roar_vs_latency2 \- Get stream position information .SH SYNOPSIS #include <roaraudio.h> ssize_t roar_vs_position(roar_vs_t * vss, int backend, int * error); roar_mus_t roar_vs_latency(roar_vs_t * vss, int backend, int * error); roar_mus_t roar_vs_latency2(roar_vs_t * vss, int backend, int wait, int * error); .SH "DESCRIPTION" \fBroar_vs_position()\fR returns the current server site position of the stream plus the current offset for the selected backend. \fBroar_vs_latency()\fR returns the latency between the client site stream position and the server site position plus the latency by the backend. Use of roar_vs_latency() is not recommended as it requires the codec to use a true constant bit rate. \fBroar_vs_latency2()\fR is perfectly equivalent to roar_vs_latency() expect that it takes the additional parameter wait. The wait parameter may have the values ROAR_VS_WAIT, ROAR_VS_NOWAIT and ROAR_VS_ASYNC. If it is ROAR_VS_WAIT the function does the same as roar_vs_latency(). If the parameter is ROAR_VS_NOWAIT roar_vs_latency2() will return interpolated data based on old data collected by calls to roar_vs_latency(), roar_vs_latency2() or roar_vs_position(). ROAR_VS_ASYNC is used to trigger asyncron updates to this internal state. Asyncron operations need to be enabled before they can be used. See \fBroar_vs_ctl\fR(3). Calling these functions too often will result in bad performance and incorrect data (pool interval smaller than server response time). Polling up to 20 times per second shoudn't be a problem. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be used. .TP \fBbackend\fR The backend used for correction. This can be a stream ID of the stream to use as backend or one of the special values defined by the constants ROAR_VS_BACKEND_*. ROAR_VS_BACKEND_NONE is used to ask for no correction. ROAR_VS_BACKEND_DEFAULT is used to ask for the default correction. This should be used in all common cases. ROAR_VS_BACKEND_FIRST is used to ask for correction based on the first primary stream on the same mixer. .TP \fBwait\fR Tells the API if the call should wait or not. Must be ROAR_VS_WAIT, ROAR_VS_NOWAIT or ROAR_VS_ASYNC. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" roar_vs_position() returns the stream position on success and \-1 on error. Stream position is the current position of the stream in units of samples (not frames!). roar_vs_latency() returns the stream latency on success and zero on error. However zero is a valid value. In case of error \fBerror\fR is set to the error. In case of no error but zero latency \fBerror\fR is cleared (set to ROAR_ERROR_NONE). Latency is retruned in mu-seconds (1/10^-6s). .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_read.3���������������������������������������������������������0000644�0001750�0001750�00000002320�11570326341�016613� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" roar_simple_play.3: .TH "roar_vs_read" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_read, roar_vs_write \- Read or write data from or to sound server .SH SYNOPSIS #include <roaraudio.h> ssize_t roar_vs_read (roar_vs_t * vss, void * buf, size_t len, int * error); ssize_t roar_vs_write(roar_vs_t * vss, const void * buf, size_t len, int * error); .SH "DESCRIPTION" roar_vs_read() reads data from the sound server into buffer \fBbuf\fR. roar_vs_write() writes data in buffer \fBbuf\fR to the sound server. .SH "PARAMETERS" .TP \fBvss\fR The VS object data is read from or written to. .TP \fBbuf\fR The buffer to read to or write from. .TP \fBlen\fR The length of the data to be read or written in byte. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return the amount of data read or written. This can be smaller than the requested size. On error, \-1 is returned. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_role.3���������������������������������������������������������0000644�0001750�0001750�00000002064�11570721250�016644� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_role" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_role \- Update role for a stream .SH SYNOPSIS #include <roaraudio.h> int roar_vs_role (roar_vs_t * vss, int role, int * error); .SH "DESCRIPTION" This function updates the role of the stream. This should be done before any read or write operation and can be used at any time to update the meta data. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be updated. .TP \fBrole\fR The new role of the stream. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" struct roar_keyval kv[2] = { {.key = "TITLE", .value = "Some title"}, {.key = "ARTIST", .value = "Some artist"} }; ret = roar_vs_meta(vss, &kv, 2, &err); .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_stream.3�������������������������������������������������������0000644�0001750�0001750�00000004350�11612656446�017211� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_stream" "3" "June 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_stream \- Set up stream parameters for VS object .SH SYNOPSIS #include <roaraudio.h> int roar_vs_stream(roar_vs_t * vss, const struct roar_audio_info * info, int dir, int * error); .SH "DESCRIPTION" This function asks a VS object opened by \fBroar_vs_new_from_con\fR(3) or \fBroar_vs_new\fR(3) to open the data connection using the audio parameters \fBinfo\fR and the stream direction \fBdir\fR. This function needs to be called before data is read or written if one of the above functions is used to create the VS object. This function is also used to provide parameters for the file mode (which is started by using \fBroar_vs_file\fR(3) or \fBroar_vs_file_simple\fR(3)). To play back a file this is not needed in a common case as the VS API tries to find correct parameters. It is required for all other stream directions. See \fBroar_vs_file\fR(3) and \fBroar_vs_file_simple\fR(3) for more information. On failture this function can be called again with diffrent parameters. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be updated. .TP \fBinfo\fR This is a pointer to the roar_audio_info structure storing the audio format parameters. The structure contains the following memebers: rate (sample rate), bits (bits per sample), channels (channels per frame) and codec. .TP \fBdir\fR This is the stream direction. Common values include ROAR_DIR_PLAY for waveform playback, ROAR_DIR_MONITOR for waveform monitoring, ROAR_DIR_RECORD for waveform recording. For MIDI ROAR_DIR_MIDI_IN and ROAR_DIR_MIDI_OUT is used. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" struct roar_audio_info info; int err; if ( roar_profile2info(&info, "isdn-eu") == \-1 ) { // error handling. } if ( roar_vs_stream(vss, &info, ROAR_DIR_PLAY, &err) == \-1 ) { // error handling. } .SH "SEE ALSO" \fBroar_vs_file\fR(3), \fBroar_vs_file_simple\fR(3), \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_strerr.3�������������������������������������������������������0000644�0001750�0001750�00000001563�11570417406�017234� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_strerr" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_strerr \- Convert an error code into a lion readable string .SH SYNOPSIS #include <roaraudio.h> const char * roar_vs_strerr(int error); .SH "DESCRIPTION" This function returns a lion readable error message for the given error code. If the error code is unknown or invalid it returns a string to represent an unknown error code unlike \fBroar_error2str\fR(3) which returns NULL. The returned string is constant memory and must not be altered or freed. This function is thread safe. .SH "PARAMETERS" .TP \fBerror\fR The error code which should be translated into a string. .SH "RETURN VALUE" Returns a constant string descripting the error \fBerror\fR. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroar_error2str\fR(3), \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ���������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_sync.3���������������������������������������������������������0000644�0001750�0001750�00000002647�11570417406�016673� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_sync" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_sync \- Sync VS object with server .SH SYNOPSIS #include <roaraudio.h> int roar_vs_sync (roar_vs_t * vss, int wait, int * error); .SH "DESCRIPTION" This function syncs the local data buffers with the server by flushing them. The parameter \fBwait\fR is used to tell the function if it should also wait for the flushed data to be played (sometimes called drain by other sound systems). This mode is not recommended expect at end of stream as it will result in buffer underruns. This function does only flush IO buffers not the ring buffers in buffered mode. Use \fBroar_vs_iterate\fR(3) or \fBroar_vs_run\fR(3) to do this. .SH "PARAMETERS" .TP \fBvss\fR The VS object to be synced. .TP \fBwait\fR Specifies if the calls should block untill all data has been played. Must be ROAR_VS_WAIT or ROAR_VS_NOWAIT. .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "NOTES" This function uses the WAIT protocol command if \fBwait\fR is set to ROAR_VS_WAIT. This is not supported by all servers. .SH "EXAMPLES" FIXME .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll �����������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man3/roar_vs_volume_get.3���������������������������������������������������0000644�0001750�0001750�00000003720�11612656446�020064� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.TH "roar_vs_volume_get" "3" "May 2011" "RoarAudio" "RoarAudio Programmer's Manual" .SH NAME roar_vs_volume_get, roar_vs_volume_mono, roar_vs_volume_stereo \- Get or set volume for audio stream .SH SYNOPSIS #include <roaraudio.h> int roar_vs_volume_get (roar_vs_t * vss, float * l, float * r, int * error); int roar_vs_volume_mono (roar_vs_t * vss, float c, int * error); int roar_vs_volume_stereo (roar_vs_t * vss, float l, float r, int * error); .SH "DESCRIPTION" Those functions are used to get or set volume for the given stream. \fBroar_vs_volume_get()\fR gets the volume for the given stream in stereo form as a left and a right component (L/R). If you need the mono volume just devide the sum of both by two. See examples below. \fBroar_vs_volume_mono()\fR sets the mono volume for the stream. Balance information is not kept. \fBroar_vs_volume_stereo()\fR sets the stereo volume for the stream as left and rigth component (L/R). .SH "PARAMETERS" .TP \fBvss\fR The VS object for wich volume is get or set. .TP \fBl\fR, \fBr\fR, \fBc\fR The volume for left, right or center (mono) channel. Value is a float in range zero to one. Zero means this channel is fully muted. One means the channel is passed without altering the amplitude. Small numerical errors are detected and corrected. Bigger errors will result in a out of range error. Note that to mute the stream you MUST NOT use volume setting but \fBroar_vs_mute\fR(3). .TP \fBerror\fR This is a pointer to a integer used to store the error value in case of error. This can be NULL if not used but it is very recommended to use this error value to report good error messages to the user. .SH "RETURN VALUE" On success these calls return 0. On error, \-1 is returned. .SH "EXAMPLES" Getting mono volume: float l, r, c; int err; if ( roar_vs_volume_get(vss, &l, &r, &err) == \-1 ) { /* handle error */ } c = (l + r)/2.; .SH "SEE ALSO" \fBroarvs\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .\" ll ������������������������������������������������roaraudio-1.0beta11/doc/man7/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553170�014076� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man7/RoarAudio.7������������������������������������������������������������0000644�0001750�0001750�00000004324�11572214725�016054� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" RoarAudio .TH "RoarAudio" "7" "November 2010" "RoarAudio" "System Manager's Manual: RoarAuido" .SH NAME RoarAudio \- RoarAudio sound system and package .SH SYNOPSIS \fBroard\fR [OPTIONS]... .SH "DESCRIPTION" \fBRoarAudio\fR is a modern, multi-OS, network transparent sound system. It supports a large amount of features required for home and professional usage. Its main purpose is to connect software (like media players) and devices (like soundcards) as a mid-layer adding features you expect from a modern sound system like software mixing and full network transparency. RoarAudio can also be used to connect multiple software components. An example for such a setup is a common webradio setup where the used playback software is connected to a streaming server in addition to a local soundcard. RoarAudio has special features for such setups like meta data passing. .SH "MAIN FEATURES" * fully network transparent. Network support for UNIX Domain Sockets, TCP/IP and DECnet * multiple audio streams per client * Vorbis comments like meta data for each audio stream * support for "legacy" clients via libroaresd, libroararts, libroaryiff * support for PulseAudio and OpenBSD's sndio clients via libroarpulse and libroarsndio * supported by many media players and other sound using applications! * mixing clients at individual levels like an analog mixer * server and client side support for common codecs like Ogg Vorbis, Speex, FLAC and many more * support for 8, 16, 24 and 32 bit per sample. Mixer resolution up to 64 bit * and many more... .SH "BUGS" A lot... .SH "SEE ALSO" \fBroar-config\fR(1), \fBroarcat\fR(1), \fBroarctl\fR(1), \fBroarfilt\fR(1), \fBroarfish\fR(1), \fBroarmon\fR(1), \fBroartypes\fR(1), \fBroarvorbis\fR(1), \fBroard\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7). .SH "HISTORY" Project started in mid of 2008. Milestones: 2008-08-31 First offical release (v. 0.1) 2009-02-04 First release of the new trunk for 0.2 (v. 0.2beta0) With this release the version schema was changed. 2009-05-21 Release of version 0.2 2009-09-06 First commercal use (roarphone, v. 0.3beta0) 2010-06-11 New pre-release based release-cycle was introduced to improve release quality 2010-08-22 Release of version 0.3 .\"ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man7/libroar.7��������������������������������������������������������������0000644�0001750�0001750�00000005322�11572214725�015620� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" RoarAudio .TH "libroar" "7" "June 2011" "RoarAudio" "System Manager's Manual: RoarAuido" .SH NAME libroar \- RoarAudio sound library .SH SYNOPSIS #include <roaraudio.h> .SH "DESCRIPTION" \fBlibroar\fR is a central library used to comunicate with RoarAudio servers. It supports all commands from simple commands to play some audio up to complex commands to controll the server and do nice things over the network. It also includes several useful functions from buffer mangement to IO abstraction. .SH "EXAMPLES" The basic tools shiped with RoarAudio are designed to also work as examples for the lib. You may start by looking at \fBroarcat\fR(1)s source code as an example on how to simply play back some audio. A more complex example is \fBroarvorbis\fR(1) which also includes meta data updates. You should also have a look at VS API, see \fBroarvs\fR(7) for a overview. .SH "TUTORIALS" Tutorials can be found in \fBroartut\fR(7). .SH "ENVIRONMENT VARIABLES" The following variables are used in libroar itself so they are common to all clients using libroar. .TP \fBHOME\fR The users home directory. .TP \fBROAR_SERVER\fR The address of the listening server. This may be in form of host:port for TCP/IP connections and /path/to/sock for UNIX Domain Sockets. If a value of '+fork' is given a roard is forked and used. This roard will not listen on any sockets so it is used exclusiv by this client. See \fBroard\fR(1) for more information. .TP \fBROAR_PROXY\fR Set the type of the proxy being used to connect to the server. Valid values are 'socks4', 'socks4a', 'socks4d', 'http' and 'ssh' for the moment. You can add type depending options in form 'type/opts'. .TP \fBsocks_proxy\fR The SOCKS4/4a/4d/5 proxy to use in form [user@]host[:port]. Default port is 9050. .TP \fBhttp_proxy\fR, \fBhttps_proxy\fR The HTTP/HTTPS Proxy server. This server needs to understand the CONNECT request type. Give the server name in this format: [http://]host[:port][/] The default port is 8080. .TP \fBssh_proxy\fR The remote host to use as SSH Proxy server. Give the server name in this format: [user@]host[:port] The default port is 22. Note that you may need to use publickey based auth or ssh-agent because the application may start SSH in a non interactive environment and SSH can not ask you for a password. .SH "FILES" .TP \fB/etc/roarserver\fR This is a symlink to the server socket. If all types of server addresses are supported. Example: ln \-s /tmp/roar /etc/roarserver ln \-s somehost /etc/roarserver ln \-s mynode:: /etc/roarserver .SH "BUGS" A lot... .SH "SEE ALSO" \fBroar-config\fR(1), \fBroartypes\fR(1), \fBroarvs\fR(7), \fBroartut\fR(7), \fBroard\fR(1), \fBroartips\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" See \fBRoarAudio\fR(7). .\"ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man7/roardecnet.7�����������������������������������������������������������0000644�0001750�0001750�00000002704�11472204233�016305� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" RoarAudio .TH "roardecnet" "7" "November 2010" "RoarAudio" "System Manager's Manual: RoarAuido" .SH NAME roardecnet \- Hints for DECnet users or RoarAudio .SH SYNOPSIS roard \-n [OPTIONS...] ... roarclient \-\-server node:: [OPTIONS...] ... .SH "DESCRIPTION" This manpage lists some hints for use of RoarAudio over DECnet. .SH "BASICS" If DECnet support is compiled in, there is the option '\fB-n\fR' of \fBroard\fR(1). If you set it the daemon will listen via DECnet. You may use the option '\fB-b\fR' to set the object name. Nodenames given via '\fB-b\fR' are ignored. Example: roard \-n roard \-n \-b ::myobject If you use the default object local clients should find there way to the server. For remote clients or if you use a non default object it is needed to give a server address in a form listent below. .SH "SERVER ADDRESS" The server address for DECnet is in one of the following forms: \fBnode::\fR, \fBnode::object\fR, \fB::object\fR, \fB::\fR. This is the way to specify a DECnet connection to node \fBnode\fR's object \fBobject\fR. Both may be omitted to use defaults. Default node name is local hosts node name. Examples: mynode:: connect to \fBmynode\fR ::roar connect to local object \fBroar\fR yournode::yourroard connect to \fByournode\fR's object \fByourroard\fR :: connect to default object on local node .SH "SEE ALSO" \fBroard\fR(1), \fBroartips\fR(7), \fBlibroar\fR(7). .\"ll ������������������������������������������������������������roaraudio-1.0beta11/doc/man7/roartips.7�������������������������������������������������������������0000644�0001750�0001750�00000004343�11413146746�016034� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" RoarAudio .TH "roartips" "7" "August 2008" "RoarAudio" "System Manager's Manual: RoarAuido" .SH NAME roartips \- Tips for RoarAudio users .SH SYNOPSIS roard [OPTIONS...] ... roarclient [OPTIONS...] ... .SH "DESCRIPTION" This manpage lists some tips for intermedia to advanced users of RoarAudio. .SH "CONTROLLING ROARD" RoarAudio supports a lot of things you can change on the fly. This includes the volume for each stream as you may allready noticed: If you cange the volume within a player only this stream is changed, other streams keep there loudness. There a a lot other things that can be changed on the fly. To do this there is a tool called \fBroarctl\fR(1). You may want to play around a bit with it. A good start are to try those two commands: roarctl \-\-help roarctl allinfo The later one will show you all information current available of the server it self, the clients and the streams. This may include a lot of information. .SH "SERVER ADDRESS" There a serverel types of server addresses based on the protocol used to communicate. This lists the corrently implemented types in order of importance: .TP \fB/path/to/sock\fR Path to UNIX Domain Socket. Example: /tmp/roar .TP \fBhost\fR, \fBhost:port\fR This is used for connections over TCP/IP. If port is omitted the default port is used. Examples: audio.homeserver.local localhost:7564 .TP \fBnode::\fR, \fBnode::object\fR, \fB::object\fR, \fB::\fR This is the way to specify a DECnet connection to node \fBnode\fR's object \fBobject\fR. Both may be omitted to use defaults. Default node name is local hosts node name. Examples: mynode:: ::roar yournode::yourroard .TP \fB+fork\fR This starts a new roard for every \fBroar_connect\fR(3). This is used internaly by the lib to emulate EsounD's fallback. .SH "ENVIRONMENT" .TP \fBROAR_SERVER\fR This varibale contains the default server address. If some client does not allow a user to set a server address or to set a default value this one come into play. Examples: ROAR_SERVER=some.host ROAR_SERVER=another.host:port ROAR_SERVER=node:: ROAR_SERVER=/tmp/roar .SH "SEE ALSO" \fBroarcat\fR(1), \fBroarctl\fR(1), \fBroarfilt\fR(1), \fBroarfish\fR(1), \fBroarmon\fR(1), \fBroarvorbis\fR(1), \fBroard\fR(1), \fBlibroar\fR(7). .\"ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man7/roartut.7��������������������������������������������������������������0000644�0001750�0001750�00000022025�11477262274�015673� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" RoarAudio .TH "roartut" "7" "November 2010" "RoarAudio" "System Manager's Manual: RoarAuido" .SH NAME roartut \- RoarAudio sound library developer tutorial .\".SH SYNOPSIS .\" #include <roaraudio.h> .SH "DESCRIPTION" This tutorial descipes some basics with working with libroar. We will create a simple application that can play a file and one that can play some sines. A lot of other examples can be found in RoarAudio's sources in the roarclients directory. This tutorial will cover some basics of the so called VS API. The VS API is a abstract layer ontop of the normal API. It is designed to be simple yet powerful. The VS API is all you need for most applications. If you need more control over what you do you must use the normal. If you need only a little of those extra power you can mix VS API and normal API. .SH "PLAYING A FILE" Playing back a file is a easy task with libroar. The VS API has some special support to play back files in a very simple way. This is shown here. First of all we need to include the needed header files: #include <roaraudio.h> /* libroar */ This main header already includes all we need to use the VS API. Now we can start our main(). We need to declare a object for the VS API as it is object oriented. This object is used to interact with the server and send all audio data to it: roar_vs_t * vss; int err; /* see later */ Next we need to open the connection to the server. The most simple function to do this is \fBroar_vs_new_from_file\fR(3) if we are going to play a file. It takes the folloing arguments: .TP \fBserver address\fR This is the address of the server. In general case This should be set to NULL. .TP \fBprogram name\fR This is the name of our program. This should be set to some name the user will recognize like "some App", "some Game". It \fBshould not\fR contain the filename of the process like "/usr/bin/someapp.bin". .TP \fBfile name\fR This is the name of the file we want to play. In fact this is a URL. VS API uses so called DSTR API to open files. DSTR API supports local files as well as for example HTTP. Examples include: "somefile.ogg", "file:///data/bla.wav", "http://radiostation.org:8000/bla.ogg". .TP \fBerror var\fR This is a pointer to a int used to store the error value in case of error. This can be set to NULL but should not. The function \fBroar_vs_strerr\fR(3) can be used to get a lion readable string of the error. .P Our call to \fBroar_vs_new_from_file\fR(3) will look like this: vss = roar_vs_new_from_file(NULL, "some App", "somefile.ogg", &err); if ( vss == NULL ) { roar_vio_printf(roar_stderr, "Error: Can not connect to server: %s\n", roar_vs_strerr(err)); return 1; } Next we need to continuously feed in the data so the server can do the playback. Again most simple way is to use \fBroar_vs_run\fR(3). if ( roar_vs_run(vss, &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: can not loop: %s\n", roar_vs_strerr(err)); } This will block untill all of the file is played. After it returned must close the VS object. This should be done directly after \fBroar_vs_run\fR(3) returned. This is done this way: if ( roar_vs_close(vss, ROAR_VS_FALSE, &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: Can not close connection to server: %s\n", roar_vs_strerr(err)); return 1; } After adding some standard main() construct we should have something like this: //vsfile.c: #include <roaraudio.h> int main (void) { roar_vs_t * vss; int err; /* see later */ vss = roar_vs_new_from_file(NULL, "some App", "somefile.ogg", &err); if ( vss == NULL ) { roar_vio_printf(roar_stderr, "Error: Can not connect to server: %s\n", roar_vs_strerr(err)); return 1; } if ( roar_vs_run(vss, &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: can not loop: %s\n", roar_vs_strerr(err)); } if ( roar_vs_close(vss, ROAR_VS_FALSE, &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: Can not close connection to server: %s\n", roar_vs_strerr(err)); return 1; } return 0; } //ll To compile and link we can use a command like this one: cc \-o vsfile vsfile.c `roar\-config \-\-libs \-\-cflags` The tool \fBroar-config\fR(1) will keep care for us about all flags needed for libroar. .SH "PLAYING A SINE" Now we want to write a application playing a sine for some secs. We start the same way by including the correct header files: #include <math.h> /* sin() */ #include <roaraudio.h> /* libroar */ After that we need some basic varibales with data about the audio we want to play back: int rate = ROAR_RATE_DEFAULT; int bits = 16; int channels = 1; /* mono */ Next we need to set the 'codec'. The codec is how the data is encoded. We want PCM as signed ints in the native byte order of our machine. int codec = ROAR_CODEC_DEFAULT; Now we need to store the frequency of our sine: float freq = 523.2; /* middle C */ float step = M_PI*2*freq/rate; /* how much time per sample we have to encode ... */ In addition we need some variables to store the current time and the length of time sine: float t = 0; /* current time */ float length = 5; /* 5 sec */ Next we need the buffer to hold the data as well as a varible used to go thru the buffer on generation of data. int16_t out[1024]; int i; last we need the VS object again as well as our error var: roar_vs_t * vss; int err; This time we open the connection to the server using \fBroar_vs_new_playback\fR(3). It is similar to \fBroar_vs_new_from_file\fR(3) but takes some other options: .TP \fBserver address\fR Same as above. .TP \fBprogram name\fR same as above. .TP \fBsample rate\fR The number of audio frames per sec. .TP \fBchannels\fR The number of samples (one per channel) per audio frame. .TP \fBcodec\fR The codec to be used. This is one of ROAR_CODEC_*. In our case we use ROAR_CODEC_DEFAULT which is signed PCM in CPU native format. .TP \fBbits\fR The number of bits per sample. .TP \fBerror var\fR same as above. .P The call looks like this: vss = roar_vs_new_playback(NULL, "vssin", rate, channels, codec, bits, &err); if ( vss == NULL ) { roar_vio_printf(roar_stderr, "Error: Can not connect to server: %s\n", roar_vs_strerr(err)); return 1; } Now we want to loop for \fBlength\fR seconds: while (t < 2*M_PI*freq*length) { } In this loop we need to calculate our samples: for (i = 0; i < (sizeof(out)/sizeof(*out)); i++) { out[i] = 32767.f*sin(t); t += step; } The sine is multiplyed by 32767 as our amplitude range for 16 bit signed int is from \-32768 to +32767. After we have our current data in \fBout\fR we want to write them to the server: if ( roar_vs_write(vss, out, sizeof(out), &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: Can not write audio data to server: %s\n", roar_vs_strerr(err)); break; } \fBNOTE:\fR In a real application you may want to check the return value for short writes: Those are writes shorter than the requested amount of data to be written. If you got any short writes you should try to rewrite the rest of your buffer later. This is not a error case. After we are finished with our main loop we have to close the connection to the server. This is done by \fBroar_vs_close\fR(3) as we already done in the file playback example: if ( roar_vs_close(vss, ROAR_VS_FALSE, &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: Can not close connection to server: %s\n", roar_vs_strerr(err)); return 1; } After adding some standard main() construct we should have something like this: //vssin.c: #include <roaraudio.h> #include <math.h> int main (void) { roar_vs_t * vss; int rate = ROAR_RATE_DEFAULT; int bits = 16; int channels = 1; /* mono */ int codec = ROAR_CODEC_DEFAULT; float freq = 523.2; /* middle C */ float step = M_PI*2*freq/rate; /* how much time per sample we have to encode ... */ float t = 0; /* current time */ float length = 5; /* 5 sec */ int16_t out[1024]; size_t i; int err; vss = roar_vs_new_playback(NULL, "vssin", rate, channels, codec, bits, &err); if ( vss == NULL ) { roar_vio_printf(roar_stderr, "Error: Can not connect to server: %s\n", roar_vs_strerr(err)); return 1; } while (t < 2*M_PI*freq*length) { for (i = 0; i < (sizeof(out)/sizeof(*out)); i++) { out[i] = 32768.f*sin(t); t += step; } if ( roar_vs_write(vss, out, sizeof(out), &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: Can not write audio data to server: %s\n", roar_vs_strerr(err)); break; } } if ( roar_vs_close(vss, ROAR_VS_FALSE, &err) == \-1 ) { roar_vio_printf(roar_stderr, "Error: Can not close connection to server: %s\n", roar_vs_strerr(err)); return 1; } return 0; } //ll To compile and link we can use a command like this one: cc \-o vssin vssin.c \-lm `roar\-config \-\-libs \-\-cflags` We need to use \fB-lm\fR to link the math library for \fBsin()\fR. The tool \fBroar-config\fR(1) will keep care for us about all flags needed for libroar. Now we should have a working binary \fBvssin\fR playing a sin() for 5 sec. Happy hacking! .SH "SEE ALSO" \fBroar-config\fR(1), \fBroarcat\fR(1), \fBlibroar\fR(7). \fBRoarAudio\fR(7). .\"ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man7/roarvio.7��������������������������������������������������������������0000644�0001750�0001750�00000003357�11570302132�015641� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" RoarAudio .TH "roarvio" "7" "May 2011" "RoarAudio" "System Manager's Manual: RoarAuido" .SH NAME libroar \- RoarAudio sound library roarvio \- RoarAudio virtual IO layer .SH SYNOPSIS #include <roaraudio.h> struct roar_vio_calls; .SH "DESCRIPTION" The RoarAudio VIO interface is RoarAudio's IO abstraction layer. It provides basic IO functions such as read and write independing on the underlaying IO. For Example can you open a plain or a gziped file via the VIO layer. After a successful open both objects behave the same, libroar takes care about the compression in the gzip case. .\".SH "EXAMPLES" .SH "TUTORIALS" Tutorials can be found in \fBroartutvio\fR(7). .SH "IMPORTANT FUNCTIONS" There are several important functions. This is a small list of the most important ones. .TP \fBOpening\fR \fBroar_vio_open_file\fR(3), \fBroar_vio_open_fh\fR(3), \fBroar_vio_open_stdio\fR(3), \fBroar_vio_open_dstr\fR(3), \fBroar_vio_open_proto\fR(3). While there are a lot functions important for opening files the most important one is \fBroar_vio_open_dstr\fR(3). It opens a stream based on URLs that can point to local files or files on remote machines. It also can handle compression and encryption. .TP \fBClosing\fR \fBroar_vio_close\fR(3), \fBroar_vio_shutdown\fR(3) .TP \fBReading and writing\fR \fBroar_vio_read\fR(3), \fBroar_vio_write\fR(3) .TP \fBSeeking and positioning\fR \fBroar_vio_lseek\fR(3) .TP \fBNon-Blocking and Asyncron IO\fR \fBroar_vio_nonblock\fR(3), \fBroar_vio_sync\fR(3), \fBroar_vio_select\fR(3) .TP \fBNetworking and Sockets\fR \fBroar_vio_accept\fR(3) .TP \fBString handling\fR \fBroar_vio_printf\fR(3) .SH "BUGS" A lot... .SH "SEE ALSO" \fBroar-config\fR(1), \fBroartypes\fR(1), \fBroartutvio\fR(7), \fBRoarAudio\fR(7). .\"ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/doc/man7/roarvs.7���������������������������������������������������������������0000644�0001750�0001750�00000003500�11613256166�015477� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" RoarAudio .TH "roarvs" "7" "June 2011" "RoarAudio" "System Manager's Manual: RoarAuido" .SH NAME libroar \- RoarAudio sound library roarvs \- RoarAudio very simple API .SH SYNOPSIS #include <roaraudio.h> roar_vs_t * vss; .SH "DESCRIPTION" The VS (for Very Simple) API is a high level abstraction layer used to allow use of RoarAudio from very simple programs. The API was designed to help people to easly upgrade existing artsc and pulse-simple code to RoarAudio. While the API is equivalently simple it is much more powerful than one one by aRtsc or PulseAudio. The VS API also has a mode to play back (and record) files easly. As this uses VIO/DSTR it can handle streams as well. .\".SH "EXAMPLES" .SH "TUTORIALS" Tutorials can be found in \fBroartut\fR(7). .SH "IMPORTANT FUNCTIONS" There are several important functions. This is a small list of the most important ones. .TP \fBError handling\fR \fBroar_vs_strerr\fR(3) .TP \fBOpening\fR \fBroar_vs_new\fR(3), \fBroar_vs_new_simple\fR(3), \fBroar_vs_new_playback\fR(3), \fBroar_vs_new_from_file\fR(3) .TP \fBClosing\fR \fBroar_vs_close\fR(3) .TP \fBReading and writing\fR \fBroar_vs_read\fR(3), \fBroar_vs_write\fR(3) .TP \fBNon-Blocking and Asyncron IO\fR \fBroar_vs_blocking\fR(3), \fBroar_vio_select\fR(3) .TP \fBVolume and Flags\fR \fBroar_vs_pause\fR(3), \fBroar_vs_mute\fR(3), \fBroar_vs_volume_mono\fR(3), \fBroar_vs_volume_stereo\fR(3), \fBroar_vs_volume_get\fR(3) .TP \fBMeta data\fR \fBroar_vs_meta\fR(3), \fBroar_vs_role\fR(3) .TP \fBFile mode\fR \fBroar_vs_file\fR(3), \fBroar_vs_file_simple\fR(3), \fBroar_vs_iterate\fR(3), \fBroar_vs_run\fR(3) .TP \fBBuffered mode\fR \fBroar_vs_buffer\fR(3), \fBroar_vs_iterate\fR(3), \fBroar_vs_run\fR(3) .SH "BUGS" A lot... .SH "SEE ALSO" \fBroar-config\fR(1), \fBroartypes\fR(1), \fBroartut\fR(7), \fBRoarAudio\fR(7). .\"ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�014114� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/����������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�015546� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/asyncctl.h������������������������������������������������������0000644�0001750�0001750�00000003156�12264733453�017543� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//asyncctl.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARASYNCCTL_H_ #define _LIBROARASYNCCTL_H_ #include "libroar.h" int roar_wait (struct roar_connection * con, struct roar_event * triggered, struct roar_event * events, size_t num); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/acl.h�����������������������������������������������������������0000644�0001750�0001750�00000003122�12264733453�016453� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//acl.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARACL_H_ #define _LIBROARACL_H_ #include "libroar.h" int roar_acl_rule_chk_connect (struct roar_acl_rule * rule, struct sockaddr * addr, socklen_t addrlen); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/authfile.h������������������������������������������������������0000644�0001750�0001750�00000006064�12264733454�017526� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//authfile.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARAUTHFILE_H_ #define _LIBROARAUTHFILE_H_ #include "libroar.h" #define ROAR_AUTHFILE_TYPE_AUTO -1 /* auto detect type of key */ #define ROAR_AUTHFILE_TYPE_NONE 0 /* dummy */ #define ROAR_AUTHFILE_TYPE_ROAR 1 /* RoarAudio */ #define ROAR_AUTHFILE_TYPE_ESD 2 /* EsounD, plain cookie, len=16 byte */ #define ROAR_AUTHFILE_TYPE_PULSE 3 /* PulseAudio, plain cookie, len=256 byte */ #define ROAR_AUTHFILE_TYPE_HTPASSWD 4 /* Common .htpasswd format */ #define ROAR_AUTHFILE_TYPE_XAUTH 5 /* a xauth file */ #define ROAR_AUTHFILE_VERSION_AUTO -1 struct roar_authfile; struct roar_authfile * roar_authfile_open(int type, const char * filename, int rw, int version); int roar_authfile_close(struct roar_authfile * authfile); int roar_authfile_lock(struct roar_authfile * authfile); int roar_authfile_unlock(struct roar_authfile * authfile); int roar_authfile_sync(struct roar_authfile * authfile); struct roar_authfile_key { size_t refc; int type; int index; const char * address; void * data; size_t len; }; struct roar_authfile_key * roar_authfile_key_new(int type, size_t len, const char * addr); #define roar_authfile_key_free(key) roar_authfile_key_unref(key) int roar_authfile_key_ref(struct roar_authfile_key * key); int roar_authfile_key_unref(struct roar_authfile_key * key); int roar_authfile_add_key(struct roar_authfile * authfile, struct roar_authfile_key * key); struct roar_authfile_key * roar_authfile_lookup_key(struct roar_authfile * authfile, int type, int minindex, const char * address); struct roar_authfile_key * roar_authfile_key_new_random(int type, size_t len, const char * addr); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/auth.h����������������������������������������������������������0000644�0001750�0001750�00000004025�12264733453�016660� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//auth.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARAUTH_H_ #define _LIBROARAUTH_H_ #include "libroar.h" struct roar_auth_message { int type; int stage; union { char c[2]; uint16_t ui16; } reserved; void * data; size_t len; }; int roar_auth (struct roar_connection * con); int roar_auth_from_mes(struct roar_auth_message * ames, struct roar_message * mes, void * data); int roar_auth_to_mes(struct roar_message * mes, void ** data, struct roar_auth_message * ames); int roar_auth_init_mes(struct roar_message * mes, struct roar_auth_message * ames); int roar_str2autht(const char * str); const char * roar_autht2str(const int auth); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/base64.h��������������������������������������������������������0000644�0001750�0001750�00000004536�12264733454�017013� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//base64.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARBASE64_H_ #define _LIBROARBASE64_H_ #include "libroar.h" #define ROAR_BASE64_FLAG_NONE 0x0000 #define ROAR_BASE64_FLAG_EOF 0x0001 #define ROAR_BASE64_FLAG_OPENPGP 0x0002 #define ROAR_BASE64_FLAG_CRC_OK 0x0004 struct roar_base64 { int flags; unsigned char iobuf[3]; int buflen; int reg, reglen; }; int roar_base64_init(struct roar_base64 * state, int flags); #define roar_base64_init_encode(state,flags) roar_base64_init((state),(flags)) #define roar_base64_init_decode(state,flags) roar_base64_init((state),(flags)) ssize_t roar_base64_encode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off, int eof); ssize_t roar_base64_decode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off); int roar_base64_is_eof(struct roar_base64 * state); int roar_base64_uninit(struct roar_base64 * state); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/basic.h���������������������������������������������������������0000644�0001750�0001750�00000013207�12264733454�017003� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//basic.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARBASIC_H_ #define _LIBROARBASIC_H_ #include "libroar.h" #define LIBROAR_BUFFER_SMALL 80 #define LIBROAR_BUFFER_MSGDATA LIBROAR_BUFFER_SMALL #define _ROAR_MESSAGE_VERSION 0 #if ROAR_MAX_CHANNELS > (LIBROAR_BUFFER_SMALL - 10) #error ROAR_MAX_CHANNELS too large change ROAR_MAX_CHANNELS or LIBROAR_BUFFER_SMALL #endif #define ROAR_CON_FLAGS_NONE 0x00000000UL #define ROAR_CON_FLAGS_FH 0x00000001UL /* obsoleted */ #define ROAR_CON_FLAGS_VIO 0x00000002UL /* mandatory */ #define ROAR_CON_FLAGS_ISCLIENT 0x00000004UL #define ROAR_CON_FLAGS_SUPPORT_V2 0x00000008UL /* mandatory if con.version == 2 */ #define ROAR_CON_FLAGS_SUPPORT_EF 0x00000010UL /* Both peers support error frames */ #define ROAR_CON_FLAGS_FREESELF 0x00000020UL /* Free the connection object */ #define ROAR_CON_FLAGS_TERMINATE 0x00000040UL /* Send TERMINATE before QUIT */ struct roar_message { int cmd; unsigned int stream; uint32_t pos; size_t datalen; char data[LIBROAR_BUFFER_MSGDATA]; int16_t seq; int32_t flags; int32_t crc; int version; uint64_t pos64; }; struct roar_stds; // "caps.h" will be included later. struct roar_connection { size_t refc; uint32_t flags; int version; struct roar_vio_calls * viocon; struct roar_vio_calls viocon_store; struct roar_error_frame errorframe; void * cb_userdata; void (*cb)(struct roar_connection * con, struct roar_message * mes, void * data, void * userdata); struct roar_stds * server_stds; char * server_name; }; int roar_connect (struct roar_connection * con, const char * server, int flags, uint_least32_t timeout); int roar_connect_none (struct roar_connection * con); int roar_connect_vio (struct roar_connection * con, struct roar_vio_calls * vio); int roar_connect_fh (struct roar_connection * con, int fh); int roar_get_connection_fh (struct roar_connection * con); struct roar_vio_calls * roar_get_connection_vio2 (struct roar_connection * con); const char * roar_get_connection_server(struct roar_connection * con); int roar_connectionref(struct roar_connection * con); int roar_connectionunref(struct roar_connection * con); #define roar_disconnect(x) roar_connectionunref((x)) int roar_set_connection_callback(struct roar_connection * con, void (*cb)(struct roar_connection * con, struct roar_message * mes, void * data, void * userdata), void * userdata); int roar_set_connection_version(struct roar_connection * con, int version); int16_t roar_message_genseq(struct roar_connection * con, int is_client); int roar_sync (struct roar_connection * con); int roar_wait_msg (struct roar_connection * con, int16_t seq, int16_t seqmask); int roar_noop (struct roar_connection * con); int roar_identify (struct roar_connection * con, const char * name); int roar_send_message (struct roar_connection * con, struct roar_message * mes, char * data); int roar_recv_message (struct roar_connection * con, struct roar_message * mes, char ** data); int roar_req (struct roar_connection * con, struct roar_message * mes, char ** data); int roar_recv_message2 (struct roar_connection * con, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe); int roar_req2 (struct roar_connection * con, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe); #define roar_req3(con,mes,data) roar_req2((con), (mes), (data), roar_err_errorframe()) int roar_vsend_message(struct roar_vio_calls * vio, struct roar_message * mes, char * data); int roar_vrecv_message(struct roar_vio_calls * vio, struct roar_message * mes, char ** data); int roar_vreq (struct roar_vio_calls * vio, struct roar_message * mes, char ** data); int roar_vrecv_message2(struct roar_vio_calls * vio, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe); int roar_vreq2 (struct roar_vio_calls * vio, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/beep.h����������������������������������������������������������0000644�0001750�0001750�00000003242�12264733455�016634� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//beep.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARBEEP_H_ #define _LIBROARBEEP_H_ #include "libroar.h" struct roar_beep { uint16_t vol; uint16_t time; uint16_t freq; uint16_t type; int16_t x, y, z; }; int roar_beep(struct roar_connection * con, const struct roar_beep * beep); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/buffer.h��������������������������������������������������������0000644�0001750�0001750�00000013102�12264733455�017166� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//buffer.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAR_BUFFER_H_ #define _LIBROAR_BUFFER_H_ #include <roaraudio.h> #define ROAR_BUFFER_FLAG_NONE 0x00 #define ROAR_BUFFER_FLAG_NOFREE 0x01 #define ROAR_BUFFER_FLAG_RING 0x02 #define ROAR_BUFFER_FLAG_FREE_RUNNING 0x04 // for memory corruption detection: #define ROAR_BUFFER_FLAG_USEABLE 0x40 #define ROAR_BUFFER_FLAG_FREED 0x80 #define ROAR_BUFFER_SET 0 #define ROAR_BUFFER_RESET 1 #define _LIBROAR_BUFFER_STDATTRS _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL struct roar_buffer; struct roar_buffer_stats { size_t parts; size_t bytes; size_t memory_usage; }; #define roar_buffer_new(a,len) roar_buffer_new_data((a), (len), NULL) #define roar_buffer_free(x) roar_buffer_unref(x) #define roar_buffer_foreach(cur) for (; (cur) != NULL; (cur) = (roar_buffer_next(&(cur)) == -1) ? NULL : (cur)) int roar_buffer_new_no_ma(struct roar_buffer ** buf, size_t len, void * data) _LIBROAR_BUFFER_STDATTRS; // no internal malloc int roar_buffer_delete (struct roar_buffer * buf, struct roar_buffer ** next) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_next (struct roar_buffer ** buf) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_add (struct roar_buffer * buf, struct roar_buffer * next) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_moveinto (struct roar_buffer * buf, struct roar_buffer ** next) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_moveintoqueue(struct roar_buffer ** buf, struct roar_buffer ** next) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_ref (struct roar_buffer * buf) _LIBROAR_ATTR_NONNULL_ALL; int roar_buffer_unref (struct roar_buffer * buf) _LIBROAR_ATTR_NONNULL_ALL; int roar_buffer_new_data (struct roar_buffer ** buf, size_t len, void ** data) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1); int roar_buffer_new_str (struct roar_buffer ** buf, const char * str, int terminate) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_buffer_ring_new (struct roar_buffer ** buf, size_t len, int free_running) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_next (struct roar_buffer * buf, struct roar_buffer ** next) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_data (struct roar_buffer * buf, void ** data) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_datalen(struct roar_buffer * buf, void ** data, size_t * len) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_set_offset (struct roar_buffer * buf, size_t off) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_shift_out (struct roar_buffer ** buf, void * data, size_t * len) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_set_meta (struct roar_buffer * buf, void * meta) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_meta (struct roar_buffer * buf, void ** meta) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_set_meta_i32(struct roar_buffer * buf, int32_t meta) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_meta_i32(struct roar_buffer * buf, int32_t * meta) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_set_type (struct roar_buffer * buf, int type) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_type (struct roar_buffer * buf, int * type) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_set_len (struct roar_buffer * buf, size_t len) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_len (struct roar_buffer * buf, size_t * len) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_set_flag (struct roar_buffer * buf, int flag, int reset) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_get_flag (struct roar_buffer * buf, int flag) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_duplicate (struct roar_buffer * buf, struct roar_buffer ** copy) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_ring_stats (struct roar_buffer * buf, struct roar_buffer_stats * stats) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_ring_read (struct roar_buffer * buf, void * data, size_t * len) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_ring_write (struct roar_buffer * buf, void * data, size_t * len) _LIBROAR_BUFFER_STDATTRS; int roar_buffer_ring_avail(struct roar_buffer * buf, size_t * readlen, size_t * writelen) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1); int roar_buffer_ring_reset(struct roar_buffer * buf) _LIBROAR_BUFFER_STDATTRS; #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/caps.h����������������������������������������������������������0000644�0001750�0001750�00000004227�12264733455�016653� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//caps.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARCAPS_H_ #define _LIBROARCAPS_H_ #include "libroar.h" struct roar_caps { int version; int type; int flags; void * data; size_t len; }; struct roar_stds { size_t stds_len; uint32_t * stds; }; const struct roar_stds * libroar_libstds(void); int roar_caps_to_msg(struct roar_message * mes, struct roar_caps * caps, void ** data); int roar_caps_from_msg(struct roar_caps * caps, struct roar_message * mes, void * data); int roar_caps_stds(struct roar_connection * con, struct roar_stds ** out, struct roar_stds * in, int flags); struct roar_stds * roar_stds_new(size_t len); int roar_stds_free(struct roar_stds * stds); int roar_stds_str2vendor(const char * vendor); const char * roar_stds_vendor2str(const int vendor); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/cdrom.h���������������������������������������������������������0000644�0001750�0001750�00000004650�12264733455�017031� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//cdrom.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARCDROM_H_ #define _LIBROARCDROM_H_ #include "libroar.h" #define ROAR_CDROM_MAX_DEVLEN 80 #define ROAR_CDROM_RATE 44100 #define ROAR_CDROM_CHANNELS 2 #define ROAR_CDROM_BITS 16 #define ROAR_CDROM_CODEC ROAR_CODEC_DEFAULT /* we ask cdparanoia to output in host byte order */ #define ROAR_CDROM_STREAMINFO ROAR_CDROM_RATE, ROAR_CDROM_CHANNELS, ROAR_CDROM_BITS, ROAR_CDROM_CODEC struct roar_cdrom { int play_local; int fh; int stream; int mixer; pid_t player; char device[ROAR_CDROM_MAX_DEVLEN]; struct roar_connection * con; }; struct roar_cdrom_title { int track; // 0..n, -1 = unset/end of list uint32_t start; // offset in samples uint32_t length; // length in samples }; int roar_cdrom_open (struct roar_connection * con, struct roar_cdrom * cdrom, const char * device, int mixer); int roar_cdrom_close(struct roar_cdrom * cdrom); int roar_cdrom_stop (struct roar_cdrom * cdrom); int roar_cdrom_play (struct roar_cdrom * cdrom, int track); #endif //ll ����������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/client.h��������������������������������������������������������0000644�0001750�0001750�00000004401�12264733456�017176� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//client.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROACLIENT_H_ #define _LIBROACLIENT_H_ #include "libroar.h" #define ROAR_CLIENT(x) ((struct roar_client*)(x)) struct roar_client { int fh; /* controll connection */ // int last_stream; /* id of the last stream created */ char name[ROAR_BUFFER_NAME]; int pid; int uid; int gid; int execed; int streams[ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT]; struct roar_acl_target * acl; int proto; int byteorder; struct roar_nnode nnode; }; int roar_client_new (struct roar_client * client); int roar_client_set_fh (struct roar_client * client, int fh); int roar_client_set_proto(struct roar_client * client, int proto, int byteorder); int roar_client_pass (struct roar_connection * con, struct roar_client * client, uint16_t flags); int roar_client_exec (struct roar_connection * con, struct roar_client * client, uint16_t flags); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/config.h��������������������������������������������������������0000644�0001750�0001750�00000016056�12264733456�017176� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//config.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARCONFIG_H_ #define _LIBROARCONFIG_H_ #include "libroar.h" struct roar_connection; // WorkAroundS: #define ROAR_LIBROAR_CONFIG_WAS_NONE 0x00 #define ROAR_LIBROAR_CONFIG_WAS_USE_EXECED 0x01 #define ROAR_LIBROAR_CONFIG_WAS_NO_SLP 0x02 #define ROAR_LIBROAR_CONFIG_PSET_Q 0x0001 #define ROAR_LIBROAR_CONFIG_PSET_COMPLEXITY 0x0002 #define ROAR_LIBROAR_CONFIG_PSET_DTX 0x0004 #define ROAR_LIBROAR_CONFIG_PSET_MAX_CC 0x0008 #define ROAR_LIBROAR_CONFIG_PSET_ABR 0x0010 /* need to implement */ #define ROAR_LIBROAR_CONFIG_PSET_VAD 0x0020 /* need to implement */ #define ROAR_LIBROAR_CONFIG_PSET_AGC 0x0040 /* need to implement */ #define ROAR_LIBROAR_CONFIG_PSET_DENOISE 0x0080 /* need to implement */ #define ROAR_LIBROAR_CONFIG_PSET_VBR 0x0100 #define ROAR_LIBROAR_CONFIG_PSET_MODE 0x0200 #define ROAR_LIBROAR_CONFIG_MODE_NB ROAR_SPEEX_MODE_NB #define ROAR_LIBROAR_CONFIG_MODE_WB ROAR_SPEEX_MODE_WB #define ROAR_LIBROAR_CONFIG_MODE_UWB ROAR_SPEEX_MODE_UWB // mode of operation: enum roar_libroar_config_opmode { ROAR_LIBROAR_CONFIG_OPMODE_NORMAL = 0, #define ROAR_LIBROAR_CONFIG_OPMODE_NORMAL ROAR_LIBROAR_CONFIG_OPMODE_NORMAL ROAR_LIBROAR_CONFIG_OPMODE_FUNNY = 1, #define ROAR_LIBROAR_CONFIG_OPMODE_FUNNY ROAR_LIBROAR_CONFIG_OPMODE_FUNNY ROAR_LIBROAR_CONFIG_OPMODE_MS = 2, #define ROAR_LIBROAR_CONFIG_OPMODE_MS ROAR_LIBROAR_CONFIG_OPMODE_MS }; struct roar_libroar_forkapi { int (*prefork)(void ** context, void * userdata); pid_t (*fork )(void ** context, void * userdata); int (*failed )(void ** context, void * userdata); int (*parent )(void ** context, void * userdata, pid_t child); int (*child )(void ** context, void * userdata); void * userdata; }; struct roar_libroar_memmgrapi { void * (*calloc) (void * userdata, size_t nmemb, size_t size); void * (*malloc) (void * userdata, size_t size); int (*free) (void * userdata, void * ptr); void * (*realloc) (void * userdata, void * ptr, size_t size); int (*reset) (void * userdata); ssize_t (*sizeofbuf)(void * userdata, void * ptr); // TODO: Memmory locking is not yet supported this way. int (*mlock) (void * userdata, const void * addr, size_t len); int (*munlock) (void * userdata, const void * addr, size_t len); int (*mlockall) (void * userdata, int flags); int (*munlockall) (void * userdata); void * userdata; }; struct roar_libroar_config_codec { uint32_t codec; // Codec ID // parameters which are set: unsigned int para_set; // the folloing ints are 256 times there correct value // to emulate a .8 bit fixed point float. int q; int complexity; // currectly bools: int dtx; int vbr; // sizes: size_t max_cc; // enums: int mode; }; struct roar_libroar_config { struct { int workarounds; } workaround; const char * server; struct { int sysio; int obsolete; } warnings; struct { size_t num; struct roar_libroar_config_codec * codec; } codecs; struct roar_audio_info info; char * authfile; char * serversfile; struct { char * display; } x11; size_t nowarncounter; #ifdef ROAR_SUPPORT_TRAP enum roar_trap_policy trap_policy; #endif enum roar_libroar_config_opmode opmode; const struct roar_libroar_forkapi * forkapi; struct roar_vio_calls * (*connect_internal)(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout); char * daemonimage; int serverflags; int protocolversion; }; struct roar_libroar_config * roar_libroar_get_config_ptr(void) _LIBROAR_ATTR_USE_RESULT; struct roar_libroar_config * roar_libroar_get_config(void) _LIBROAR_ATTR_USE_RESULT; int roar_libroar_reset_config(void); int roar_libroar_config_parse(char * txt, char * delm) _LIBROAR_ATTR_NONNULL(1); struct roar_libroar_config_codec * roar_libroar_config_codec_get(int32_t codec, int create); int roar_libroar_set_server(const char * server); const char * roar_libroar_get_server(void) _LIBROAR_ATTR_USE_RESULT; int roar_libroar_set_forkapi(const struct roar_libroar_forkapi * api); int roar_libroar_set_memmgrapi(const struct roar_libroar_memmgrapi * api); // implemented in memmgr.c. int roar_libroar_set_connect_internal(struct roar_vio_calls * (*func)(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout)); void roar_libroar_nowarn(void); void roar_libroar_warn(void); #define roar_libroar_iswarn(cfg) (((cfg) == NULL ? roar_libroar_get_config_ptr() : (cfg))->nowarncounter ? 0 : 1) // get a buffer to a system local path (prefix). // name is the symbolic name of the path, e.g. "prefix-lib". // null_as_universal tells of NULL is considered as "universal". // if not set NULL is considered 'do not add product path, give root prefix'. // product is the name of the product in standard "product <id/vendor>" format. // provider is the "<id/vendor>" format. If NULL this is ignored. // Returns buffer which needs to be freed with roar_mm_free(). // Not all paths support product/provider part. If not supported they are ignored. char * roar_libroar_get_path(const char * name, int null_as_universal, const char * product, const char * provider) _LIBROAR_ATTR_USE_RESULT; // This is similar roar_libroar_get_path() with the following diffrences: // * No product, provider or universal attribute can be passed. // The result is as if they were 0, NULL, NULL. // * The returned buffer is some read-only memory which does not need to be // freed. const char * roar_libroar_get_path_static(const char * name); // list all known paths: ssize_t roar_libroar_list_path(const char ** list, size_t len, size_t offset) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/crc.h�����������������������������������������������������������0000644�0001750�0001750�00000004137�12264733456�016475� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//crc.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARCRC_H_ #define _LIBROARCRC_H_ #include "libroar.h" uint32_t roar_crc24_add(uint32_t state, const void * data, size_t len); #define roar_crc24_init() roar_crc24_add(0, NULL, 0) uint32_t roar_adler32_add(uint32_t state, const void * data, size_t len); #define roar_adler32_init() roar_adler32_add(0, NULL, 0) int roar_hash_crc24_init(void * state); int roar_hash_crc24_digest(void * state, void * digest, size_t * len); int roar_hash_crc24_proc(void * state, const void * data, size_t len); int roar_hash_adler32_init(void * state); int roar_hash_adler32_digest(void * state, void * digest, size_t * len); int roar_hash_adler32_proc(void * state, const void * data, size_t len); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/crypto.h��������������������������������������������������������0000644�0001750�0001750�00000003020�12264733456�017234� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//crypto.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARCRYPTO_H_ #define _LIBROARCRYPTO_H_ #include "libroar.h" int roar_crypto_init (void); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/ctl.h�����������������������������������������������������������0000644�0001750�0001750�00000011452�12264733457�016507� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ctl.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARCTL_H_ #define _LIBROARCTL_H_ #include "libroar.h" #define _LIBROAR_CTL_STDATTRS _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL int roar_get_clientid (struct roar_connection * con) _LIBROAR_CTL_STDATTRS; int roar_get_standby (struct roar_connection * con) _LIBROAR_CTL_STDATTRS; int roar_set_standby (struct roar_connection * con, int state) _LIBROAR_CTL_STDATTRS; int roar_terminate (struct roar_connection * con, int terminate) _LIBROAR_CTL_STDATTRS; int roar_server_oinfo (struct roar_connection * con, struct roar_stream * s, int dir) _LIBROAR_CTL_STDATTRS; int roar_list (struct roar_connection * con, int * items, int max, int cmd) _LIBROAR_CTL_STDATTRS; int roar_list_filtered(struct roar_connection * con, int * items, int max, int cmd, unsigned char filter, unsigned char cmp, uint32_t id) _LIBROAR_CTL_STDATTRS; /* int roar_list_clients (struct roar_connection * con, int * clients, int max); int roar_list_streams (struct roar_connection * con, int * streams, int max); */ #define roar_list_clients(c,i,m) roar_list((c),(i),(m),ROAR_CMD_LIST_CLIENTS) #define roar_list_streams(c,i,m) roar_list((c),(i),(m),ROAR_CMD_LIST_STREAMS) int roar_get_client (struct roar_connection * con, struct roar_client * client, int id) _LIBROAR_CTL_STDATTRS; int roar_get_stream (struct roar_connection * con, struct roar_stream * stream, int id) _LIBROAR_CTL_STDATTRS; int roar_kick (struct roar_connection * con, int type, int id) _LIBROAR_ATTR_NONNULL_ALL; int roar_set_vol (struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int channels, int mode) _LIBROAR_CTL_STDATTRS; int roar_get_vol (struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int * channels) _LIBROAR_CTL_STDATTRS; // filter... int roar_ctl_f2m (struct roar_message * m, unsigned char filter, unsigned char cmp, uint32_t id); int roar_ctl_m2f (struct roar_message * m, unsigned char * filter, unsigned char * cmp, uint32_t * id); #define roar_ctl_f2m_any(m) roar_ctl_f2m((m), ROAR_CTL_FILTER_ANY, ROAR_CTL_FILTER_ANY, ROAR_CTL_FILTER_ANY) int roar_filter_match (const unsigned cmp, const uint32_t a, const uint32_t b) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; // int array int roar_ctl_ia2m (struct roar_message * m, int * data, size_t len); int roar_ctl_m2ia (struct roar_message * m, int * data, size_t len); // client int roar_ctl_c2m (struct roar_message * m, struct roar_client * c); int roar_ctl_m2c (struct roar_message * m, struct roar_client * c); int roar_ctl_c2m2 (struct roar_message * m, struct roar_client * c, void ** data); int roar_ctl_m2c2 (struct roar_message * m, struct roar_client * c, void * data); int roar_str2proto (const char * proto) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; const char * roar_proto2str (const int proto) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; int roar_str2byteorder (const char * byteorder) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; const char * roar_byteorder2str (const int byteorder) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; int roar_str2ot (const char * ot) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; const char * roar_ot2str (const int ot) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; int roar_conv_volume (struct roar_mixer_settings * dst, struct roar_mixer_settings * src, int dstchans, int srcchans) _LIBROAR_CTL_STDATTRS; #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/debug.h���������������������������������������������������������0000644�0001750�0001750�00000005705�12264733457�017017� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//debug.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDEBUG_H_ #define _LIBROARDEBUG_H_ #include "libroar.h" #define ROAR_WARNING_NEVER 0 #define ROAR_WARNING_ONCE 1 #define ROAR_WARNING_ALWAYS 2 #define ROAR_DEBUG_TYPE_ERROR 1 #define ROAR_DEBUG_TYPE_WARNING 2 #define ROAR_DEBUG_TYPE_INFO 3 #define ROAR_DEBUG_TYPE_DEBUG 4 #define ROAR_DEBUG_MODE_SYSIO 0 #define ROAR_DEBUG_MODE_VIO 1 #define ROAR_DEBUG_MODE_SYSLOG 2 #if 1 #define roar_debug_warn_sysio(f,n,i) roar_debug_warn_sysio_real((f),(n),(i)) #define roar_debug_warn_obsolete(f,n,i) roar_debug_warn_obsolete_real((f),(n),(i)) #else #define roar_debug_warn_sysio(f,n,i) #define roar_debug_warn_obsolete(f,n,i) #endif void roar_debug_warn_sysio_real (char * func, char * newfunc, char * info); void roar_debug_warn_obsolete_real(char * func, char * newfunc, char * info); void roar_debug_bin_obsolete(const char * progname, const char * newprog, const char * info); void roar_debug_option_obsolete(const char * progname, const char * option, const char * newopt, const char * info); // Error handle: struct roar_vio_calls; // will be declared later in vio.h void roar_debug_set_stderr_fh(int fh); void roar_debug_set_stderr_vio(struct roar_vio_calls * vio); void roar_debug_set_stderr_mode(int mode); struct roar_vio_calls * roar_debug_get_stderr(void); void roar_debug_msg_simple(const char *format, ...) _LIBROAR_ATTR_PRINTF(1, 2); void roar_debug_msg(int type, unsigned long int line, const char * file, const char * prefix, const char * format, ...) _LIBROAR_ATTR_PRINTF(5, 6); #endif //ll �����������������������������������������������������������roaraudio-1.0beta11/include/libroar/display.h�������������������������������������������������������0000644�0001750�0001750�00000003160�12264733457�017367� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//display.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDISPLAY_H_ #define _LIBROARDISPLAY_H_ #include "libroar.h" #define ROAR_DISPLAY_TYPE_NONE 0 #define ROAR_DISPLAY_TYPE_X11 1 struct roar_display_info { int type; }; #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/enumdev.h�������������������������������������������������������0000644�0001750�0001750�00000006445�12264733457�017376� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//enumdev.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARENUMDEV_H_ #define _LIBROARENUMDEV_H_ #include "libroar.h" #define ROAR_ENUM_FLAG_NONE 0x0000 /* no flags set */ #define ROAR_ENUM_FLAG_DESC 0x0001 /* ask for server description 1 */ #define ROAR_ENUM_FLAG_LOCATION 0x0002 /* ask for server location 1 */ #define ROAR_ENUM_FLAG_NONBLOCK 0x0004 /* do not block */ #define ROAR_ENUM_FLAG_HARDNONBLOCK 0x0008 /* do even less block than NONBLOCK */ #define ROAR_ENUM_FLAG_LOCALONLY 0x0010 /* only list local servers */ /* * 1 = This is a request. The result may include or not include the data anyway. * This is only so the lib does not need to spend extra work when data is not needed. */ struct roar_server { const char * server; const char * description; const char * location; }; struct roar_mixer { const int dir; //... }; /* Get a list of possible devices * * This function returns a list of possible device names. * The list is for suggestions in GUIs and simular. * A implementation SHOULD (VERY, VERY RECOMMENDED) have a freeform * input so the user can enter any server address. * * The list returned is a array of struct roar_server elements. * The final element has the member server set to NULL. * This element represents the default server (libroar will try to find * a server on it's own). * */ struct roar_server * roar_enum_servers(int flags, int dir, int socktype); /* Free the server list */ int roar_enum_servers_free(struct roar_server * servs); /* Return the number of elements in the server list * * This function is a optimized way to find out how may entry are in the server list. * However you should not call this too often and avoid needing to know the total at all. * Write software in a way that it tests for the server == NULL condition. */ ssize_t roar_enum_servers_num(struct roar_server * servs); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/env.h�����������������������������������������������������������0000644�0001750�0001750�00000003533�12264733460�016510� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//env.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARENV_H_ #define _LIBROARENV_H_ #include "libroar.h" int roar_env_set(struct roar_keyval * keyval); const char * roar_env_get(const char * key) _LIBROAR_ATTR_USE_RESULT; const char * roar_env_get_home(int level) _LIBROAR_ATTR_USE_RESULT; int roar_env_get_home_r(int level, char * str, size_t len) _LIBROAR_ATTR_USE_RESULT; int roar_env_render_path_r(char * out, size_t len, const char * inpath) _LIBROAR_ATTR_USE_RESULT; #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/error.h���������������������������������������������������������0000644�0001750�0001750�00000011226�12264733460�017047� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//error.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARERROR_H_ #define _LIBROARERROR_H_ #include "libroar.h" struct roar_message; enum roar_error_type { ROAR_ERROR_TYPE_ROARAUDIO = 0, ROAR_ERROR_TYPE_ERRNO, ROAR_ERROR_TYPE_WINSOCK, ROAR_ERROR_TYPE_HERROR, ROAR_ERROR_TYPE_YIFF, ROAR_ERROR_TYPE_APPLICATION, ROAR_ERROR_TYPE_HTTP, ROAR_ERROR_TYPE_EAI /* getaddrinfo() and friends */ }; /* Off Size (Byte) | | /- Name 0 1 Version 1 1 Cmd 2 1 RA Errno 3 1 RA SubErrno 4 2 Portable Errno 6 2 Flags (8 0 Datalen) 8 N Data */ struct roar_error_frame { int version; int cmd; int ra_errno; int ra_suberrno; int p_errno; uint16_t flags; size_t datalen; void * data; }; struct roar_error_state { size_t refc; int libroar_error; // roar_error int system_error; // errno #ifdef ROAR_TARGET_WIN32 int winsock_error; // WSAGetLastError(), WSASetLastError() #endif #ifdef ROAR_HAVE_VAR_H_ERRNO int syssock_herror; // h_errno #endif #ifdef __YIFF__ yiffc_error_t yiffc_error; // yiffc_error #endif }; struct roar_error_frame * roar_err_errorframe(void); int roar_err_init(struct roar_error_frame * frame); void * roar_err_buildmsg(struct roar_message * mes, void ** data, struct roar_error_frame * frame); int roar_err_parsemsg(struct roar_message * mes, void * data, struct roar_error_frame * frame); #define roar_error (*roar_errno2()) int * roar_errno2(void); // clear RoarAudio's error value void roar_err_clear(void); // clear system's error value (errno) void roar_err_clear_errno(void); // clear all error values (to be used before calling roar_err_update()) void roar_err_clear_all(void); // syncs RoarAudio's and system's error values void roar_err_update(void); // test of system's error value is set to 'no error' int roar_err_is_errno_clear(void); // set RoarAudio's error value void roar_err_set(const int error); // sync RoarAudio's error value with the value from the system void roar_err_from_errno(void); // sync systen's error value with the value from RoarAudio void roar_err_to_errno(void); // Convert error codes between diffrent representations. // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_convert(int * out, const enum roar_error_type outtype, const int in, const enum roar_error_type intype); // Outputs a default error for the given type. // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_get_default_error(int * out, const enum roar_error_type type); // Resets the stored state to 'no error' state. This can be used // to init the state. int roar_err_initstore(struct roar_error_state * state); // store a error state (both libroar and system) // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_store(struct roar_error_state * state); // restore error state to values at time of call to roar_err_store() // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_restore(struct roar_error_state * state); // Return a string descriping the error const char * roar_error2str(const int error); // Error string looking like a read only variable. #define roar_errorstring (roar_error2str(roar_error)) #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/file.h����������������������������������������������������������0000644�0001750�0001750�00000003237�12264733460�016640� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//file.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARFILE_H_ #define _LIBROARFILE_H_ #include "libroar.h" #ifdef ROAR_HAVE_LINUX_SENDFILE #include <sys/sendfile.h> #endif int roar_file_codecdetect(const char * buf, const int len); const char * roar_cdromdevice (void); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/hash.h����������������������������������������������������������0000644�0001750�0001750�00000011104�12264733460�016634� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//hash.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARHASH_H_ #define _LIBROARHASH_H_ #include "libroar.h" typedef uint_least32_t roar_hash_t; // the hashtypes: #define ROAR_HT_NONE ((roar_hash_t)0UL) #define ROAR_HT_MD5 ((roar_hash_t)1UL) #define ROAR_HT_SHA1 ((roar_hash_t)2UL) #define ROAR_HT_RIPEMD160 ((roar_hash_t)3UL) #define ROAR_HT_MD2 ((roar_hash_t)5UL) #define ROAR_HT_TIGER ((roar_hash_t)6UL) #define ROAR_HT_HAVAL ((roar_hash_t)7UL) #define ROAR_HT_SHA256 ((roar_hash_t)8UL) #define ROAR_HT_SHA384 ((roar_hash_t)9UL) #define ROAR_HT_SHA512 ((roar_hash_t)10UL) #define ROAR_HT_SHA224 ((roar_hash_t)11UL) #define ROAR_HT_MD4 ((roar_hash_t)301UL) #define ROAR_HT_CRC32 ((roar_hash_t)302UL) #define ROAR_HT_RFC1510 ((roar_hash_t)303UL) #define ROAR_HT_RFC2440 ((roar_hash_t)304UL) #define ROAR_HT_WHIRLPOOL ((roar_hash_t)305UL) #define ROAR_HT_UUID ((roar_hash_t)70000UL) #define ROAR_HT_GTN8 ((roar_hash_t)70001UL) #define ROAR_HT_GTN16 ((roar_hash_t)70002UL) #define ROAR_HT_GTN32 ((roar_hash_t)70004UL) #define ROAR_HT_GTN64 ((roar_hash_t)70008UL) #define ROAR_HT_CLIENTID ((roar_hash_t)71001UL) #define ROAR_HT_STREAMID ((roar_hash_t)71002UL) #define ROAR_HT_SOURCEID ((roar_hash_t)71003UL) #define ROAR_HT_SAMPLEID ((roar_hash_t)71004UL) #define ROAR_HT_MIXERID ((roar_hash_t)71005UL) #define ROAR_HT_BRIDGEID ((roar_hash_t)71006UL) #define ROAR_HT_LISTENID ((roar_hash_t)71007UL) #define ROAR_HT_ACTIONID ((roar_hash_t)71008UL) #define ROAR_HT_MSGQUEUEID ((roar_hash_t)71009UL) #define ROAR_HT_MSGBUSID ((roar_hash_t)71010UL) #define ROAR_HT_GTIN8 ((roar_hash_t)72001UL) #define ROAR_HT_GTIN13 ((roar_hash_t)72002UL) #define ROAR_HT_ISBN10 ((roar_hash_t)72003UL) #define ROAR_HT_ISBN13 ROAR_HT_GTIN13 #define ROAR_HT_ADLER32 ((roar_hash_t)73001UL) struct roar_hash_cmds { roar_hash_t algo; ssize_t statelen; ssize_t blocksize; int (*init)(void * state); int (*uninit)(void * state); int (*digest)(void * state, void * digest, size_t * len); int (*proc_block)(void * state, const void * block); int (*proc)(void * state, const void * data, size_t len); }; const char * roar_ht2str (const roar_hash_t ht); roar_hash_t roar_str2ht (const char * ht); ssize_t roar_ht_digestlen (const roar_hash_t ht); ssize_t roar_hash_digest2str(char * out, size_t outlen, void * digest, size_t digestlen, roar_hash_t ht); int roar_ht_is_supported(const roar_hash_t ht); struct roar_hash_state; struct roar_hash_state * roar_hash_new(roar_hash_t algo); int roar_hash_free(struct roar_hash_state * state); int roar_hash_digest(struct roar_hash_state * state, void * digest, size_t * len); int roar_hash_proc(struct roar_hash_state * state, const void * data, size_t len); int roar_hash_buffer(void * digest, const void * data, size_t datalen, roar_hash_t algo); int roar_hash_salted_buffer(void * digest, const void * data, size_t datalen, roar_hash_t algo, const void * salt, size_t saltlen); // 'forwardings' for hashes without own header: struct roar_hash_sha1 { uint32_t state[5]; uint64_t count; size_t in_buffer; char buffer[64]; int is_final; }; #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/hash_tiger.h����������������������������������������������������0000644�0001750�0001750�00000005127�12264733461�020037� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//hash_tiger.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARHASH_TIGER_H_ #define _LIBROARHASH_TIGER_H_ #include "libroar.h" struct roar_hash_tiger { uint64_t a, b, c; char inbuf[64]; size_t inlen; size_t blocks; int is_final; }; // init and deinit functions: int roar_hash_tiger_init(struct roar_hash_tiger * state); int roar_hash_tiger_uninit(struct roar_hash_tiger * state); // functions needed for string internal state: int roar_hash_tiger_init_from_pstate(struct roar_hash_tiger * state, void * oldstate); int roar_hash_tiger_to_pstate(struct roar_hash_tiger * state, void * newstate, size_t * len); ssize_t roar_hash_tiger_statelen(struct roar_hash_tiger * state); // finalize, should not be called directly: int roar_hash_tiger_finalize(struct roar_hash_tiger * state); // finalize and get final digest: int roar_hash_tiger_get_digest(struct roar_hash_tiger * state, void * digest, size_t * len); // optimized functions to process fixed size data blocks: int roar_hash_tiger_proc_block(struct roar_hash_tiger * state, void * block); ssize_t roar_hash_tiger_blocklen(struct roar_hash_tiger * state); // normal function to process data: int roar_hash_tiger_proc(struct roar_hash_tiger * state, void * data, size_t len); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/keyval.h��������������������������������������������������������0000644�0001750�0001750�00000004205�12264733461�017211� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//keyval.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARKEYVAL_H_ #define _LIBROARKEYVAL_H_ #include "libroar.h" struct roar_keyval { char * key; char * value; }; struct roar_keyval * roar_keyval_lookup (struct roar_keyval * kv, const char * key, ssize_t len, int casesens); /* Split string into kv array. * Array needs to be freed with roar_mm_free(). * String is not copied and destroyed by splitting but not freed. * fdel is list of seperator chars between kv-pairs. * kdel is list of seperator chars between keys and values. */ ssize_t roar_keyval_split (struct roar_keyval ** kv, char * str, const char * fdel, const char * kdel, int quotes); void * roar_keyval_copy(struct roar_keyval ** copy, const struct roar_keyval * src, ssize_t len); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/kstore.h��������������������������������������������������������0000644�0001750�0001750�00000005021�12264733461�017222� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//kstore.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARKSTORE_H_ #define _LIBROARKSTORE_H_ #include "libroar.h" struct roar_kstore; struct roar_kstore * roar_kstore_new(ssize_t len, int (*ref)(void *), int (*unref)(void *), const char * (*get_key)(void *)); int roar_kstore_ref(struct roar_kstore * store); int roar_kstore_unref(struct roar_kstore * store); int roar_kstore_add(struct roar_kstore * store, void * obj, const char * key); void * roar_kstore_get(struct roar_kstore * store, const char * key); int roar_kstore_delete(struct roar_kstore * store, const char * key); const char * roar_kstore_name(struct roar_kstore * store, const void * obj); // aliases: #define roar_kstore_new_connection(len) roar_kstore_new((len), \ (int (*)(void*))roar_connectionref, \ (int (*)(void*))roar_connectionunref, \ (const char * (*)(void*))roar_get_connection_server) #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/libroar.h�������������������������������������������������������0000644�0001750�0001750�00000017336�12264733462�017362� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroar.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAR_H_ #define _LIBROAR_H_ //#define ROAR_DBG_PREFIX "libroar" #include <roaraudio.h> // Parameter passing: #include <stdarg.h> // Process control: #ifdef ROAR_HAVE_WAIT #include <sys/wait.h> #endif // File handle control: #ifdef ROAR_HAVE_H_FCNTL #include <fcntl.h> #endif // Signal handling: #ifdef ROAR_HAVE_H_SIGNAL #include <signal.h> #endif // Logging: #ifdef ROAR_HAVE_SYSLOG #include <syslog.h> #endif // Network: #ifdef ROAR_TARGET_WIN32 #include <winsock2.h> #elif defined(ROAR_HAVE_BSDSOCKETS) #ifdef ROAR_HAVE_H_SYS_SOCKET #include <sys/socket.h> #endif #ifdef ROAR_HAVE_IPV4 #include <netinet/in_systm.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #endif #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) #include <arpa/inet.h> #endif #include <sys/uio.h> #ifdef ROAR_HAVE_UNIX #include <sys/un.h> #endif #ifdef ROAR_HAVE_LIBDNET #include <netdnet/dn.h> #include <netdnet/dnetdb.h> #endif #ifdef ROAR_HAVE_IPX #include <netipx/ipx.h> #endif #endif /* ROAR_HAVE_BSDSOCKETS */ #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) #include <netdb.h> #endif // OpenSLP (autoconf): #ifdef ROAR_HAVE_LIBSLP #include <slp.h> #ifdef ROAR_HAVE_H_SYS_TIME #include <sys/time.h> #endif #endif // Time related: #ifdef ROAR_HAVE_H_TIME #include <time.h> #endif // Dynamic loader: #if defined(ROAR_HAVE_H_DLFCN) #include <dlfcn.h> #endif // X11: #ifdef ROAR_HAVE_LIBX11 #include <X11/Xlib.h> #include <X11/Xatom.h> #endif #include "roarfeatures.h" #include "error.h" #include "trap.h" #include "config.h" #include "roarfloat.h" #include "crc.h" #include "base64.h" #include "keyval.h" #include "uuid.h" #include "env.h" #include "roardl.h" #include "plugincontainer.h" #include "services.h" #include "debug.h" #include "memmgr.h" #include "stack.h" #include "buffer.h" #include "crypto.h" #include "random.h" #include "hash.h" #include "hash_tiger.h" #include "nnode.h" #include "vio_ctl.h" #include "vio.h" #include "vio_buffer.h" #include "vio_buffer_store.h" #include "vio_cmd.h" #include "vio_zlib.h" #include "vio_ops.h" #include "vio_string.h" #include "vio_magic.h" #include "vio_bio.h" #include "vio_stdio.h" #include "vio_stack.h" #include "vio_jumbo.h" #include "vio_pipe.h" #include "vio_socket.h" #include "vio_winsock.h" #include "vio_proto.h" #include "vio_proxy.h" #include "vio_rtp.h" #include "vio_select.h" // dstr needs to have access to all other VIOs, so it must be included last #include "vio_dstr.h" #include "vio_tantalos.h" #include "vio_stdvios.h" #include "vio_misc.h" #include "client.h" #include "basic.h" #include "serverinfo.h" #include "stream.h" #include "simple.h" #include "cdrom.h" #include "authfile.h" #include "auth.h" #include "socket.h" #include "ctl.h" #include "caps.h" #include "roartime.h" #include "meta.h" #include "file.h" #include "acl.h" #include "pinentry.h" #include "sshaskpass.h" #include "passwordapi.h" #include "roarslp.h" #include "display.h" #include "roarx11.h" #include "beep.h" #include "ltm.h" #include "vs.h" #include "enumdev.h" #include "notify.h" #include "notify_proxy.h" #include "asyncctl.h" #include "kstore.h" #include "watchdog.h" #include "scheduler.h" // some basic macros: #define ROAR_MAX2(a,b) ((a) > (b) ? (a) : (b)) #define ROAR_MIN2(a,b) ((a) < (b) ? (a) : (b)) #define ROAR_MAX3(a,b,c) ROAR_MAX2(ROAR_MAX2(a,b),c) #define ROAR_MIN3(a,b,c) ROAR_MIN2(ROAR_MIN2(a,b),c) #define ROAR_MAX4(a,b,c,d) ROAR_MAX2(ROAR_MAX2(a,b),ROAR_MAX2(c,d)) #define ROAR_MIN4(a,b,c,d) ROAR_MIN2(ROAR_MIN2(a,b),ROAR_MIN2(c,d)) #define ROAR_MAX ROAR_MAX2 #define ROAR_MIN ROAR_MIN2 #define ROAR_CKHAVEARGS(x) if ( (i + (x)) >= argc ) { \ ROAR_ERR("Option %s requires more arguments. See --help for more details.", k); \ return 70; \ } int roar_usleep(uint_least32_t t); int roar_sleep(int t); pid_t roar_fork(const struct roar_libroar_forkapi * api); // call this function after we fork/exec()ed or similar. enum roar_reset { ROAR_RESET_UNKNOWN = -1, #define ROAR_RESET_UNKNOWN ROAR_RESET_UNKNOWN ROAR_RESET_NONE = 0, #define ROAR_RESET_NONE ROAR_RESET_NONE ROAR_RESET_ON_FORK = 1, #define ROAR_RESET_ON_FORK ROAR_RESET_ON_FORK ROAR_RESET_ON_EXIT = 2, #define ROAR_RESET_ON_EXIT ROAR_RESET_ON_EXIT ROAR_RESET_ON_PRE_EXEC = 3, #define ROAR_RESET_ON_PRE_EXEC ROAR_RESET_ON_PRE_EXEC ROAR_RESET_MEMORY = 0x81, #define ROAR_RESET_MEMORY ROAR_RESET_MEMORY ROAR_RESET_CONFIG = 0x82, #define ROAR_RESET_CONFIG ROAR_RESET_CONFIG ROAR_RESET_RANDOMPOOL = 0x84, #define ROAR_RESET_RANDOMPOOL ROAR_RESET_RANDOMPOOL ROAR_RESET_EOL = -2 #define ROAR_RESET_EOL ROAR_RESET_EOL }; int roar_reset(enum roar_reset what); // fatal probelms: enum roar_fatal_error { ROAR_FATAL_ERROR_NONE = 0, // ??? ROAR_FATAL_ERROR_UNKNOWN, // Unknown error #define ROAR_FATAL_ERROR_UNKNOWN ROAR_FATAL_ERROR_UNKNOWN ROAR_FATAL_ERROR_MEMORY_CORRUPTION, // some structure has been corrupted #define ROAR_FATAL_ERROR_MEMORY_CORRUPTION ROAR_FATAL_ERROR_MEMORY_CORRUPTION ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD, // memory was corruppted but no data has been harmed (yet) #define ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD ROAR_FATAL_ERROR_CPU_FAILURE, // CPU general CPU failure #define ROAR_FATAL_ERROR_CPU_FAILURE ROAR_FATAL_ERROR_CPU_FAILURE ROAR_FATAL_ERROR_CPU_FAILTURE = ROAR_FATAL_ERROR_CPU_FAILURE, ROAR_FATAL_ERROR_MEMORY_USED_AFTER_FREE, #define ROAR_FATAL_ERROR_MEMORY_USED_AFTER_FREE ROAR_FATAL_ERROR_MEMORY_USED_AFTER_FREE ROAR_FATAL_ERROR_MEMORY_DOUBLE_FREE, #define ROAR_FATAL_ERROR_MEMORY_DOUBLE_FREE ROAR_FATAL_ERROR_MEMORY_DOUBLE_FREE ROAR_FATAL_ERROR_WATCHDOG, #define ROAR_FATAL_ERROR_WATCHDOG ROAR_FATAL_ERROR_WATCHDOG ROAR_FATAL_ERROR_EOL }; #if __STDC_VERSION__ < 199901L #if __GNUC__ >= 2 #define __roar_func__ __FUNCTION__ #else #define __roar_func__ NULL #endif #else #define __roar_func__ __func__ #endif #define roar_panic(err,info) roar_panic_real((err), (info), __LINE__, __FILE__, ROAR_DBG_PREFIX, __roar_func__) void roar_panic_real(enum roar_fatal_error error, const char * info, unsigned long int line, const char * file, const char * prefix, const char * func); // version stuff: const char * roar_version_string(void); uint32_t roar_version_num(void); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/ltm.h�����������������������������������������������������������0000644�0001750�0001750�00000013747�12264733462�016526� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ltm.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illegal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARLTM_H_ #define _LIBROARLTM_H_ #include "libroar.h" // forward declaration for return type of roar_ltm_get(). // you must not access members directly. struct roar_ltm_result; /* Register streams for LTM. * Takes * - connection to server, * - used MT (monitoring type), * - used window, * - array of streams, * - length of the array of streams. * Returns -1 on error or 0 on no error. * * Registration is stacked. * This means that if you register a stream twice you need to unregister it twice. * This is because maybe clients may witch to use LTM and it would be bad * if the first client which disconnects would remove the LTM from the stream. */ int roar_ltm_register(struct roar_connection * con, int mt, int window, int * streams, size_t slen); /* Unregister streams from LTM. * This function works just like roar_ltm_register() just that it * unregisters the streams again. * * The set of streams you unregister in one stream does not need to be * the same as the set you registered. It is perfectly valid to just * unregister a subset. or a larger set of streams. * * The given mt must match. If it does not the behavior is undefined. * The server may refuse the request or just unregister the given bits. * you should not do this. * * you must not unregister streams which got deleted by the server. */ int roar_ltm_unregister(struct roar_connection * con, int mt, int window, int * streams, size_t slen); /* Read values for LTM from the server. * This function takes: * - The connection to the server, * - the monitoring types you request, * - the window you request data from, * - an array of streams you want data for, * - the length of the streams array, * - an old result of this function. * * It returns a pointer to an result object or NULL on error. * * The MT is allowed to not match the registered mt but must not * contain more bits than registered. In most causes this match * the registered MT. * * The window must match the window used then streams got registered. * * The list of streams must not match a single registration. * but all streams must be registered with at least the bits used in mt * set at registration. * * The old result is taken so this function does not need to always * allocate new memory. If the given result is as big as needed to store * the new result it is overwritten or freed and re-allocated if it is * too small. * If you do not have a old result set pass NULL. * * If you no longer need the result and will not call this function again * you must free the result with roar_ltm_freeres(). */ struct roar_ltm_result * roar_ltm_get(struct roar_connection * con, int mt, int window, int * streams, size_t slen, struct roar_ltm_result * oldresult); /* This function frees the result. * This may be defined as macro. Never call the function * this references as directly if this is a macro. */ #define roar_ltm_freeres(x) roar_mm_free((x)) /* Get number of streams which are included in a result. * returns -1 on error. */ int roar_ltm_get_numstreams(struct roar_ltm_result * res); /* Get the mt included in the given result. * returns -1 on error. */ int roar_ltm_get_mt(struct roar_ltm_result * res); /* Get the window included in the given result. * returns -1 on error. */ int roar_ltm_get_window(struct roar_ltm_result * res); /* Get the number of channels a stream in result has. * Takes the result and the index of the stream in the result. * The stream index is the index of the stream in the stream list * you provided to roar_ltm_get(). This is not the stream id. * * returns -1 on error. * * You must use this function to get the number of channels for a stream * and not any value you got on some other way. * This is because this function returns the value in the very moment in witch the * result set was collected in the server. */ int roar_ltm_get_numchans(struct roar_ltm_result * res, size_t streamidx); /* Extract a single value from the result. * Takes * - the result, * - the mt for which you ask, * - the index of the stream in the result and * - The channel you request a value for. * * returns -1 on error. * * The mt parameter must not have more than one bit set. * * The stream index is the index of the stream in the stream list * you provided to roar_ltm_get(). This is not the stream id. * * The channel is the channel number you ask data for. * it must not be bigger than one less what roar_ltm_get_numchans() returned. * (channels are counted from zero to N-1, not from 1 to N) */ int64_t roar_ltm_extract(struct roar_ltm_result * res, int mt, size_t streamidx, int channel); #endif //ll �������������������������roaraudio-1.0beta11/include/libroar/memmgr.h��������������������������������������������������������0000644�0001750�0001750�00000012237�12264733462�017207� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//memmgr.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARMEMMGR_H_ #define _LIBROARMEMMGR_H_ #include "libroar.h" #ifndef ROAR_USE_MEMMGR #if !defined(ROAR_HAVE_MALLOC) || !defined(ROAR_HAVE_CALLOC) || !defined(ROAR_HAVE_REALLOC) || !defined(ROAR_HAVE_FREE) #define ROAR_USE_MEMMGR #endif #endif #ifdef ROAR_USE_MEMMGR // those functions are currently not implemeted: int roar_mm_reset(void); ssize_t roar_mm_sizeof(void * buf); void * roar_mm_calloc(size_t nmemb, size_t size); void * roar_mm_malloc(size_t size); int roar_mm_free(void *ptr); void * roar_mm_realloc(void *ptr, size_t size); /* * TODO: we need some functions to control the pre-alloc * of memory. */ #else #define roar_mm_reset() (0) #define roar_mm_sizeof(ptr) ((ssize_t)-1) #define roar_mm_calloc(nmemb, size) calloc((nmemb), (size)) #define roar_mm_malloc(size) malloc((size)) #define roar_mm_free(ptr) free((ptr)) #define roar_mm_realloc(ptr, size) realloc((ptr), (size)) #endif // dummy function doing the same as roar_mm_free() but return void. // this should only be used in case a function pointer of this type is required. void roar_mm_free_retvoid(void *ptr); // dummy function doing the same as roar_mm_free() but does not return any error // or alter global error states. void roar_mm_free_noerror(void *ptr); // memory locking: #if defined(ROAR_HAVE_MLOCK) && defined(__linux__) #define roar_mm_mlock(addr, len) mlock((addr), (len)) #elif defined(ROAR_TARGET_MICROCONTROLLER) #define roar_mm_mlock(addr, len) 0 #else int roar_mm_mlock(const void *addr, size_t len); #endif #if defined(ROAR_HAVE_MUNLOCK) && defined(__linux__) #define roar_mm_munlock(addr, len) munlock((addr), (len)) #elif defined(ROAR_TARGET_MICROCONTROLLER) #define roar_mm_munlock(addr, len) 0 #else int roar_mm_munlock(const void *addr, size_t len); #endif #if defined(ROAR_HAVE_MLOCKALL) #define roar_mm_mlockall(flags) mlockall((flags)) #elif defined(ROAR_TARGET_MICROCONTROLLER) #define roar_mm_mlockall(flags) 0 #else #define roar_mm_mlockall(flags) (-1) #endif #if defined(ROAR_HAVE_MUNLOCKALL) #define roar_mm_munlockall() munlockall() #elif defined(ROAR_TARGET_MICROCONTROLLER) #define roar_mm_munlockall() 0 #else #define roar_mm_munlockall() (-1) #endif // for compatibility with old versions: #define ROAR_MLOCK _ROAR_MLOCK // aux functions: void * roar_mm_memdup(const void * s, size_t len); // string functions: #ifndef ROAR_HAVE_STRLEN ssize_t roar_mm_strlen(const char *s); #else #define roar_mm_strlen(str) strlen((str)) #endif ssize_t roar_mm_strnlen(const char *s, size_t maxlen); #if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRDUP) char * roar_mm_strdup(const char *s); #else #define roar_mm_strdup(str) strdup((str)) #endif char * roar_mm_strdup2(const char *s, const char *def); #if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRNDUP) char *roar_mm_strndup(const char *s, size_t n); #else #define roar_mm_strndup(str, size) strdup((str), (size)) #endif #ifndef ROAR_HAVE_STRLCPY ssize_t roar_mm_strlcpy(char *dst, const char *src, size_t size); #else #define roar_mm_strlcpy(dst,src,size) strlcpy((dst),(src),(size)) #endif #define roar_mm_strscpy(dst,src) roar_mm_strlcpy((dst),(src),sizeof((dst))) #ifndef ROAR_HAVE_STRLCAT ssize_t roar_mm_strlcat(char *dst, const char *src, size_t size); #else #define roar_mm_strlcat(dst,src,size) strlcat((dst),(src),(size)) #endif #define roar_mm_strscat(dst,src) roar_mm_strlcat((dst),(src),sizeof((dst))) #ifndef ROAR_HAVE_STRTOK_R char * roar_mm_strtok_r(char *str, const char *delim, char **saveptr); #else #define roar_mm_strtok_r(str,delim,saveptr) strtok_r((str),(delim),(saveptr)) #endif // Selector parsing. int roar_mm_strselcmp(const char *s1, const char *s2); ssize_t roar_mm_strseltok(const char *s1, char *s2, char ** tok, size_t toks); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/meta.h����������������������������������������������������������0000644�0001750�0001750�00000004172�12264733463�016651� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//meta.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARMETA_H_ #define _LIBROARMETA_H_ #include "libroar.h" int roar_stream_meta_set (struct roar_connection * con, struct roar_stream * s, int mode, struct roar_meta * meta); int roar_stream_meta_get (struct roar_connection * con, struct roar_stream * s, struct roar_meta * meta); int roar_stream_meta_list (struct roar_connection * con, struct roar_stream * s, int * types, size_t len); int roar_meta_free (struct roar_meta * meta); const char * roar_meta_strtype(const int type); int roar_meta_inttype(const char * type); const char * roar_meta_strgenre(const int genre); int roar_meta_intgenre(const char * genre); int roar_meta_parse_audioinfo(struct roar_audio_info * info, const char * str); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/nnode.h���������������������������������������������������������0000644�0001750�0001750�00000004566�12264733464�017036� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//nnode.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARNNODE_H_ #define _LIBROARNNODE_H_ #include "libroar.h" struct roar_nnode { int socktype; union { unsigned char inet4[4]; unsigned char inet6[16]; struct { int area; int node; } decnet; } addr; }; int roar_nnode_new (struct roar_nnode * nnode, int socktype); int roar_nnode_new_from_af(struct roar_nnode * nnode, int af); int roar_nnode_new_from_sockaddr(struct roar_nnode * nnode, struct sockaddr * addr, socklen_t len); int roar_nnode_new_from_fh(struct roar_nnode * nnode, int fh, int remote); int roar_nnode_free (struct roar_nnode * nnode); int roar_nnode_get_socktype (struct roar_nnode * nnode); int roar_nnode_to_str (struct roar_nnode * nnode, char * str, size_t len); int roar_nnode_from_blob (struct roar_nnode * nnode, void * blob, size_t * len); int roar_nnode_to_blob (struct roar_nnode * nnode, void * blob, size_t * len); int roar_nnode_cmp (struct roar_nnode * n0, struct roar_nnode * n1); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/notify.h��������������������������������������������������������0000644�0001750�0001750�00000006665�12264733464�017245� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//notify.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARNOTIFY_H_ #define _LIBROARNOTIFY_H_ #include "libroar.h" #define ROAR_EVENT_FLAG_NONE ROAR_EVENT_NETFLAG_NONE #define ROAR_EVENT_FLAG_NETTRANS ROAR_EVENT_NETFLAG_DATA #define ROAR_EVENT_FLAG_PROXYEVENT ROAR_EVENT_NETFLAG_PROXYEVENT struct roar_event { uint32_t flags; uint32_t event; uint32_t event_proxy; int emitter; int target; int target_type; int arg0; int arg1; void * arg2; ssize_t arg2_len; }; struct roar_subscriber; struct roar_notify_core; #define ROAR_EVENT_GET_TYPE(x) ((x) == NULL ? ROAR_NOTIFY_SPECIAL : ((x)->flags & ROAR_EVENT_FLAG_PROXYEVENT ? (x)->event_proxy : (x)->event)) struct roar_notify_core * roar_notify_core_new(ssize_t lists); int roar_notify_core_ref(struct roar_notify_core * core); int roar_notify_core_unref(struct roar_notify_core * core); #define roar_notify_core_free(x) roar_notify_core_unref((x)) int roar_notify_core_new_global(ssize_t lists); struct roar_notify_core * roar_notify_core_swap_global(struct roar_notify_core * core); int roar_notify_core_register_proxy(struct roar_notify_core * core, void (*cb)(struct roar_notify_core * core, struct roar_event * event, void * userdata), void * userdata); struct roar_subscriber * roar_notify_core_subscribe(struct roar_notify_core * core, struct roar_event * event, void (*cb)(struct roar_notify_core * core, struct roar_event * event, void * userdata), void * userdata); int roar_notify_core_unsubscribe(struct roar_notify_core * core, struct roar_subscriber * subscriber); int roar_notify_core_emit(struct roar_notify_core * core, struct roar_event * event); int roar_notify_core_emit_simple(uint32_t event, int emitter, int target, int target_type, int arg0, int arg1, void * arg2, ssize_t arg2_len); #define roar_notify_core_emit_snoargs(event,emitter,target,target_type) roar_notify_core_emit_simple((event),(emitter),(target),(target_type),-1,-1,NULL,0) int roar_event_to_blob(struct roar_event * event, void * blob, size_t * len); int roar_event_from_blob(struct roar_event * event, void * blob, size_t * len); #endif //ll ���������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/notify_proxy.h��������������������������������������������������0000644�0001750�0001750�00000003155�12264733464�020475� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//notify_proxy.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARNOTIFY_PROXY_H_ #define _LIBROARNOTIFY_PROXY_H_ #include "libroar.h" void roar_notify_proxy_std(struct roar_notify_core * core, struct roar_event * event, void * userdata); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/passwordapi.h���������������������������������������������������0000644�0001750�0001750�00000003132�12264733464�020253� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//passwordapi.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARPASSWORDAPI_H_ #define _LIBROARPASSWORDAPI_H_ #include "libroar.h" ssize_t roar_passwd_simple_ask_pw (char ** pw, char * prompt, const char * cachetoken); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/pinentry.h������������������������������������������������������0000644�0001750�0001750�00000005166�12264733465�017601� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//pinentry.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAR_PINENTRY_H_ #define _LIBROAR_PINENTRY_H_ #include "libroar.h" //pinentry.h struct roar_pinentry { int opened; pid_t pid; int in; int out; FILE * fin; }; int roar_pinentry_open (struct roar_pinentry * pe, int flags, const char * display, const char * tty, const char * term); int roar_pinentry_simple_open(struct roar_pinentry * pe); int roar_pinentry_close(struct roar_pinentry * pe); int roar_pinentry_send (struct roar_pinentry * pe, char * cmd, char * args); int roar_pinentry_recv (struct roar_pinentry * pe, char ** line, char ** opts); int roar_pinentry_req (struct roar_pinentry * pe, char * cmd, char * args, char ** line, char ** opts); int roar_pinentry_set_desc (struct roar_pinentry * pe, char * desc); int roar_pinentry_set_prompt(struct roar_pinentry * pe, char * prompt); int roar_pinentry_set_yes (struct roar_pinentry * pe, char * yes); int roar_pinentry_set_no (struct roar_pinentry * pe, char * no); int roar_pinentry_set (struct roar_pinentry * pe, char * obj, char * text); int roar_pinentry_getpin (struct roar_pinentry * pe, char ** pw, char * desc, char * prompt); int roar_pinentry_confirm (struct roar_pinentry * pe, char * desc, char * yes, char * no); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/plugincontainer.h�����������������������������������������������0000644�0001750�0001750�00000017602�12264733465�021130� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//plugincontainer.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARPLUGINCONTAINER_H_ #define _LIBROARPLUGINCONTAINER_H_ #include "libroar.h" struct roar_plugincontainer; struct roar_plugincontainer_callbacks { /* prefree() is called before the container is freed. */ int (*prefree)(struct roar_plugincontainer * cont, void ** userdata); /* freeuserdata() is called when the userdata needs to be freed. * This is the case then the container is freed. * It is not called when the current userdata is NULL. * If not set or userdata is still non-NULL after this call the userdata * is freed using roar_mm_free(). */ int (*freeuserdata)(struct roar_plugincontainer * cont, void ** userdata); /* freecontext() is called when the context needs to be freed. * It is not called when the current context is NULL. * If not set or context is still non-NULL after this call the context * is freed using roar_mm_free(). */ int (*freecontext)(struct roar_plugincontainer * cont, void ** context); /* preload() and postload() are called before and after a plugin is loaded. */ int (*preload) (struct roar_plugincontainer * cont, void ** context, const char * name, int flags, struct roar_dl_librarypara * para); int (*postload)(struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle, const char * name, int flags, struct roar_dl_librarypara * para); /* preunload() and postunload() are called before and after a plugin is unloaded. * Those functions are also called if the plugin was loaded but ra_init was not yet done or failed. */ int (*preunload) (struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle); int (*postunload)(struct roar_plugincontainer * cont, void ** context); /* prera_init() and postra_init() are called before and after a plugin is ra_init-ed. * This is also true if the plugin is ra_init-ed while being loaded. * Note the limits of roar_plugincontainer_ra_init() if this is used * with roar_plugincontainer_ra_init(). * postra_init() is also called in case the ra_init failed. */ int (*prera_init) (struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle, struct roar_dl_librarypara * para); int (*postra_init)(struct roar_plugincontainer * cont, void ** context, struct roar_dl_lhandle * lhandle, struct roar_dl_librarypara * para); }; struct roar_plugincontainer_plugininfo { /* The name of the plugin. */ const char * libname; /* The roardl's library handle. */ struct roar_dl_lhandle * handle; /* The number of librarys/plugins depending on this plugin. */ size_t rdepends; /* A pointer to the current user context. */ void ** context; }; /* Create a new plugin container. * Takes a default parameter set. */ struct roar_plugincontainer * roar_plugincontainer_new(struct roar_dl_librarypara * default_para); /* Create a new plugin container. * Takes host application's appname and abiversion. */ struct roar_plugincontainer * roar_plugincontainer_new_simple(const char * appname, const char * abiversion); // Increment the refrence counter. int roar_plugincontainer_ref(struct roar_plugincontainer * cont); /* Decrement the refrence counter. * Unloads all plugins and frees all resources when there are no refreneces left. */ int roar_plugincontainer_unref(struct roar_plugincontainer * cont); /* Set Autoappsched. * If set the INIT and FREE appsched events are send automatically. */ int roar_plugincontainer_set_autoappsched(struct roar_plugincontainer * cont, int val); /* Set callbacks. */ int roar_plugincontainer_set_callbacks(struct roar_plugincontainer * cont, const struct roar_plugincontainer_callbacks * callbacks); /* Set container's userdata. */ int roar_plugincontainer_set_userdata(struct roar_plugincontainer * cont, void * userdata); /* Get container's userdata. */ void * roar_plugincontainer_get_userdata(struct roar_plugincontainer * cont); /* Get a lhandle by name of the loaded plugin. */ struct roar_dl_lhandle * roar_plugincontainer_get_lhandle_by_name (struct roar_plugincontainer * cont, const char * name); /* Get infos about current state of plugin. */ struct roar_plugincontainer_plugininfo roar_plugincontainer_get_info_by_name (struct roar_plugincontainer * cont, const char * name); // plugin loading and unloading: // Load a plugin by name. int roar_plugincontainer_load (struct roar_plugincontainer * cont, const char * name, struct roar_dl_librarypara * para); /* Load a plugin by name with extra options. * This is for advanced applications only. * NOTE: Using this handle after the plugin has been unloaded from the * container results in undefind behavior. */ struct roar_dl_lhandle * roar_plugincontainer_load_lhandle (struct roar_plugincontainer * cont, const char * name, int flags, int ra_init, struct roar_dl_librarypara * para); /* Unload a plugin by name. * NOTE: The name here is from the plugin and may not match the name you load * the plugin with. */ int roar_plugincontainer_unload (struct roar_plugincontainer * cont, const char * name); /* Load a plugin by roardl handle. * This is for advanced applications only. */ int roar_plugincontainer_unload_lhandle (struct roar_plugincontainer * cont, struct roar_dl_lhandle * lhandle); /* Post ra_init plugins not yet inited. * NOTE: This uses the default para, * not the one given with roar_plugincontainer_load_lhandle(). * This is for advanced applications only. */ int roar_plugincontainer_ra_init (struct roar_plugincontainer * cont); // appsched: // Trigger an application schedule event on all plugins. int roar_plugincontainer_appsched_trigger(struct roar_plugincontainer * cont, enum roar_dl_appsched_trigger trigger); #endif //ll ������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/random.h��������������������������������������������������������0000644�0001750�0001750�00000004061�12264733465�017202� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//random.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARRANDOM_H_ #define _LIBROARRANDOM_H_ #include "libroar.h" #define ROAR_RANDOM_NONE 0 #define ROAR_RANDOM_VERY_WEAK 1 #define ROAR_RANDOM_WEAK 2 #define ROAR_RANDOM_NORMAL 3 #define ROAR_RANDOM_STRONG 4 #define ROAR_RANDOM_VERY_STRONG 5 #define ROAR_RANDOM_NONCE ROAR_RANDOM_VERY_WEAK int roar_random_gen_nonce(void * buffer, size_t len); int roar_random_salt_nonce (void * salt, size_t len); uint16_t roar_random_uint16(void); uint32_t roar_random_uint32(void); int roar_random_gen(void * buffer, size_t len, int quality); void * roar_random_genbuf(size_t len, int quality, int locked); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/roardl.h��������������������������������������������������������0000644�0001750�0001750�00000061345�12264733466�017216� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roardl.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARROARDL_H_ #define _LIBROARROARDL_H_ #include "libroar.h" #define ROAR_DL_FLAG_DEFAULTS -1 #define ROAR_DL_FLAG_PLUGIN -2 #define ROAR_DL_FLAG_NONE 0x0000 #define ROAR_DL_FLAG_STATIC 0x0001 /* plugins are linked statically -lfoo */ #define ROAR_DL_FLAG_LAZY 0x0002 #define ROAR_DL_FLAG_PLUGINPATH 0x0004 /* Use plugin search path */ #define ROAR_DL_HANDLE_DEFAULT ((struct roar_dl_lhandle*)(void*)0) #define ROAR_DL_HANDLE_NEXT ((struct roar_dl_lhandle*)(void*)1) #define ROAR_DL_HANDLE_LIBROAR ((struct roar_dl_lhandle*)(void*)2) #define ROAR_DL_HANDLE_APPLICATION ((struct roar_dl_lhandle*)(void*)3) #define ROAR_DL_HANDLE_LIB ((struct roar_dl_lhandle*)(void*)4) #define LIBROAR_DL_APPNAME "libroar " ROAR_VSTR_ROARAUDIO #define LIBROAR_DL_ABIVERSION "1.0beta9" #define ROAR_DL_FN_DSTR 0 /* VIO and DSTR drivers */ #define ROAR_DL_FN_CDRIVER 1 /* Client drivers, libroareio */ #define ROAR_DL_FN_TRANSCODER 2 /* Transcoder, libroardsp */ #define ROAR_DL_FN_DRIVER 3 /* Driver, roard? */ #define ROAR_DL_FN_SOURCE 4 /* Sources, roard? */ #define ROAR_DL_FN_FILTER 5 /* Filter, libroardsp */ #define ROAR_DL_FN_FF 6 /* file format??? */ #define ROAR_DL_FN_AUTH 7 /* Auth */ #define ROAR_DL_FN_BRIDGE 8 /* Bridges, roard? */ #define ROAR_DL_FN_ROARDSCHED 9 /* legacy, roard: Like appsched, but roard specific, old */ #define ROAR_DL_FN_APPSCHED 10 /* legacy: AppSched, old interface */ #define ROAR_DL_FN_PROTO 11 /* CPI, roard: Protocols */ #define ROAR_DL_FN_NOTIFY 12 /* ??? */ #define ROAR_DL_FN_INIT 13 /* global plugin instance init. should be avoided */ #define ROAR_DL_FN_REGFN 14 /* FN Registrations */ #define ROAR_DL_FN_APPLICATION 15 /* Application specific stuff */ #define ROAR_DL_FN_SERVICE 16 /* CSI: Services */ //#define ROAR_DL_FN_ 9 #define ROAR_DL_FN_MAX 24 #define ROAR_DL_LIBPARA_VERSION 1 #define ROAR_DL_LIBNAME_VERSION 0 #define ROAR_DL_LIBINST_VERSION 1 #define ROAR_DL_LIBDEP_VERSION 0 #define ROAR_DL_PLUGIN(lib) struct roar_dl_libraryinst * \ _##lib##_roaraudio_library_init(struct roar_dl_librarypara * para); \ struct roar_dl_libraryinst * \ _roaraudio_library_init(struct roar_dl_librarypara * para) { \ return _##lib##_roaraudio_library_init(para); \ } \ struct roar_dl_libraryinst * \ _##lib##_roaraudio_library_init(struct roar_dl_librarypara * para) \ #define ROAR_DL_PLUGIN_START(xlib) ROAR_DL_PLUGIN(xlib) { \ static int _inited = 0; \ static struct roar_dl_libraryinst lib; \ static struct roar_dl_libraryname libname; \ (void)para; \ if ( _inited ) \ return &lib; \ if ( para != NULL && \ (para->version != ROAR_DL_LIBPARA_VERSION || \ para->len < sizeof(struct roar_dl_librarypara)) ) { \ /* we should set ROAR_ERROR_NSVERSION here but can not */ \ /* because that would require the plugin to be linked */ \ /* aginst libroar */ \ return NULL; \ } \ memset(&lib, 0, sizeof(lib)); \ lib.version = ROAR_DL_LIBINST_VERSION; \ lib.len = sizeof(lib); \ memset(&libname, 0, sizeof(libname)); \ libname.version = ROAR_DL_LIBNAME_VERSION; \ libname.len = sizeof(libname); \ libname.name = #xlib; \ lib.libname = &libname; \ do #define ROAR_DL_PLUGIN_END while(0); \ _inited = 1; \ return &lib; \ } // general stuff: #define ROAR_DL_PLUGIN_ABORT_LOADING(err) roar_err_set((err)); return NULL #define ROAR_DL_PLUGIN_CHECK_VERSIONS(app,abi) (((lib.host_appname = (app)) != NULL) | \ ((lib.host_abiversion = (abi)) != NULL) ) // should we keep this macro at all? Is it helpfull at all? // if a plugin can handle multiple hosts it needs to call roar_dl_para_check_version() itself anyway. #define ROAR_DL_PLUGIN_CHECK_VERSIONS_NOW(app,abi) if ( roar_dl_para_check_version(para, (app), (abi)) == -1 ) return NULL // register stuff: #define ROAR_DL_PLUGIN_REG(fn, funcptr) (lib.func[(fn)] = (funcptr)) #define ROAR_DL_PLUGIN_REG_UNLOAD(func) (lib.unload = (func)) #define ROAR_DL_PLUGIN_REG_APPSCHED(sched) (lib.appsched = (sched)) #define ROAR_DL_PLUGIN_REG_GLOBAL_DATA(ptr,init) lib.global_data_len = sizeof((init)); \ lib.global_data_init = &(init); \ lib.global_data_pointer = (void*)&(ptr) #define ROAR_DL_PLUGIN_REG_LIBDEP(deps) (((lib.libdep = (deps)) == NULL) ? \ (ssize_t)-1 : \ (ssize_t)(lib.libdep_len = sizeof((deps))/sizeof(struct roar_dl_librarydep))) // register objects using FN: #define ROAR_DL_PLUGIN_REG_FN(subtype,obj,version) roar_dl_register_fn(NULL, -1, (subtype), &(obj), sizeof((obj)), (version), ROAR_DL_FNREG_OPT_NONE) #define ROAR_DL_PLUGIN_REG_FNFUNC(fn) ROAR_DL_PLUGIN_REG((fn), _roaraudio_library_ ## fn) // Do a FN reg callback registration: #define ROAR_DL_RFNREG(lhandle,obj) roar_dl_register_fn((lhandle), ROAR_DL_FN_REGFN, ROAR_DL_FNREG_SUBTYPE, &(obj), sizeof((obj)), ROAR_DL_FNREG_VERSION, ROAR_DL_FNREG_OPT_NONE) // meta data stuff: #define ROAR_DL_PLUGIN_META_PRODUCT(x) (libname.libname = (x)) #define ROAR_DL_PLUGIN_META_PRODUCT_NV(name,vendor) ROAR_DL_PLUGIN_META_PRODUCT(name " <" vendor ">") #define ROAR_DL_PLUGIN_META_PRODUCT_NIV_REAL(name,id,vendor) ROAR_DL_PLUGIN_META_PRODUCT(name " <" #id "/" vendor ">") #define ROAR_DL_PLUGIN_META_PRODUCT_NIV(name,id,vendor) ROAR_DL_PLUGIN_META_PRODUCT_NIV_REAL(name,id,vendor) #define ROAR_DL_PLUGIN_META_VERSION(x) (libname.libversion = (x)) #define ROAR_DL_PLUGIN_META_ABI(x) (libname.abiversion = (x)) #define ROAR_DL_PLUGIN_META_DESC(x) (libname.description = (x)) #define ROAR_DL_PLUGIN_META_CONTACT(x) (libname.contact = (x)) #define ROAR_DL_PLUGIN_META_CONTACT_FL(first,last) ROAR_DL_PLUGIN_META_CONTACT(first " " last) #define ROAR_DL_PLUGIN_META_CONTACT_FLE(first,last,email) ROAR_DL_PLUGIN_META_CONTACT(first " " last " <" email ">") #define ROAR_DL_PLUGIN_META_CONTACT_FLNE(first,last,nick,email) ROAR_DL_PLUGIN_META_CONTACT(first " \"" nick "\" " last " <" email ">") #define ROAR_DL_PLUGIN_META_AUTHORS(x) (libname.authors = (x)) #define ROAR_DL_PLUGIN_META_LICENSE(x) (libname.license = (x)) #define ROAR_DL_PLUGIN_META_LICENSE_TAG(x) ROAR_DL_PLUGIN_META_LICENSE(ROAR_LICENSE_ ## x) enum roar_dl_loadercmd { ROAR_DL_LOADER_NOOP = 0, ROAR_DL_LOADER_PRELOAD, ROAR_DL_LOADER_LOAD, ROAR_DL_LOADER_POSTLOAD, ROAR_DL_LOADER_PREUNLOAD, ROAR_DL_LOADER_UNLOAD, ROAR_DL_LOADER_POSTUNLOAD }; struct roar_plugincontainer; struct roar_dl_librarypara { int version; // version of this struct type (must be ROAR_DL_LIBPARA_VERSION) size_t len; // Length of this struct type (must be sizeof(struct roar_dl_librarypara) size_t refc; // Reference counter. size_t argc; // number of elements in argv struct roar_keyval * argv; // Parameter for the plugin void * args_store; // Storage area for argv's data. // If not NULL this and argv will be freed. // If NULL argv will be left untouched. void * binargv; // A pointer with binary data arguments. // This can be used to pass any non-string data to // the plugin. Normally this is NULL or the pointer // to a struct with members of whatever is needed. const char * appname; // application name in common format: // Product/Version <VendorID/VendorName> (comments) // Version and comment are optional and should be avoided. // When no vendor ID is registered use <VendorName>. // The VendorName MUST NOT contain a slash and SHOULD // be as unique as possible. // Examples: roard <0/RoarAudio>, MyAPP <myapp.org>, // AnAPP <Musterman GbR> const char * abiversion; // The ABI version. For libraries this should be the SONAME. // For applications this should be the version of the release // which introduced the current ABI. // Examples: libroar2, 0.5.1 struct roar_notify_core * notifycore; struct roar_plugincontainer * container; int (*loader)(struct roar_dl_librarypara * lhandle, void * loader_userdata, enum roar_dl_loadercmd cmd, void * argp); void * loader_userdata; }; struct roar_dl_libraryname { int version; size_t len; const char * name; //Format: shortname const char * libname; //This is the same as appname in struct roar_dl_librarypara. //Format: Product <VendorID/VendorName> (comments) const char * libversion; //This is the pure version number of the library. const char * abiversion; //This is the same as abiversion in struct roar_dl_librarypara. //Format: Version const char * description; //Free form. const char * contact; //Format: first ["']nick["'] last (comment) <email>/OpenPGPkey/Phone/Room const char * authors; //Other authors as free form. const char * license; //Format: LicenseName-Version (options) //Examples: GPL-3.0, LGPL-2.1, LGPL-3.0 (or later). }; struct roar_dl_librarydep { int version; size_t len; uint32_t flags; const char * name; const char * libname; const char * abiversion; }; #define ROAR_DL_DEP(__flags,__name,__libname,__abiversion) \ {.version = ROAR_DL_LIBDEP_VERSION, \ .len = sizeof(struct roar_dl_librarydep), \ .flags = __flags, \ .name = __name, \ .libname = __libname, \ .abiversion = __abiversion} struct roar_dl_libraryinst { int version; size_t len; int (*unload)(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib); int (*func[ROAR_DL_FN_MAX])(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib); struct roar_dl_libraryname * libname; size_t global_data_len; void * global_data_init; void ** global_data_pointer; struct roar_dl_librarydep * libdep; size_t libdep_len; struct roar_dl_appsched * appsched; const char * host_appname; const char * host_abiversion; }; struct roar_dl_appsched { int (*init) (struct roar_dl_librarypara * para); int (*free) (struct roar_dl_librarypara * para); int (*update)(struct roar_dl_librarypara * para); int (*tick) (struct roar_dl_librarypara * para); int (*wait) (struct roar_dl_librarypara * para); }; enum roar_dl_appsched_trigger { ROAR_DL_APPSCHED_INIT = 1, #define ROAR_DL_APPSCHED_INIT ROAR_DL_APPSCHED_INIT ROAR_DL_APPSCHED_FREE, #define ROAR_DL_APPSCHED_FREE ROAR_DL_APPSCHED_FREE ROAR_DL_APPSCHED_UPDATE, #define ROAR_DL_APPSCHED_UPDATE ROAR_DL_APPSCHED_UPDATE ROAR_DL_APPSCHED_TICK, #define ROAR_DL_APPSCHED_TICK ROAR_DL_APPSCHED_TICK ROAR_DL_APPSCHED_WAIT, #define ROAR_DL_APPSCHED_WAIT ROAR_DL_APPSCHED_WAIT ROAR_DL_APPSCHED_ABOUT, #define ROAR_DL_APPSCHED_ABOUT ROAR_DL_APPSCHED_ABOUT ROAR_DL_APPSCHED_HELP, #define ROAR_DL_APPSCHED_HELP ROAR_DL_APPSCHED_HELP ROAR_DL_APPSCHED_PREFERENCES #define ROAR_DL_APPSCHED_PREFERENCES ROAR_DL_APPSCHED_PREFERENCES }; // parameter functions: struct roar_dl_librarypara * roar_dl_para_new(const char * args, void * binargv, const char * appname, const char * abiversion); int roar_dl_para_ref (struct roar_dl_librarypara * para); int roar_dl_para_unref (struct roar_dl_librarypara * para); int roar_dl_para_check_version (struct roar_dl_librarypara * para, const char * appname, const char * abiversion); // 'core' dynamic loader functions. struct roar_dl_lhandle * roar_dl_open (const char * filename, int flags, int ra_init, struct roar_dl_librarypara * para); int roar_dl_ref (struct roar_dl_lhandle * lhandle); int roar_dl_unref (struct roar_dl_lhandle * lhandle); #define roar_dl_close(x) roar_dl_unref((x)) void * roar_dl_getsym (struct roar_dl_lhandle * lhandle, const char * sym, int type); int roar_dl_ra_init(struct roar_dl_lhandle * lhandle, const char * prefix, struct roar_dl_librarypara * para); const char * roar_dl_errstr (struct roar_dl_lhandle * lhandle); // getting meta data: struct roar_dl_librarypara * roar_dl_getpara(struct roar_dl_lhandle * lhandle); const struct roar_dl_libraryname * roar_dl_getlibname(struct roar_dl_lhandle * lhandle); // context switching: // _restore() is to switch from main to library context. _store() is to store library context // and switch back to main context. int roar_dl_context_restore(struct roar_dl_lhandle * lhandle); int roar_dl_context_store(struct roar_dl_lhandle * lhandle); // appsched: int roar_dl_appsched_trigger(struct roar_dl_lhandle * lhandle, enum roar_dl_appsched_trigger trigger); // FN Registration: // Actions objects can emit: enum roar_dl_fnreg_action { ROAR_DL_FNREG = 1, // The object is being registered ROAR_DL_FNUNREG = 2 // The object is being unregistered }; // Callback for registering/unregistering objects: struct roar_dl_fnreg { int fn; // Filter: The FN of the registering object or -1 for any. int subtype; // Filter: The subtype of the registering object or -1 for any. int version; // Filter: The version of the registering object or -1 for any. int (*callback)( // Callback to call on register/unregister. enum roar_dl_fnreg_action action, // The action happening int fn, // The FN of the object int subtype, // The subtype of the object const void * object, // Pointer to the object size_t objectlen, // Length of the object int version, // Version of the object int options, // Object Options. void * userdata, // User data for the callback. struct roar_dl_lhandle * lhandle // The registering handle. // This is valid until the object is unregistered. // Only roar_dl_context_restore(), roar_dl_context_store() // and roar_dl_getpara() may be used on this object. // Result of all other functions is undefined. ); void * userdata; // The user data pointer passed to the callback. }; // Parameters for FNREG registration: #define ROAR_DL_FNREG_SUBTYPE 0 #define ROAR_DL_FNREG_VERSION 0 #define ROAR_DL_FNREG_SIZE sizeof(struct roar_dl_fnreg) // Common protocol interface (CPI): struct roar_dl_proto { const int proto; const char * description; const int flags; int (*set_proto)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara); int (*unset_proto)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara); int (*handle)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara); int (*flush)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara); int (*flushed)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara); int (*status)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara); }; #define ROAR_DL_PROTO_FLAGS_NONE 0 #define ROAR_DL_PROTO_STATUS_RX_READY 0x0001 #define ROAR_DL_PROTO_STATUS_TX_READY 0x0002 #define ROAR_DL_PROTO_STATUS_WAIT_NOTIFY 0x0004 // Parameters for FNREG registration: #define ROAR_DL_PROTO_SUBTYPE 1 /* 0 = roard */ #define ROAR_DL_PROTO_VERSION 0 #define ROAR_DL_PROTO_SIZE sizeof(struct roar_dl_proto) // Common Service Interface (CSI): struct roar_dl_service { // Name and ABI version of the application: // if appname is NULL this is a /universal/ service. // Such services MUST use APIs defined by the RoarAudio Project. // If a random Vendor needs a API universal to own applications // it should define a virtual application name for this. const char * appname; const char * appabi; // Name and ABI/API version of service: const char * servicename; const char * serviceabi; // Description: const char * description; // Flags (see below for defined flags): const int flags; // Userdata: // This is some kind of constant data. // It can bed used by the functions below for internal stuff. const void * userdata; // Functions: // get_api returns a pointer to a struct with the API. // The api is specific to [appname, appabi, servicename, serviceabi]. const void * (*get_api)(const struct roar_dl_service * service, struct roar_dl_librarypara * para); }; #define ROAR_DL_SERVICE_FLAGS_NONE 0x0000 #define ROAR_DL_SERVICE_SUBTYPE 0 #define ROAR_DL_SERVICE_VERSION 0 #define ROAR_DL_SERVICE_SIZE sizeof(struct roar_dl_service) #define ROAR_DL_PLUGIN_REG_SERVICES(obj) \ static int _roaraudio_library_ROAR_DL_FN_SERVICE(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { \ size_t i; \ (void)para, (void)lib; \ for (i = 0; i < (sizeof((obj))/sizeof(*(obj))); i++) { \ ROAR_DL_PLUGIN_REG_FN(ROAR_DL_SERVICE_SUBTYPE, (obj)[i], ROAR_DL_SERVICE_VERSION); \ } \ return 0; \ } #define ROAR_DL_PLUGIN_REG_SERVICES_GET_API(name,obj) \ static const void * name(const struct roar_dl_service * service, struct roar_dl_librarypara * para) { \ (void)service, (void)para; \ return &(obj); \ } struct roar_dl_service_api { const void * api; struct roar_dl_lhandle * lhandle; const struct roar_dl_service * service; }; #define libroar_dl_service_apitype(type) \ union { \ struct roar_dl_service_api apiinterface; \ const struct type * api; \ } int libroar_dl_service_get_api_real(struct roar_dl_librarypara * para, const char * appname, const char * appabi, const char * servicename, const char * serviceabi, int universal, struct roar_dl_service_api * api, int retry); #define libroar_dl_service_get_api(para,appname,appabi,servicename,serviceabi,universal,api) libroar_dl_service_get_api_real((para),(appname),(appabi),(servicename),(serviceabi),(universal),(struct roar_dl_service_api *)(api), 1) #define roar_dl_service_get_api(para,servicename,serviceabi,api) libroar_dl_service_get_api((para), (para) == NULL ? NULL : ((struct roar_dl_librarypara *)(para))->appname, (para) == NULL ? NULL : ((struct roar_dl_librarypara *)(para))->abiversion, (servicename), (serviceabi), 1, (api)) int libroar_dl_service_free_api_real(struct roar_dl_service_api * api); #define libroar_dl_service_free_api(api) libroar_dl_service_free_api_real((struct roar_dl_service_api *)&(api)) #define libroar_dl_service_run_func(obj,name,type,...) ((type[3]){(type)roar_dl_context_restore((obj).apiinterface.lhandle), ((obj).api->name(__VA_ARGS__)), (type)roar_dl_context_store((obj).apiinterface.lhandle)})[1] #define libroar_dl_service_run_func_void(obj,name,...) do { roar_dl_context_restore((obj).apiinterface.lhandle); (obj).api->name(__VA_ARGS__); roar_dl_context_store((obj).apiinterface.lhandle); } while (0) #define libroar_dl_service_check_func(obj,name) ((obj).api->name != NULL) // Reg FN: // Options: #define ROAR_DL_FNREG_OPT_NONE 0 /* no options */ // Register an FN. int roar_dl_register_fn(struct roar_dl_lhandle * lhandle, int fn, int subtype, const void * object, size_t objectlen, int version, int options); // Unregister an FN. int roar_dl_unregister_fn2(struct roar_dl_lhandle * lhandle, int fn, int subtype, const void * object, size_t objectlen, int version, int options); // Unregister FN for the given plugin. // This should not be called directly and is called internally when needed. int roar_dl_unregister_fn(struct roar_dl_lhandle * lhandle); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/roarfeatures.h��������������������������������������������������0000644�0001750�0001750�00000005055�12264733466�020431� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarfeatures.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARFEATURES_H_ #define _LIBROARFEATURES_H_ #include "libroar.h" // libroar1 features: #define ROAR_FT_FUNC_SET_FLAGS2 #define ROAR_FT_FUNC_LIST_FILTERED #define ROAR_FT_FUNC_WAIT #define ROAR_FT_FUNC_VS_CTL #define ROAR_FT_FUNC_SET_VOL2 #define ROAR_FT_FUNC_CONNECT2 #define ROAR_FT_FUNC_SIMPLE_CONNECT2 #define ROAR_FT_FUNC_PANIC #define ROAR_FT_FUNC_RESET #define ROAR_FT_FUNC_CLOCK_GETTIME #define ROAR_FT_FUNC_BUFFER_MOVEINTOQUEUE #define ROAR_FT_FUNC_CTL_C2M2 #define ROAR_FT_FUNC_CTL_M2C2 #define ROAR_FT_FUNC_GET_PATH #define ROAR_FT_FUNC_MM_STRDUP2 #define ROAR_FT_FEATURE_VS #define ROAR_FT_FEATURE_VS_FILE #define ROAR_FT_FEATURE_VS_BUFFERED #define ROAR_FT_FEATURE_CRC24 #define ROAR_FT_FEATURE_HASH_TIGER #define ROAR_FT_FEATURE_CAPS_STANDARDS #define ROAR_FT_FEATURE_SERVER_INFO_IT_SERVER #define ROAR_FT_FEATURE_HASH_API #define ROAR_FT_FEATURE_RANDOM_NONCE #define ROAR_FT_FEATURE_UUID /* see #230 */ #define ROAR_FT_FEATURE_COMMON_PROTO /* see #257 */ #define ROAR_FT_FEATURE_SELECTOR_HANDLING /* see #285 */ #define ROAR_FT_FEATURE_WATCHDOG /* see #291 */ // libroar2 features: #define ROAR_FT_SONAME_LIBROAR2 #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/roarfloat.h�����������������������������������������������������0000644�0001750�0001750�00000004405�12264733466�017716� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarfloat.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARROARFLOAT_H_ #define _LIBROARROARFLOAT_H_ #include "libroar.h" typedef uint32_t roarfloat32; #define ROAR_UFLOAT32_MAX 65535 #define ROAR_UFLOAT32_ZERO ROAR_HOST2NET32(0x00000000); #define ROAR_UFLOAT32_PINF ROAR_HOST2NET32(0x00000001); #define ROAR_UFLOAT32_NINF ROAR_HOST2NET32(0x0000FFFF); #define ROAR_UFLOAT32_PNAN ROAR_HOST2NET32(0x00007FFF); #define ROAR_UFLOAT32_NNAN ROAR_HOST2NET32(0x00008000); roarfloat32 roar_ufloat32_build(const uint16_t mul, const uint16_t scale); uint16_t roar_ufloat32_scale(const roarfloat32 f); uint16_t roar_ufloat32_mul(const roarfloat32 f); roarfloat32 roar_ufloat32_from_float(const float f); float roar_ufloat32_to_float (const roarfloat32 f); int roar_float32_iszero(const roarfloat32 f); int roar_float32_isinf(const roarfloat32 f); int roar_float32_isnan(const roarfloat32 f); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/roarslp.h�������������������������������������������������������0000644�0001750�0001750�00000005654�12264733466�017416� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarslp.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSLP_H_ #define _LIBROARSLP_H_ #include "libroar.h" #define ROAR_SLP_MAX_MATCHES 8 #define ROAR_SLP_MAX_URL_LEN 256 #define ROAR_SLP_URL_TYPE_ROAR "service:mixer.fellig:roar" #define ROAR_SLP_URL_TYPE_ROAR_LEN 25 #define ROAR_SLP_URL_TYPE_ESD "service:mixer.fellig:esd" #define ROAR_SLP_URL_TYPE_ESD_LEN 24 #define ROAR_SLP_URL_TYPE ROAR_SLP_URL_TYPE_ROAR #define ROAR_SLP_URL_TYPE_LEN ROAR_SLP_URL_TYPE_ROAR_LEN #ifndef ROAR_HAVE_LIBSLP #define SLPHandle void * #define SLPError int #define SLPBoolean int #define SLP_FALSE 0 #define SLP_TRUE 1 #endif struct roar_slp_search { char dummy[8]; }; struct roar_slp_match { char url[ROAR_SLP_MAX_URL_LEN]; time_t tod; // Time Of Dead (found+TTL) }; struct roar_slp_cookie { SLPError callbackerr; struct roar_slp_search * search; struct roar_slp_match match[ROAR_SLP_MAX_MATCHES]; int matchcount; }; SLPBoolean roar_slp_url_callback(SLPHandle hslp, const char * srvurl, unsigned short lifetime, SLPError errcode, void * cookie); int roar_slp_search (struct roar_slp_cookie * cookie, char * type); int roar_slp_cookie_init (struct roar_slp_cookie * cookie, struct roar_slp_search * search); char * roar_slp_find_roard (int nocache); int roar_slp_find_roard_r (char * addr, size_t len, int nocache); #endif //ll ������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/roartime.h������������������������������������������������������0000644�0001750�0001750�00000004054�12264733467�017550� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//time.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARTIME_H_ #define _LIBROARTIME_H_ #include "libroar.h" struct roar_time { int64_t t_sec; // secund part of system time uint64_t t_ssec; // sub secs in 2^-64sec units. uint64_t c_freq; // clock freq in nHz. (use zero for unknown/undefined) uint64_t c_drift; // clock drift in 2^-64sec per sec. (use zero for unknown/undefined) }; int roar_time_to_msg(struct roar_message * mes, struct roar_time * time); int roar_time_from_msg(struct roar_time * time, struct roar_message * mes); int roar_get_time (struct roar_connection * con, struct roar_time * time); int roar_clock_gettime(struct roar_time * rt, int clock); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/roarx11.h�������������������������������������������������������0000644�0001750�0001750�00000005071�12264733467�017223� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarx11.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARX11_H_ #define _LIBROARX11_H_ #include "libroar.h" #ifdef ROAR_HAVE_LIBX11 #define _ROAR_X11_DISPLAY Display #define _ROAR_X11_WINDOW Window #else #define _ROAR_X11_DISPLAY void #define _ROAR_X11_WINDOW uint_least32_t #endif struct roar_x11_connection { #ifdef ROAR_HAVE_LIBX11 int close; Display * display; #else char dummy[8]; #endif }; #define ROAR_X11_MAX_WIN_PER_INFO 4 struct roar_display_info_x11 { int type; int socktype; char * host; int display; int screen; size_t wins; _ROAR_X11_WINDOW window[ROAR_X11_MAX_WIN_PER_INFO]; }; struct roar_x11_connection * roar_x11_connect(char * display); struct roar_x11_connection * roar_x11_connect_display(_ROAR_X11_DISPLAY * display); int roar_x11_disconnect(struct roar_x11_connection * con); #define roar_x11_get_display(con) ((con) == NULL ? NULL : (con)->display) int roar_x11_flush(struct roar_x11_connection * con); int roar_x11_set_prop(struct roar_x11_connection * con, const char * key, const char * val); int roar_x11_delete_prop(struct roar_x11_connection * con, const char * key); char * roar_x11_get_prop(struct roar_x11_connection * con, const char * key); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/scheduler.h�����������������������������������������������������0000644�0001750�0001750�00000007266�12264733470�017706� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//scheduler.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSCHEDULER_H_ #define _LIBROARSCHEDULER_H_ #include "libroar.h" enum roar_scheduler_type { ROAR_SCHEDULER_NONE = 0, ROAR_SCHEDULER_VIO, ROAR_SCHEDULER_TIMEOUT, ROAR_SCHEDULER_PLUGIN, ROAR_SCHEDULER_PLUGINCONTAINER, ROAR_SCHEDULER_CPI_LISTEN, ROAR_SCHEDULER_CPI_CLIENT, ROAR_SCHEDULER_CPI_SERVICE, // listen for CPI registrations. // for future use. ROAR_SCHEDULER_CONNECTION, ROAR_SCHEDULER_VSS }; enum roar_scheduler_strategy { ROAR_SCHEDULER_STRATEGY_DEFAULT = -1, ROAR_SCHEDULER_STRATEGY_SELECT = 1, ROAR_SCHEDULER_STRATEGY_WAIT, ROAR_SCHEDULER_STRATEGY_SELECTORWAIT, ROAR_SCHEDULER_STRATEGY_WAITORSELECT, }; #define ROAR_SCHEDULER_FLAG_DEFAULT -1 #define ROAR_SCHEDULER_FLAG_NONE 0x0000 #define ROAR_SCHEDULER_FLAG_FREE 0x0001 #define ROAR_SCHEDULER_FLAG_STUB 0x0002 #define ROAR_SCHEDULER_FLAG_KEEP_RUNNING 0x0004 /* keep _run() running in case of no work */ struct roar_scheduler_source { enum roar_scheduler_type type; int flags; struct roar_dl_lhandle * lhandle; struct roar_vio_calls * vio; int (*cb)(struct roar_scheduler_source * source, void * userdata, int eventsa); void * userdata; union { void * vp; // dummy. int eventsq; struct roar_vio_selecttv timeout; struct roar_plugincontainer * container; struct { int proto; const struct roar_dl_proto * impl; int client; struct roar_buffer *obuffer; void * userdata; const struct roar_keyval * protopara; ssize_t protoparalen; } cpi; struct roar_connection * con; roar_vs_t * vss; } handle; }; struct roar_scheduler; struct roar_scheduler * roar_scheduler_new(int flags, enum roar_scheduler_strategy strategy); int roar_scheduler_ref(struct roar_scheduler * sched); int roar_scheduler_unref(struct roar_scheduler * sched); int roar_scheduler_iterate(struct roar_scheduler * sched); int roar_scheduler_run(struct roar_scheduler * sched); int roar_scheduler_source_add(struct roar_scheduler * sched, struct roar_scheduler_source * source); int roar_scheduler_source_del(struct roar_scheduler * sched, struct roar_scheduler_source * source); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/serverinfo.h����������������������������������������������������0000644�0001750�0001750�00000004360�12264733470�020102� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//serverinfo.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSERVERINFO_H_ #define _LIBROARSERVERINFO_H_ #include "libroar.h" struct roar_server_info { const char * version; const char * location; const char * description; const char * contact; const char * serial; const char * address; const char * uiurl; const char * hostid; const char * license; const char * build; struct { const char * sysname; const char * release; const char * nodename; const char * machine; } un; }; struct roar_server_info * roar_server_info(struct roar_connection * con); struct roar_server_info * roar_library_info(void); int roar_server_info_free(struct roar_server_info * info); int roar_server_info_to_mes(struct roar_message * mes, struct roar_server_info * info, void ** data); struct roar_server_info * roar_server_info_from_mes(struct roar_message * mes, void * data); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/services.h������������������������������������������������������0000644�0001750�0001750�00000025343�12264733470�017547� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//services.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSERVICES_H_ #define _LIBROARSERVICES_H_ #include "libroar.h" enum roar_service_num { // Error value in case any function returns this type. // roar_error must be set on return. ROAR_SERVICE_NUM_ERROR = -1, #define ROAR_SERVICE_NUM_ERROR ROAR_SERVICE_NUM_ERROR // reserved for future use. ROAR_SERVICE_NUM_DEFAULT = 0, //#define ROAR_SERVICE_NUM_DEFAULT ROAR_SERVICE_NUM_DEFAULT // current number of objects. ROAR_SERVICE_NUM_CURRENT = 1, #define ROAR_SERVICE_NUM_CURRENT ROAR_SERVICE_NUM_CURRENT // minumum number of objects. Optional. ROAR_SERVICE_NUM_MIN, #define ROAR_SERVICE_NUM_MIN ROAR_SERVICE_NUM_MIN // maximum number of objects. Optional. ROAR_SERVICE_NUM_MAX, #define ROAR_SERVICE_NUM_MAX ROAR_SERVICE_NUM_MAX // average number of objects. Optional. ROAR_SERVICE_NUM_AVG, #define ROAR_SERVICE_NUM_AVG ROAR_SERVICE_NUM_AVG // Hint for buffer size used to list(). list() can still return 'buffer to short'. ROAR_SERVICE_NUM_BUFFER, #define ROAR_SERVICE_NUM_BUFFER ROAR_SERVICE_NUM_BUFFER }; // clients: #define ROAR_SERVICE_CLIENT_NAME "client" #define ROAR_SERVICE_CLIENT_ABI "1.0beta9-pr1" struct roar_client; struct roar_service_client { // get list of client IDs. // buffer is passed as ids, buffer size (in elements) is passed as len. // returns the number of elements stored in ids or -1 on error. ssize_t (*list)(int * ids, size_t len); // get the number of clients. See also comments above on what. ssize_t (*num)(enum roar_service_num what); // get a client by ID. The object returned is a copy and must not be motified. int (*get)(int id, struct roar_client * client); // kick a client by ID. The reason for the kick is stored in error and msg. // if msg is NULL it defaults to roar_error2str(error). int (*kick)(int id, int error, const char * msg); // return status of client as returned by CPI's status() callback. int (*status)(int id); // optional functions follow: // set PID, UID and/or GID for client. // if any ID is -1 the old value is not touched if clear is false. // if clear is false IDs passed as -1 are reset to 'not set'. // if altering IDs changes the permissions of a given client is up to the // provider. int (*set_ids)(int id, int clear, int pid, int uid, int gid); // set the name of the client. // the name is copied within this call so the bufer holding it can be freed. int (*set_name)(int id, const char * name); // this will change the protocol of the client. int (*set_proto)(int id, int proto); // this execes the stream. // the stream must be owned by the client. // if stream is -1 the client is execed. // This will result in the client be completly reset to a state // as directly after accept(). This must be followed by a call to set_proto(). int (*exec)(int id, int stream); }; // streams: struct roar_stream_info; struct roar_stream_rpg; struct roar_service_stream { // get list of stream IDs. // buffer is passed as ids, buffer size (in elements) is passed as len. // returns the number of elements stored in ids or -1 on error. ssize_t (*list)(int * ids, size_t len); // get the number of streams. See also comments above on what. ssize_t (*num)(enum roar_service_num what); // get a stream by ID. The object returned is a copy and must not be motified. int (*get)(int id, struct roar_stream * s, struct roar_stream_info * info); // kick a stream by ID. The reason for the kick is stored in error and msg. // if msg is NULL it defaults to roar_error2str(error). int (*kick)(int id, int error, const char * msg); // optional functions follow: // create a new stream. // if parent is set to -1 a normal stream is created. // if it is set to the ID of an existing stream it is created as child/virtual stream. // if mixer is set to -1 the default mixer is used. int (*new)(const struct roar_audio_info * info, int dir, int parent, int mixer); // get the ID of the client owning the stream. int (*get_client)(int id); // set the owner of the stream. // if the stream is already owned by a client it is moved if possible. int (*set_client)(int id, int client); // set role of stream. // if role is passed as -1 the role is cleared. int (*set_role)(int id, int role); // alter stream flags. int (*set_flag)(int id, uint32_t flags, int action); // get name of stream. // the buffer returned in *name must be freed using roar_mm_free(). int (*get_name)(int id, char ** name); // set name of stream. // stream name will be copied so the buffer can be freed after this call. // passing NULL will unset the stream name. int (*set_name)(int id, const char * name); // set volume and rpg settings. // If mixer or rpg is NULL the corresponding setting is not touched. // if both are NULL this does nothing. int (*set_volume)(int id, const struct roar_mixer_settings * mixer, const struct roar_stream_rpg * rpg); }; // about: #define ROAR_SERVICE_ABOUT_NAME "about" #define ROAR_SERVICE_ABOUT_ABI "1.0beta9" struct roar_service_about { int (*show)(const struct roar_dl_libraryname * libname); }; // help: #define ROAR_SERVICE_HELP_NAME "help" #define ROAR_SERVICE_HELP_ABI "1.0beta9" struct roar_service_help { int (*show)(const struct roar_dl_libraryname * libname, const char * topic); }; // prefs: // procctl: #define ROAR_SERVICE_PROCCTL_ERROR ((uint_least32_t)0xFFFFFFFFUL) #define ROAR_SERVICE_PROCCTL_NONE ((uint_least32_t)0x00000000UL) #define ROAR_SERVICE_PROCCTL_ALL ((uint_least32_t)0x7FFFFFFFUL) #define ROAR_SERVICE_PROCCTL_CONFIG ((uint_least32_t)0x00000001UL) #define ROAR_SERVICE_PROCCTL_LOGFILE ((uint_least32_t)0x00000002UL) #define ROAR_SERVICE_PROCCTL_PIDFILE ((uint_least32_t)0x00000004UL) struct roar_service_procctl { // terminate the process. // rv is the return POSIX return code. // a value of zero means no error. // a value of -1 means the provider should decide the value // based on the other parameters. // a value smaller than -1 is not allowed. // all other values indicate some kind of error. // error and msg give a closer information why the process is terminated. // those can be be used in case rv is set to -1. they can also be printed // or logged by the the provider for later inspection. int (*exit)(int rv, int error, const char * msg); // optional functions follow: // restart the process. int (*restart)(void); // daemonize the process. // the process is moved into background, detaching from the console. int (*daemonize)(void); // reload config or other parts. See above. int (*reload)(uint_least32_t what); // reopen logfiles or other parts. See above. int (*reopen)(uint_least32_t what); }; // queue: struct roar_service_queue { ssize_t (*list)(int * ids, size_t len); ssize_t (*num)(enum roar_service_num what); int (*get_name)(int id, char ** name); // status? int (*play)(int id); int (*stop)(int id); int (*pause)(int id, int how); int (*next)(int id); int (*prev)(int id); }; // GPIO/Sensors: #define ROAR_SERVICE_GPIO_NAME "gpio" #define ROAR_SERVICE_GPIO_ABI "1.0beta10-pr0" #define ROAR_SERVICE_GPIO_FINPUT ((uint_least32_t)0x00000001UL) #define ROAR_SERVICE_GPIO_FOUTPUT ((uint_least32_t)0x00000002UL) #define ROAR_SERVICE_GPIO_FPULLDOWN ((uint_least32_t)0x00000004UL) #define ROAR_SERVICE_GPIO_FPULLUP ((uint_least32_t)0x00000008UL) #define ROAR_SERVICE_GPIO_FCACHED ((uint_least32_t)0x00000010UL) enum roar_service_gpio_type { ROAR_SERVICE_GPIO_TERROR = -1, ROAR_SERVICE_GPIO_TUNKNOWN = 0, ROAR_SERVICE_GPIO_TINT, ROAR_SERVICE_GPIO_TENUM, ROAR_SERVICE_GPIO_TBOOL, ROAR_SERVICE_GPIO_TTRISTATE, ROAR_SERVICE_GPIO_TFLOAT }; enum roar_service_gpio_state { ROAR_SERVICE_GPIO_SERROR = -1, ROAR_SERVICE_GPIO_SUNKNOWN = 0, ROAR_SERVICE_GPIO_SFREE, ROAR_SERVICE_GPIO_SUNINITED, ROAR_SERVICE_GPIO_SREADY, ROAR_SERVICE_GPIO_SBUSY, ROAR_SERVICE_GPIO_SDISCONNECTED, ROAR_SERVICE_GPIO_SDISABLED, ROAR_SERVICE_GPIO_SINERROR }; struct roar_service_gpio_port { int id; const char * name; uint_least32_t mode; const char * unit; enum roar_service_gpio_type type; enum roar_service_gpio_state state; int irange_min; int irange_max; double frange_min; double frange_max; }; struct roar_service_gpio { // get list of gpio IDs. // buffer is passed as ids, buffer size (in elements) is passed as len. // returns the number of elements stored in ids or -1 on error. ssize_t (*list)(int * ids, size_t len); // get the number of gpios. See also comments above on what. ssize_t (*num)(enum roar_service_num what); // get a gpio by ID. The object returned is a copy and must not be motified or freed. int (*get)(int id, struct roar_service_gpio_port * port); // Sets up ports. // the controler should set mode and state of port to given target mode and state. // If id is given as -1 this is about the controler. mode MUST NOT contain any // flags beside ROAR_SERVICE_GPIO_FCACHED. If ROAR_SERVICE_GPIO_FCACHED // is set it is applied all ports. int (*setup)(int id, uint_least32_t mode, enum roar_service_gpio_state state); // get value of port (input or output) as int or float. int (*get_int)(int id); double (*get_float)(int id); // set value of output (as int or float). int (*set_int)(int id, int val); int (*set_float)(int id, double val); // convert the value val as returned by the port to the base unit of the port. // if rev is set converst from the base unit to the value as used by the port. int (*convert_int)(int id, int val, int rev); double (*convert_float)(int id, double val, int rev); }; #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/simple.h��������������������������������������������������������0000644�0001750�0001750�00000004124�12264733470�017207� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//simple.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSIMPLE_H_ #define _LIBROARSIMPLE_H_ #include "libroar.h" int roar_simple_connect (struct roar_connection * con, const char * server, const char * name); int roar_simple_connect2(struct roar_connection * con, const char * server, const char * name, int flags, uint_least32_t timeout); int roar_simple_new_stream_attachexeced_obj (struct roar_connection * con, struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, int dir, int mixer); int roar_simple_play_file(const char * file, const char * server, const char * name); int roar_simple_connect_virtual(struct roar_connection * con, struct roar_stream * s, int parent, int dir); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/socket.h��������������������������������������������������������0000644�0001750�0001750�00000004673�12264733471�017220� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//socket.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSOCKET_H_ #define _LIBROARSOCKET_H_ #include "libroar.h" #define ROAR_SOCKET_MODE_NONE 0 #define ROAR_SOCKET_MODE_LISTEN 1 #define ROAR_SOCKET_MODE_CONNECT 2 #define ROAR_SOCKET_QUEUE_LEN 8 #define ROAR_SOCKET_BLOCK 1 #define ROAR_SOCKET_NONBLOCK 2 #define ROAR_SOCKET_MAX_HOSTNAMELEN 64 int roar_socket_listen (int type, const char * host, int port); int roar_socket_connect (int type, const char * host, int port); // TODO: those function should be made /static/. #if 0 int roar_socket_new_decnet_seqpacket (void) _LIBROAR_ATTR_TO_STATIC; int roar_socket_new_ipxspx (void) _LIBROAR_ATTR_TO_STATIC; #endif int roar_socket_new (int type); int roar_socket_open (int mode, int type, const char * host, int port); const char * roar_socket_get_local_nodename(void); int roar_socket_nonblock(int fh, int state); int roar_socket_dup_udp_local_end (int fh); int roar_socket_send_fh (int sock, int fh, char * mes, size_t len); int roar_socket_recv_fh (int sock, char * mes, size_t * len); #endif //ll ���������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/sshaskpass.h����������������������������������������������������0000644�0001750�0001750�00000003072�12264733471�020103� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//sshaskpass.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAR_SSHASKPASS_H_ #define _LIBROAR_SSHASKPASS_H_ #include "libroar.h" int roar_sshaskpass_getpass (char ** pw, char * desc); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/stack.h���������������������������������������������������������0000644�0001750�0001750�00000004321�12264733471�017023� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stack.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSTACK_H_ #define _LIBROARSTACK_H_ #include "libroar.h" #define ROAR_STACK_SIZE 32 #define ROAR_STACK_FLAG_NONE 0x00 #define ROAR_STACK_FLAG_FREE_SELF 0x01 #define ROAR_STACK_FLAG_FREE_DATA 0x02 struct roar_stack { int next; int flags; void (*free)(void*); void * slot[ROAR_STACK_SIZE]; }; int roar_stack_new(struct roar_stack * stack); struct roar_stack * roar_stack_newalloc(void); int roar_stack_free(struct roar_stack * stack); int roar_stack_set_free(struct roar_stack * stack, void (*func)(void*)); int roar_stack_set_flag(struct roar_stack * stack, int flag, int reset); int roar_stack_push (struct roar_stack * stack, void * ptr); int roar_stack_pop (struct roar_stack * stack, void ** ptr); int roar_stack_get_cur (struct roar_stack * stack, void ** ptr); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/stream.h��������������������������������������������������������0000644�0001750�0001750�00000014777�12264733472�017232� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stream.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARSTREAM_H_ #define _LIBROARSTREAM_H_ #include "roaraudio.h" #define _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL const char * roar_dir2str (const int dir) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; int roar_str2dir (const char * name) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL _LIBROAR_ATTR_PURE; struct roar_stream_info { int block_size; int pre_underruns; int post_underruns; uint32_t codec; uint32_t flags; char * driver; uint_least32_t delay; int state; int mixer; int role; }; struct roar_stream_rpg { int mode; uint16_t mul; uint16_t div; }; int roar_stream_connect (struct roar_connection * con, struct roar_stream * s, int dir, int mixer) _LIBROAR_STREAM_STDATTRS; int roar_stream_new (struct roar_stream * s, unsigned int rate, unsigned int channels, unsigned int bits, unsigned int codec) _LIBROAR_ATTR_NONNULL_ALL; int roar_stream_new_by_info (struct roar_stream * s, const struct roar_audio_info * info) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_rel_id(struct roar_stream * s, int id) _LIBROAR_ATTR_NONNULL_ALL; int roar_stream_get_rel_id(struct roar_stream * s) _LIBROAR_STREAM_STDATTRS; int roar_stream_new_by_id(struct roar_stream * s, int id) _LIBROAR_ATTR_NONNULL_ALL; int roar_stream_new_empty(struct roar_stream * s) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_id (struct roar_stream * s, int id) _LIBROAR_ATTR_NONNULL_ALL; int roar_stream_get_id (struct roar_stream * s) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_fh (struct roar_stream * s, int fh) _LIBROAR_ATTR_NONNULL_ALL; int roar_stream_get_fh (struct roar_stream * s) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_dir (struct roar_stream * s, int dir) _LIBROAR_ATTR_NONNULL_ALL; int roar_stream_get_dir (struct roar_stream * s) _LIBROAR_STREAM_STDATTRS; int roar_stream_exec (struct roar_connection * con, struct roar_stream * s) _LIBROAR_STREAM_STDATTRS; int roar_stream_connect_to (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port); int roar_stream_connect_to_ask (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port); int roar_stream_passfh (struct roar_connection * con, struct roar_stream * s, int fh) _LIBROAR_STREAM_STDATTRS; int roar_stream_attach_simple (struct roar_connection * con, struct roar_stream * s, int client) _LIBROAR_STREAM_STDATTRS; int roar_stream_get_info (struct roar_connection * con, struct roar_stream * s, struct roar_stream_info * info) _LIBROAR_STREAM_STDATTRS; int roar_stream_get_name (struct roar_connection * con, struct roar_stream * s, char * name, size_t len) _LIBROAR_STREAM_STDATTRS; int roar_stream_get_chanmap (struct roar_connection * con, struct roar_stream * s, char * map, size_t * len) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_chanmap (struct roar_connection * con, struct roar_stream * s, char * map, size_t len) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_flags (struct roar_connection * con, struct roar_stream * s, uint32_t flags, int action) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_role (struct roar_connection * con, struct roar_stream * s, int role) _LIBROAR_STREAM_STDATTRS; int roar_stream_get_rpg (struct roar_connection * con, struct roar_stream * s, struct roar_stream_rpg * rpg) _LIBROAR_STREAM_STDATTRS; int roar_stream_set_rpg (struct roar_connection * con, struct roar_stream * s, const struct roar_stream_rpg * rpg) _LIBROAR_STREAM_STDATTRS; int roar_stream_s2m (struct roar_stream * s, struct roar_message * m); int roar_stream_m2s (struct roar_stream * s, struct roar_message * m); int32_t roar_str2codec (const char * codec) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; const char * roar_codec2str (const uint32_t codec) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; int32_t roar_mime2codec (const char * mime) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; const char * roar_codec2mime (const uint32_t codec) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; int32_t roar_str2rate(const char * rate) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; int32_t roar_str2bits(const char * bits) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; int32_t roar_str2channels(const char * channels) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; const char * roar_streamstate2str(int streamstate) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; int roar_str2role (const char * role) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; const char * roar_role2str (const int role) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; const char * roar_rpgmode2str(const int rpgmode) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_PURE; ssize_t roar_info2samplesize (struct roar_audio_info * info) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; ssize_t roar_info2framesize (struct roar_audio_info * info) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; ssize_t roar_info2bitspersec (struct roar_audio_info * info) _LIBROAR_STREAM_STDATTRS _LIBROAR_ATTR_PURE; int roar_profile2info (struct roar_audio_info * info, const char * profile) _LIBROAR_STREAM_STDATTRS; ssize_t roar_profiles_list (const char ** list, size_t len, size_t offset) _LIBROAR_STREAM_STDATTRS; #endif //ll �roaraudio-1.0beta11/include/libroar/trap.h����������������������������������������������������������0000644�0001750�0001750�00000004502�12264733472�016666� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//trap.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARTRAP_H_ #define _LIBROARTRAP_H_ #include "libroar.h" #ifdef ROAR_SUPPORT_TRAP #define roar_strap(group,name) roar_strap_impl((group),(name), __LINE__, __FILE__, ROAR_DBG_PREFIX) #else #define roar_strap(group,name) #endif #define ROAR_TRAP_GROUP_LIBROAR 1 #define ROAR_TRAP_GROUP_ROARD 2 #define ROAR_TRAP_GROUP_APP 3 #define ROAR_TRAP_GROUP_LIB 4 #define ROAR_TRAP_GROUP_NETWORK 5 #define ROAR_TRAP_GROUP_PROTO 6 #define ROAR_TRAP_GROUP_USER_MIN 1025 enum roar_trap_policy { ROAR_TRAP_IGNORE = 0, ROAR_TRAP_WARN, ROAR_TRAP_ABORT, ROAR_TRAP_KILL, ROAR_TRAP_STOP, ROAR_TRAP_DIE }; unsigned int roar_trap_register_group(const char * name); const char * roar_trap_get_groupname(const unsigned int group); unsigned int roar_trap_get_groupid(const char * name); void roar_strap_impl(const unsigned int group, const char * name, unsigned int line, const char * file, const char * prefix); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/uuid.h����������������������������������������������������������0000644�0001750�0001750�00000005411�12264733472�016666� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//uuid.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARUUID_H_ #define _LIBROARUUID_H_ #include "libroar.h" typedef unsigned char roar_uuid_t[16]; enum roar_uuid_type { ROAR_UUID_TYPE_NULL = 0, ROAR_UUID_TYPE_TIME = 1, ROAR_UUID_TYPE_DCE_SECURITY = 2, ROAR_UUID_TYPE_MD5 = 3, ROAR_UUID_TYPE_RANDOM = 4, ROAR_UUID_TYPE_SHA1 = 5 }; // compare two UUIDs: return 1 if they are the same, 0 if they are not and -1 in case of error. int roar_uuid_eq(const roar_uuid_t a, const roar_uuid_t b); int roar_uuid2str(char * str, const roar_uuid_t uuid, ssize_t len); int roar_str2uuid(roar_uuid_t uuid, const char * str); // returns UUIDs for common namespaces. const roar_uuid_t * roar_uuid_get_ns_real(const char * ns); #define roar_uuid_get_ns(ns) (*roar_uuid_get_ns_real((ns))) int roar_uuid_gen(roar_uuid_t uuid, enum roar_uuid_type type, const roar_uuid_t ns, const void * argp, ssize_t arglen); #define roar_uuid_gen_null(uuid) roar_uuid_gen((uuid), ROAR_UUID_TYPE_NULL, NULL, NULL, -1) #define roar_uuid_gen_time(uuid) roar_uuid_gen((uuid), ROAR_UUID_TYPE_TIME, NULL, NULL, -1) #define roar_uuid_gen_random(uuid) roar_uuid_gen((uuid), ROAR_UUID_TYPE_RANDOM, NULL, NULL, -1) #define roar_uuid_gen_fromstr(uuid,str,ns) roar_uuid_gen((uuid), ROAR_UUID_TYPE_SHA1, roar_uuid_get_ns((ns)), (str), roar_mm_strlen((str))) #define roar_uuid_clear(uuid) roar_uuid_gen_null((uuid)) #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio.h�����������������������������������������������������������0000644�0001750�0001750�00000015340�12264733472�016517� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_H_ #define _LIBROARVIO_H_ #include "libroar.h" // some defines: #define ROAR_VIOF_EXEC O_EXEC #define ROAR_VIOF_READ O_RDONLY #define ROAR_VIOF_WRITE O_WRONLY #define ROAR_VIOF_READWRITE O_RDWR #define ROAR_VIOF_SEARCH O_SEARCH #define ROAR_VIOF_LISTEN (-"") /* compiler error as long as there is no O_LISTEN */ #define ROAR_VIOF_CREAT O_CREAT #define ROAR_VIOF_TRUNC O_TRUNC #define ROAR_VIOF_APPEND O_APPEND #ifndef ROAR_TARGET_WIN32 #define ROAR_VIOF_NONBLOCK O_NONBLOCK #else #define ROAR_VIOF_NONBLOCK 0 #endif #define ROAR_VIO_FLAGS_NONE 0x00000000UL #define ROAR_VIO_FLAGS_FREESELF 0x00000001UL /* Free the VIO object */ struct roar_connection; // sys io: typedef int32_t roar_vio_ctl_t; typedef int_least64_t roar_off_t; struct roar_vio_calls { size_t refc; uint32_t flags; void *inst; ssize_t (*read )(struct roar_vio_calls * vio, void *buf, size_t count); ssize_t (*write )(struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t (*lseek )(struct roar_vio_calls * vio, roar_off_t offset, int whence); int (*sync )(struct roar_vio_calls * vio); int (*ctl )(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int (*close )(struct roar_vio_calls * vio); }; int roar_vio_clear_calls (struct roar_vio_calls * calls); ssize_t roar_vio_read (struct roar_vio_calls * vio, void *buf, size_t count) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; ssize_t roar_vio_write (struct roar_vio_calls * vio, void *buf, size_t count) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; roar_off_t roar_vio_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_nonblock(struct roar_vio_calls * vio, int state) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_sync (struct roar_vio_calls * vio) _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1); #define roar_vio_close(x) roar_vio_unref((x)) int roar_vio_ref (struct roar_vio_calls * vio) _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_unref (struct roar_vio_calls * vio) _LIBROAR_ATTR_NONNULL_ALL; // special commands: int roar_vio_accept (struct roar_vio_calls * calls, struct roar_vio_calls * dst) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_shutdown(struct roar_vio_calls * vio, int how) _LIBROAR_ATTR_NONNULL_ALL; // converters: int roar_vio_open_fh (struct roar_vio_calls * calls, int fh) _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_open_fh_socket(struct roar_vio_calls * calls, int fh) _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_open_socket (struct roar_vio_calls * calls, const char * host, int port) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_open_socket_listen(struct roar_vio_calls * calls, int type, const char * host, int port) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_simple_stream (struct roar_vio_calls * calls, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, const char * server, int dir, const char * name, int mixer); int roar_vio_simple_new_stream_obj (struct roar_vio_calls * calls, struct roar_connection * con, struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, int dir, int mixer); // possible VIOs: // basic ssize_t roar_vio_basic_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_basic_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_basic_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int roar_vio_basic_sync (struct roar_vio_calls * vio); int roar_vio_basic_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_basic_close (struct roar_vio_calls * vio); // null // this is a read and write in one! ssize_t roar_vio_null_rw (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_null_sync (struct roar_vio_calls * vio); // pass int roar_vio_open_pass (struct roar_vio_calls * calls, struct roar_vio_calls * dst); ssize_t roar_vio_pass_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_pass_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_pass_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int roar_vio_pass_sync (struct roar_vio_calls * vio); int roar_vio_pass_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_pass_close (struct roar_vio_calls * vio); // re-read/write int roar_vio_open_re (struct roar_vio_calls * calls, struct roar_vio_calls * dst); ssize_t roar_vio_re_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_re_write(struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_re_lseek(struct roar_vio_calls * vio, roar_off_t offset, int whence); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_bio.h�������������������������������������������������������0000644�0001750�0001750�00000003202�12264733472�017342� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_bio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_BIO_H_ #define _LIBROARVIO_BIO_H_ #include "libroar.h" int roar_vio_open_bio (struct roar_vio_calls * calls, void * bio); void * roar_vio_to_bio (struct roar_vio_calls * calls); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_buffer.h����������������������������������������������������0000644�0001750�0001750�00000004650�12264733472�020052� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_buffer.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_BUFFER_H_ #define _LIBROARVIO_BUFFER_H_ #include "libroar.h" struct roar_vio_buffer_offset { int is_old; size_t offset; }; struct roar_vio_buffer { struct roar_vio_calls * backend; struct roar_buffer * buf_old, * buf_cur; size_t len_old, len_cur; ssize_t min_bufsize; struct roar_vio_buffer_offset offset; struct roar_vio_calls re_vio; int use_re; size_t abspos; }; int roar_vio_open_buffer (struct roar_vio_calls * calls, struct roar_vio_calls * dst, ssize_t minsize, int use_re); ssize_t roar_vio_buffer_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_buffer_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_buffer_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int roar_vio_buffer_sync (struct roar_vio_calls * vio); int roar_vio_buffer_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_buffer_close (struct roar_vio_calls * vio); #endif //ll ����������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_buffer_store.h����������������������������������������������0000644�0001750�0001750�00000004327�12264733473�021270� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_buffer_store.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_BUFFER_STORE_H_ #define _LIBROARVIO_BUFFER_STORE_H_ #include "libroar.h" struct roar_vio_buffer_store { struct roar_buffer * in, * out; }; int roar_vio_open_buffer_store (struct roar_vio_calls * calls, struct roar_vio_buffer_store ** inst); ssize_t roar_vio_buffer_store_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_buffer_store_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_buffer_store_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int roar_vio_buffer_store_sync (struct roar_vio_calls * vio); int roar_vio_buffer_store_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_buffer_store_close (struct roar_vio_calls * vio); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_cmd.h�������������������������������������������������������0000644�0001750�0001750�00000007464�12264733473�017353� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_cmd.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_CMD_H_ #define _LIBROARVIO_CMD_H_ #include "libroar.h" #define ROAR_VIO_CMD_OPTS_NONE 0x00 #define ROAR_VIO_CMD_OPTS_NONBLOCK 0x01 #define ROAR_VIO_CMD_OPTS_ON_DEMAND 0x02 #define ROAR_VIO_CMD_BUFSIZE 1024 #define ROAR_VIO_CMD_STATE_NONE 0 #define ROAR_VIO_CMD_STATE_OPEN 1 #define ROAR_VIO_CMD_STATE_CLOSING 2 #define ROAR_VIO_CMD_STATE_CLOSED 3 // for OpenPGP interface: #define ROAR_VIO_PGP_OPTS_NONE 0x00 #define ROAR_VIO_PGP_OPTS_ASCII 0x01 #define ROAR_VIO_PGP_OPTS_SIGN 0x02 #define ROAR_VIO_PGP_OPTS_TEXTMODE 0x04 struct roar_vio_cmd_child { int opened; pid_t pid; int in; int out; char * cmd; }; struct roar_vio_cmd_state { struct roar_vio_calls * next; int options; int state; struct roar_vio_cmd_child reader; struct roar_vio_cmd_child writer; }; struct roar_vio_2popen_state { int options; int state; struct roar_vio_cmd_child child; }; int roar_vio_open_cmd(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * reader, char * writer, int options); int roar_vio_cmd_close(struct roar_vio_calls * vio); int roar_vio_cmd_fork(struct roar_vio_cmd_child * child); int roar_vio_cmd_wait(struct roar_vio_cmd_child * child); int roar_vio_open_2popen(struct roar_vio_calls * calls, char * command, int options); int roar_vio_2popen_close(struct roar_vio_calls * vio); // possible VIOs: // cmd: ssize_t roar_vio_cmd_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_cmd_write (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_cmd_sync (struct roar_vio_calls * vio); int roar_vio_cmd_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); // MISC: int roar_vio_open_gzip(struct roar_vio_calls * calls, struct roar_vio_calls * dst, int level); int roar_vio_open_gpg(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw, int wronly, char * opts, int options); int roar_vio_open_pgp_decrypt(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw); int roar_vio_open_pgp_store(struct roar_vio_calls * calls, struct roar_vio_calls * dst, int options); int roar_vio_open_pgp_encrypt_sym(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw, int options); int roar_vio_open_pgp_encrypt_pub(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw, int options, char * recipient); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_ctl.h�������������������������������������������������������0000644�0001750�0001750�00000024022�12264733473�017357� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_ctl.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_CTL_H_ #define _LIBROARVIO_CTL_H_ #include "libroar.h" // CTLs: /* * 0xAAAABBBB * AAAA: * 0x0001 -> Basic stream calls * 0x0002 -> Driver calls * * BBBB: * 0x0XXX -> Client * 0x1XXX -> Server */ #define ROAR_VIO_CTL_GET 0x1UL #define ROAR_VIO_CTL_SET 0x2UL #define ROAR_VIO_CTL_CLIENT 0x0000UL #define ROAR_VIO_CTL_SERVER 0x1000UL #define ROAR_VIO_CTL_GENERIC (0x0000UL<<16) #define ROAR_VIO_CTL_STREAM (0x0001UL<<16) #define ROAR_VIO_CTL_DRIVER (0x0002UL<<16) // basic calls: #define ROAR_VIO_CTL_GET_NEXT (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0100) #define ROAR_VIO_CTL_SET_NEXT (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0100) #define ROAR_VIO_CTL_GET_FH (ROAR_VIO_CTL_GENERIC|0x0110) #define ROAR_VIO_CTL_GET_READ_FH (ROAR_VIO_CTL_GENERIC|0x0111) #define ROAR_VIO_CTL_GET_WRITE_FH (ROAR_VIO_CTL_GENERIC|0x0112) #define ROAR_VIO_CTL_GET_SELECT_FH (ROAR_VIO_CTL_GENERIC|0x0113) #define ROAR_VIO_CTL_GET_SELECT_READ_FH (ROAR_VIO_CTL_GENERIC|0x0114) #define ROAR_VIO_CTL_GET_SELECT_WRITE_FH (ROAR_VIO_CTL_GENERIC|0x0115) #define ROAR_VIO_CTL_SELECT (ROAR_VIO_CTL_GENERIC|0x0120) #define ROAR_VIO_CTL_GET_UMMAP (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0130) /* Use mmap(), int as bool */ #define ROAR_VIO_CTL_SET_UMMAP (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0130) /* ** */ #define ROAR_VIO_CTL_GET_SHUTDOWN (ROAR_VIO_CTL_GENERIC|0x0140) /* shutdown(), need specs */ #define ROAR_VIO_CTL_SET_NOSYNC (ROAR_VIO_CTL_GENERIC|0x0150) /* delete call of vio sync() from object */ #define ROAR_VIO_CTL_GET_NAME (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0160) /* get name of VIO */ #define ROAR_VIO_CTL_ACCEPT (ROAR_VIO_CTL_GENERIC|0x0170) /* accept(), vio* */ #define ROAR_VIO_CTL_SHUTDOWN (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0174) /* shutdown(), int */ #define ROAR_VIO_CTL_SYSIO_IOCTL (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0180) /* ioctl(), */ /* struct roar_vio_sysio_ioctl* */ #define ROAR_VIO_CTL_FSTAT (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0184) /* fstat() */ #define ROAR_VIO_CTL_GET_SOCKNAME (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0188) /* getsockname() */ #define ROAR_VIO_CTL_GET_PEERNAME (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x018C) /* getpeername() */ // NOTE: The following two blocks have some discontinuity in the used IDs: // 0x0190 was used by both ROAR_VIO_CTL_[GS]ET_SYSIO_SOCKOPT and ROAR_VIO_CTL_[GS]ET_MIMETYPE. // we fixed this by changeing IDs for both and add new consts for the conflicting IDs. // roar_vio_ctl() will print a warning if they are used. #define ROAR_VIO_CTL_CONFLICTING_ID_0 (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0190) #define ROAR_VIO_CTL_CONFLICTING_ID_1 (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0190) #define ROAR_VIO_CTL_GET_SYSIO_SOCKOPT (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0198) /* getsockopt() */ #define ROAR_VIO_CTL_SET_SYSIO_SOCKOPT (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0198) /* setsockopt() */ // more about network based protocols: #define ROAR_VIO_CTL_GET_MIMETYPE (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x019C) #define ROAR_VIO_CTL_SET_MIMETYPE (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x019C) #define ROAR_VIO_CTL_GET_USERPASS (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0194) #define ROAR_VIO_CTL_SET_USERPASS (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0194) // Implement roar_vio_nonblock()... #define ROAR_VIO_CTL_NONBLOCK (ROAR_VIO_CTL_GENERIC|0x01A0) /* roar_vio_nonblock(), int */ // get or set data format used for read and write calls, see below #define ROAR_VIO_CTL_GET_DATA_FORMAT (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_GET|0x0170) #define ROAR_VIO_CTL_SET_DATA_FORMAT (ROAR_VIO_CTL_GENERIC|ROAR_VIO_CTL_SET|0x0170) // stream: #define ROAR_VIO_CTL_SET_STREAM (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_CLIENT|ROAR_VIO_CTL_SET) /* normal streams */ #define ROAR_VIO_CTL_GET_STREAM (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_CLIENT|ROAR_VIO_CTL_GET) #define ROAR_VIO_CTL_SET_DMXSCHAN (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_CLIENT|ROAR_VIO_CTL_SET|0x10) /* simple DMX Channel */ #define ROAR_VIO_CTL_GET_DMXSCHAN (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_CLIENT|ROAR_VIO_CTL_GET|0x10) #define ROAR_VIO_CTL_SET_DMXUNIV (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_CLIENT|ROAR_VIO_CTL_SET|0x20) /* DMX Universe */ #define ROAR_VIO_CTL_GET_DMXUNIV (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_CLIENT|ROAR_VIO_CTL_GET|0x20) #define ROAR_VIO_CTL_SET_SSTREAM (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_SERVER|ROAR_VIO_CTL_SET) /* server streams */ #define ROAR_VIO_CTL_GET_SSTREAM (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_SERVER|ROAR_VIO_CTL_GET) #define ROAR_VIO_CTL_SET_SSTREAMID (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_SERVER|ROAR_VIO_CTL_SET|0x10) /* server streams */ #define ROAR_VIO_CTL_GET_SSTREAMID (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_SERVER|ROAR_VIO_CTL_GET|0x10) #define ROAR_VIO_CTL_SET_AUINFO (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_SET|0x2000) /* set a struct roar_audio_info */ #define ROAR_VIO_CTL_GET_AUINFO (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_GET|0x2000) /* get a struct roar_audio_info */ #define ROAR_VIO_CTL_GET_DELAY (ROAR_VIO_CTL_STREAM|ROAR_VIO_CTL_GET|0x010) /* return in bytes as the vio interface */ /* does not know anything about streams */ #define ROAR_VIO_CTL_GET_DBLOCKS (ROAR_VIO_CTL_DRIVER|0x0001) /* get Driver Blocks */ #define ROAR_VIO_CTL_SET_DBLOCKS (ROAR_VIO_CTL_DRIVER|0x0002) /* set Driver Blocks */ #define ROAR_VIO_CTL_GET_DBLKSIZE (ROAR_VIO_CTL_DRIVER|0x0003) /* get Driver Blocks size (in byte) */ #define ROAR_VIO_CTL_SET_DBLKSIZE (ROAR_VIO_CTL_DRIVER|0x0004) /* set Driver Blocks size (in byte) */ #define ROAR_VIO_CTL_GET_VOLUME (ROAR_VIO_CTL_DRIVER|ROAR_VIO_CTL_GET|0x10) #define ROAR_VIO_CTL_SET_VOLUME (ROAR_VIO_CTL_DRIVER|ROAR_VIO_CTL_SET|0x10) #define ROAR_VIO_CTL_GET_RECORD (ROAR_VIO_CTL_DRIVER|ROAR_VIO_CTL_GET|0x20) /* int */ #define ROAR_VIO_CTL_SET_RECORD (ROAR_VIO_CTL_DRIVER|ROAR_VIO_CTL_SET|0x20) /* int */ // consts for ROAR_VIO_CTL_SHUTDOWN: #define ROAR_VIO_SHUTDOWN_READ 0x1 #define ROAR_VIO_SHUTDOWN_WRITE 0x2 #define ROAR_VIO_SHUTDOWN_LISTEN 0x4 /* like close() on listen sock but allow padding requests */ /* to be accept()ed */ #define ROAR_VIO_SHUTDOWN_RW (ROAR_VIO_SHUTDOWN_READ|ROAR_VIO_SHUTDOWN_WRITE) // Data format used for read/write(): // _D_ata _F_ormat _T_ypes: // generic types: #define ROAR_VIO_DFT_UNKNOWN -1 #define ROAR_VIO_DFT_NULL 0x0000 #define ROAR_VIO_DFT_RAW 0x0001 /* raw bytes, default */ #define ROAR_VIO_DFT_PACKET 0x0002 /* a packet of some kind including headers */ #define ROAR_VIO_DFT_UNFRAMED 0x0003 /* a packet of some kind excluding headers */ // RoarAudio types: #define ROAR_VIO_DFT_RA_MESSAGE 0x0101 #define ROAR_VIO_DFT_RA_BUFFER 0x0102 // extern types: #define ROAR_VIO_DFT_OGG_PAGE 0x0201 #define ROAR_VIO_DFT_OGG_PACKET 0x0202 struct roar_vio_dataformat { unsigned int type; }; struct roar_vio_sysio_ioctl { long long int cmd; void * argp; }; struct roar_vio_sysio_sockopt { int level; int optname; void * optval; socklen_t optlen; }; #if 0 struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ X mode_t st_mode; /* protection */ X nlink_t st_nlink; /* number of hard links */ X uid_t st_uid; /* user ID of owner */ X gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ X off_t st_size; /* total size, in bytes */ X blksize_t st_blksize; /* blocksize for filesystem I/O */ X blkcnt_t st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ }; #endif struct roar_vio_stat { mode_t mode; size_t linkc; uid_t uid; gid_t gid; size_t size; size_t blksize; size_t blocks; }; // struct for userpass: struct roar_userpass { int subtype; char * user; char * pass; }; // for ROAR_VIO_CTL_GET_SOCKNAME and ROAR_VIO_CTL_GET_PEERNAME struct roar_sockname { int flags; int type; char * addr; int port; }; #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_dstr.h������������������������������������������������������0000644�0001750�0001750�00000024161�12264733473�017555� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_dstr.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_DSTR_H_ #define _LIBROARVIO_DSTR_H_ #include "libroar.h" #define ROAR_VIO_DEF_TYPE_EOL -1 #define ROAR_VIO_DEF_TYPE_NONE 0 #define ROAR_VIO_DEF_TYPE_FILE 1 #define ROAR_VIO_DEF_TYPE_SOCKET 2 #define ROAR_VIO_DEF_TYPE_FH 3 #define ROAR_VIO_DEF_TYPE_SOCKETFH 4 #define ROAR_VIO_DSTR_OBJGT_INTERNAL 0x0000 #define ROAR_VIO_DSTR_OBJGT_GEN 0x0100 #define ROAR_VIO_DSTR_OBJGT_SOCKET 0x0200 #define ROAR_VIO_DSTR_OBJGT_PROXY 0x0300 #define ROAR_VIO_DSTR_OBJGT_COMP 0x0400 /* compression */ #define ROAR_VIO_DSTR_OBJGT_CRYPT 0x0500 #define ROAR_VIO_DSTR_OBJGT_PROTO 0x0600 /* protocolls like HTTP and Gopher */ #define ROAR_VIO_DSTR_OBJGT_CONTENT 0x0700 /* things changeing the content of the data */ #define ROAR_VIO_DSTR_OBJGT_MUX 0x0800 /* muxers and demuxers */ #define ROAR_VIO_DSTR_OBJGT_SPECAL 0xff00 #define ROAR_VIO_DSTR_OBJT_EOL -1 #define ROAR_VIO_DSTR_OBJT_NONE 0 #define ROAR_VIO_DSTR_OBJT_INTERNAL 1 #define ROAR_VIO_DSTR_OBJT_FILE (0x01|ROAR_VIO_DSTR_OBJGT_GEN) #define ROAR_VIO_DSTR_OBJT_FH (0x02|ROAR_VIO_DSTR_OBJGT_GEN) #define ROAR_VIO_DSTR_OBJT_FD ROAR_VIO_DSTR_OBJT_FH #define ROAR_VIO_DSTR_OBJT_SOCKETFH (0x03|ROAR_VIO_DSTR_OBJGT_GEN) /* some space to add memory FHs and the like */ #define ROAR_VIO_DSTR_OBJT_PASS (0x10|ROAR_VIO_DSTR_OBJGT_GEN) #define ROAR_VIO_DSTR_OBJT_RE (0x11|ROAR_VIO_DSTR_OBJGT_GEN) #define ROAR_VIO_DSTR_OBJT_JUMBO (0x12|ROAR_VIO_DSTR_OBJGT_GEN) #define ROAR_VIO_DSTR_OBJT_EXEC (0x20|ROAR_VIO_DSTR_OBJGT_GEN) /* special devices */ #define ROAR_VIO_DSTR_OBJT_NULL (0x30|ROAR_VIO_DSTR_OBJGT_GEN) /* /dev/null */ #define ROAR_VIO_DSTR_OBJT_ZERO (0x31|ROAR_VIO_DSTR_OBJGT_GEN) /* /dev/zero */ #define ROAR_VIO_DSTR_OBJT_FULL (0x32|ROAR_VIO_DSTR_OBJGT_GEN) /* /dev/full */ #define ROAR_VIO_DSTR_OBJT_SOCKET (0x01|ROAR_VIO_DSTR_OBJGT_SOCKET) #define ROAR_VIO_DSTR_OBJT_UNIX (0x02|ROAR_VIO_DSTR_OBJGT_SOCKET) #define ROAR_VIO_DSTR_OBJT_DECNET (0x10|ROAR_VIO_DSTR_OBJGT_SOCKET) #define ROAR_VIO_DSTR_OBJT_TCP (0x21|ROAR_VIO_DSTR_OBJGT_SOCKET) #define ROAR_VIO_DSTR_OBJT_UDP (0x22|ROAR_VIO_DSTR_OBJGT_SOCKET) #define ROAR_VIO_DSTR_OBJT_TCP6 (0x31|ROAR_VIO_DSTR_OBJGT_SOCKET) #define ROAR_VIO_DSTR_OBJT_UDP6 (0x32|ROAR_VIO_DSTR_OBJGT_SOCKET) #define ROAR_VIO_DSTR_OBJT_SOCKS (0x10|ROAR_VIO_DSTR_OBJGT_PROXY) #define ROAR_VIO_DSTR_OBJT_SOCKS4 (0x14|ROAR_VIO_DSTR_OBJGT_PROXY) #define ROAR_VIO_DSTR_OBJT_SOCKS4A (0x1a|ROAR_VIO_DSTR_OBJGT_PROXY) #define ROAR_VIO_DSTR_OBJT_SOCKS4D (0x1d|ROAR_VIO_DSTR_OBJGT_PROXY) #define ROAR_VIO_DSTR_OBJT_SOCKS5 (0x15|ROAR_VIO_DSTR_OBJGT_PROXY) #define ROAR_VIO_DSTR_OBJT_SSH (0x21|ROAR_VIO_DSTR_OBJGT_PROXY) //#define ROAR_VIO_DSTR_OBJT_HTTP (0x31|ROAR_VIO_DSTR_OBJGT_PROXY) //#define ROAR_VIO_DSTR_OBJT_HTTP (0x10|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_HTTP09 (0x11|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_HTTP10 (0x12|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_HTTP11 (0x13|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_HTTP ROAR_VIO_DSTR_OBJT_HTTP11 #define ROAR_VIO_DSTR_OBJT_GOPHER (0x21|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_GOPHER_PLUS (0x22|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_ICY (0x31|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_RTP2 (0x42|ROAR_VIO_DSTR_OBJGT_PROTO) #define ROAR_VIO_DSTR_OBJT_RTP ROAR_VIO_DSTR_OBJT_RTP2 /* #define ROAR_VIO_DSTR_OBJGT_CRYPT 0x0500 */ #define ROAR_VIO_DSTR_OBJT_GZIP (0x10|ROAR_VIO_DSTR_OBJGT_COMP) #define ROAR_VIO_DSTR_OBJT_ZLIB (0x11|ROAR_VIO_DSTR_OBJGT_COMP) #define ROAR_VIO_DSTR_OBJT_BZIP2 (0x22|ROAR_VIO_DSTR_OBJGT_COMP) #define ROAR_VIO_DSTR_OBJT_PGP (0x10|ROAR_VIO_DSTR_OBJGT_CRYPT) #define ROAR_VIO_DSTR_OBJT_PGP_ENC (0x11|ROAR_VIO_DSTR_OBJGT_CRYPT) #define ROAR_VIO_DSTR_OBJT_PGP_STORE (0x12|ROAR_VIO_DSTR_OBJGT_CRYPT) #define ROAR_VIO_DSTR_OBJT_SSL1 (0x21|ROAR_VIO_DSTR_OBJGT_CRYPT) #define ROAR_VIO_DSTR_OBJT_SSL2 (0x22|ROAR_VIO_DSTR_OBJGT_CRYPT) #define ROAR_VIO_DSTR_OBJT_SSL3 (0x23|ROAR_VIO_DSTR_OBJGT_CRYPT) #define ROAR_VIO_DSTR_OBJT_TLS (0x2a|ROAR_VIO_DSTR_OBJGT_CRYPT) #define ROAR_VIO_DSTR_OBJT_SSLTLS ROAR_VIO_DSTR_OBJT_TLS /* Random numbers, 0x30+ROAR_RANDOM_* */ #define ROAR_VIO_DSTR_OBJT_NRANDOM (0x31|ROAR_VIO_DSTR_OBJGT_CRYPT) /* nonce */ #define ROAR_VIO_DSTR_OBJT_URANDOM (0x33|ROAR_VIO_DSTR_OBJGT_CRYPT) /* like urandom */ #define ROAR_VIO_DSTR_OBJT_SRANDOM (0x34|ROAR_VIO_DSTR_OBJGT_CRYPT) /* strong random */ #define ROAR_VIO_DSTR_OBJT_TRANSCODE (0x10|ROAR_VIO_DSTR_OBJGT_CONTENT) #define ROAR_VIO_DSTR_OBJT_RAUM (0x11|ROAR_VIO_DSTR_OBJGT_MUX) #define ROAR_VIO_DSTR_OBJT_OGG (0x12|ROAR_VIO_DSTR_OBJGT_MUX) #define ROAR_VIO_DSTR_OBJT_TAR (0x13|ROAR_VIO_DSTR_OBJGT_MUX) #define ROAR_VIO_DSTR_OBJT_MAGIC (0x01|ROAR_VIO_DSTR_OBJGT_SPECAL) #define ROAR_VIO_DSTR_OBJT_TANTALOS (0x02|ROAR_VIO_DSTR_OBJGT_SPECAL) struct roar_vio_defaults { int type; mode_t o_mode; int o_flags; union { const char * file; int fh; struct { int domain; int type; const char * host; union { struct sockaddr sa; #ifdef ROAR_HAVE_IPV4 struct sockaddr_in in; #endif #ifdef ROAR_HAVE_UNIX struct sockaddr_un un; #endif #ifdef ROAR_HAVE_LIBDNET struct sockaddr_dn dn; #endif #ifdef ROAR_HAVE_IPV6 struct sockaddr_in6 in6; #endif #ifdef ROAR_HAVE_IPX struct sockaddr_ipx ipx; #endif } sa; socklen_t len; } socket; } d; }; #define ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN 16 struct roar_vio_dstr_chain { int type; char * opts; char * dst; int need_vio; struct roar_vio_defaults * def; struct roar_vio_calls * vio; struct roar_vio_defaults store_def; }; struct roar_vio_dstr_pathelement { const char * dstr; int flags; }; // PEF = Path Element Flag #define ROAR_VIO_DSTR_PEF_NONE 0x0000 #define ROAR_VIO_DSTR_PEF_IS_DIR 0x0001 #define ROAR_VIO_DSTR_PEF_ALLOW_MULTI 0x0100 #define ROAR_VIO_DSTR_PEF_ALLOW_PARENT 0x0200 #define ROAR_VIO_DSTR_PEF_ALLOW_ABSOLUTE 0x0400 #define ROAR_VIO_DSTR_PEF_ALLOW_ALL (ROAR_VIO_DSTR_PEF_ALLOW_MULTI|ROAR_VIO_DSTR_PEF_ALLOW_PARENT|ROAR_VIO_DSTR_PEF_ALLOW_ABSOLUTE) int roar_vio_dstr_get_type(const char * str); const char * roar_vio_dstr_get_name(const int type); int roar_vio_dstr_register_type(int type, char *name, int (*setdef) (struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next), int (*openvio)(struct roar_vio_calls * calls, struct roar_vio_calls * dst, struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next)); int roar_vio_dstr_init_defaults (struct roar_vio_defaults * def, int type, int o_flags, mode_t o_mode); int roar_vio_dstr_init_defaults_c (struct roar_vio_defaults * def, int type, struct roar_vio_defaults * odef, int o_flags); int roar_vio_open_default (struct roar_vio_calls * calls, struct roar_vio_defaults * def, char * opts); int roar_vio_open_dstr_simple(struct roar_vio_calls * calls, const char * dstr, int o_flags); struct roar_vio_calls * roar_vio_open_dstr_simple_new(const char * dstr, int o_flags); int roar_vio_open_dstr (struct roar_vio_calls * calls, const char * dstr, struct roar_vio_defaults * def, int dnum); int roar_vio_open_dstr_vio(struct roar_vio_calls * calls, const char * dstr, struct roar_vio_defaults * def, int dnum, struct roar_vio_calls * vio); int roar_vio_dstr_parse_opts(struct roar_vio_dstr_chain * chain); int roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain, int len, struct roar_vio_defaults * def, int dnum); int roar_vio_dstr_build_chain(struct roar_vio_dstr_chain * chain, struct roar_vio_calls * calls, struct roar_vio_calls * vio); char * roar_vio_dstr_cat(char * buffer, ssize_t bufferlen, const struct roar_vio_dstr_pathelement * elements, size_t elementslen); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_jumbo.h�����������������������������������������������������0000644�0001750�0001750�00000004325�12264733473�017715� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_jumbo.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_JUMBO_H_ #define _LIBROARVIO_JUMBO_H_ #include "libroar.h" struct roar_vio_jumbo { struct roar_buffer * buffer; struct roar_vio_calls * backend; size_t pos; }; int roar_vio_open_jumbo (struct roar_vio_calls * calls, struct roar_vio_calls * vio, size_t buffersize); ssize_t roar_vio_jumbo_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_jumbo_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_jumbo_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int roar_vio_jumbo_sync (struct roar_vio_calls * vio); int roar_vio_jumbo_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_jumbo_close (struct roar_vio_calls * vio); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_magic.h�����������������������������������������������������0000644�0001750�0001750�00000003305�12264733473�017656� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_magic.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_MAGIC_H_ #define _LIBROARVIO_MAGIC_H_ #include "libroar.h" #if 0 struct roar_vio_magic { struct roar_buffer * inp; struct roar_stack vios; }; int roar_vio_open_magic (struct roar_vio_calls * calls, struct roar_vio_calls * dst, int * codec); #endif #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_misc.h������������������������������������������������������0000644�0001750�0001750�00000003740�12264733473�017534� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_misc.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_MISC_H_ #define _LIBROARVIO_MISC_H_ #include "libroar.h" struct roar_vio_misc { const char * name; const int support_nonblocking; ssize_t (*read )(void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks); ssize_t (*write)(void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks); }; int roar_vio_open_misc (struct roar_vio_calls * calls, const struct roar_vio_misc * callbacks); int roar_vio_open_misc_by_name(struct roar_vio_calls * calls, const char * name); #endif //ll ��������������������������������roaraudio-1.0beta11/include/libroar/vio_ops.h�������������������������������������������������������0000644�0001750�0001750�00000004015�12264733473�017376� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_ops.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_OPS_H_ #define _LIBROARVIO_OPS_H_ #include "libroar.h" #define ROAR_VIO_TEE_MAX_SLOTS 32 struct roar_vio_tee { int next; struct roar_vio_calls * slots[ROAR_VIO_TEE_MAX_SLOTS]; }; struct roar_split { struct roar_vio_calls * reader; struct roar_vio_calls * writer; }; ssize_t roar_vio_copy_data (struct roar_vio_calls * out, struct roar_vio_calls * in) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_open_tee (struct roar_vio_calls * calls); int roar_vio_open_split (struct roar_vio_calls * calls, struct roar_vio_calls * reader, struct roar_vio_calls * writer); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_pipe.h������������������������������������������������������0000644�0001750�0001750�00000005420�12264733474�017534� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_pipe.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_PIPE_H_ #define _LIBROARVIO_PIPE_H_ #include "libroar.h" #define ROAR_VIO_PIPE_TYPE_AUTO -1 #define ROAR_VIO_PIPE_TYPE_AUTO_FORK ROAR_VIO_PIPE_TYPE_AUTO #define ROAR_VIO_PIPE_TYPE_AUTO_NOFORK ROAR_VIO_PIPE_TYPE_AUTO #define ROAR_VIO_PIPE_TYPE_NONE 0 #define ROAR_VIO_PIPE_TYPE_BUFFER 1 #define ROAR_VIO_PIPE_TYPE_PIPE 2 #define ROAR_VIO_PIPE_TYPE_SOCKET 3 #define ROAR_VIO_PIPE_S(self,stream) ((self->s0) == (stream) ? 0 : 1) #define ROAR_VIO_PIPE_SR(self,stream) ((self->s0) == (stream) ? 1 : 0) #define ROAR_VIO_PIPE_SF(self,stream) ROAR_VIO_PIPE_S(self,stream) struct roar_vio_pipe { int refcount; int type; int flags; union { struct roar_buffer * b[2]; int p[4]; } b; struct roar_vio_calls * s0; }; int roar_vio_open_pipe (struct roar_vio_calls * s0, struct roar_vio_calls * s1, int type, int flags); int roar_vio_pipe_init (struct roar_vio_calls * s, struct roar_vio_pipe * self, int flags); ssize_t roar_vio_pipe_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_pipe_write (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_pipe_sync (struct roar_vio_calls * vio); int roar_vio_pipe_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_pipe_close (struct roar_vio_calls * vio); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_proto.h�����������������������������������������������������0000644�0001750�0001750�00000005572�12264733474�017752� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_proto.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_PROTO_H_ #define _LIBROARVIO_PROTO_H_ #include "libroar.h" struct roar_vio_defaults; #define ROAR_VIO_PROTO_P_NONE 0 #define ROAR_VIO_PROTO_P_HTTP 1 #define ROAR_VIO_PROTO_P_GOPHER 2 #define ROAR_VIO_PROTO_P_ICY 3 struct roar_vio_proto { struct roar_vio_calls * next; struct { struct roar_buffer * buffer; } reader, writer; struct { size_t metaint; size_t leftint; struct roar_buffer * mdbuf; } metadata; char * content_type; int proto; }; int roar_vio_proto_init_def (struct roar_vio_defaults * def, char * dstr, int proto, struct roar_vio_defaults * odef); int roar_vio_open_proto (struct roar_vio_calls * calls, struct roar_vio_calls * dst, const char * dstr, int proto, struct roar_vio_defaults * odef); ssize_t roar_vio_proto_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_proto_write (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_proto_sync (struct roar_vio_calls * vio); int roar_vio_proto_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_proto_close (struct roar_vio_calls * vio); int roar_vio_open_proto_http (struct roar_vio_calls * calls, struct roar_vio_calls * dst, const char * host, const char * file, struct roar_userpass * up); int roar_vio_open_proto_gopher (struct roar_vio_calls * calls, struct roar_vio_calls * dst, const char * host, const char * file); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_proxy.h�����������������������������������������������������0000644�0001750�0001750�00000005560�12264733474�017765� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_proxy.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_PROXY_H_ #define _LIBROARVIO_PROXY_H_ #include "libroar.h" enum roar_vio_proxy_type { ROAR_VIO_PROXY_INVALID = -1, ROAR_VIO_PROXY_NONE = 0, #define ROAR_VIO_PROXY_NONE ROAR_VIO_PROXY_NONE ROAR_VIO_PROXY_SOCKS = 1, /* unknown version */ #define ROAR_VIO_PROXY_SOCKS ROAR_VIO_PROXY_SOCKS ROAR_VIO_PROXY_SOCKS4 = 2, #define ROAR_VIO_PROXY_SOCKS4 ROAR_VIO_PROXY_SOCKS4 ROAR_VIO_PROXY_SOCKS4a = 3, #define ROAR_VIO_PROXY_SOCKS4a ROAR_VIO_PROXY_SOCKS4a ROAR_VIO_PROXY_SOCKS4d = 4, #define ROAR_VIO_PROXY_SOCKS4d ROAR_VIO_PROXY_SOCKS4d ROAR_VIO_PROXY_SOCKS5 = 5, #define ROAR_VIO_PROXY_SOCKS5 ROAR_VIO_PROXY_SOCKS5 ROAR_VIO_PROXY_HTTP = 6, #define ROAR_VIO_PROXY_HTTP ROAR_VIO_PROXY_HTTP ROAR_VIO_PROXY_SSH = 7 #define ROAR_VIO_PROXY_SSH ROAR_VIO_PROXY_SSH }; int roar_vio_proxy_init_def(struct roar_vio_defaults * def, char * dstr, enum roar_vio_proxy_type type, struct roar_vio_defaults * odef); int roar_vio_open_proxy (struct roar_vio_calls * calls, struct roar_vio_calls * dst, enum roar_vio_proxy_type type, struct roar_vio_defaults * odef); // DSTR interface: struct roar_vio_dstr_chain; int roar_vio_proxy_setdef(struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next); int roar_vio_proxy_openvio(struct roar_vio_calls * calls, struct roar_vio_calls * dst, struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_rtp.h�������������������������������������������������������0000644�0001750�0001750�00000011757�12264733474�017416� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_rtp.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_RTP_H_ #define _LIBROARVIO_RTP_H_ #include "libroar.h" #define ROAR_RTP_FLAG_PADDING 0x02 #define ROAR_RTP_FLAG_EXTENSION 0x03 #define ROAR_RTP_FLAG_MARKER 0x08 /* RFC 3551 RTP A/V Profile July 2003 PT encoding media type clock rate channels name (Hz) ___________________________________________________ 0 PCMU A 8,000 1 1 reserved A 2 reserved A 3 GSM A 8,000 1 4 G723 A 8,000 1 5 DVI4 A 8,000 1 6 DVI4 A 16,000 1 7 LPC A 8,000 1 8 PCMA A 8,000 1 9 G722 A 8,000 1 10 L16 A 44,100 2 11 L16 A 44,100 1 12 QCELP A 8,000 1 13 CN A 8,000 1 14 MPA A 90,000 (see text) 15 G728 A 8,000 1 16 DVI4 A 11,025 1 17 DVI4 A 22,050 1 18 G729 A 8,000 1 19 reserved A 20 unassigned A 21 unassigned A 22 unassigned A 23 unassigned A dyn G726-40 A 8,000 1 dyn G726-32 A 8,000 1 dyn G726-24 A 8,000 1 dyn G726-16 A 8,000 1 dyn G729D A 8,000 1 dyn G729E A 8,000 1 dyn GSM-EFR A 8,000 1 dyn L8 A var. var. dyn RED A (see text) dyn VDVI A var. 1 Table 4: Payload types (PT) for audio encodings */ #define ROAR_RTP_PT_A_PCMU 0 /* mu-Law */ #define ROAR_RTP_PT_A_PCMA 8 /* A-Law */ #define ROAR_RTP_PT_A_L16_441_2 10 #define ROAR_RTP_PT_A_L16_441_1 11 #define ROAR_RTP_PT_UNKNOWN 127 /* non standard asignment */ struct roar_rtp_header { int version; int flags; int csrc_count; int payload_type; uint16_t seq_num; uint32_t ts; uint32_t ssrc; uint32_t csrc[16]; }; struct roar_rtp_inst { struct roar_vio_calls * vio; struct roar_rtp_header header; struct roar_buffer * io; struct roar_audio_info info; size_t mtu; int bpf; // byte per frame // read speific things struct roar_buffer * rx_decoded; // buffer to hold allready decoded data }; int roar_vio_open_rtp (struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * dstr, struct roar_vio_defaults * odef); ssize_t roar_vio_rtp_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_rtp_write (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_rtp_sync (struct roar_vio_calls * vio); int roar_vio_rtp_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_rtp_close (struct roar_vio_calls * vio); #endif //ll �����������������roaraudio-1.0beta11/include/libroar/vio_select.h����������������������������������������������������0000644�0001750�0001750�00000005133�12264733474�020057� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_select.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_SELECT_H_ #define _LIBROARVIO_SELECT_H_ #include "libroar.h" #define ROAR_VIO_SELECT_NONE 0x0000 #define ROAR_VIO_SELECT_READ 0x0001 #define ROAR_VIO_SELECT_WRITE 0x0002 #define ROAR_VIO_SELECT_EXCEPT 0x0004 #define ROAR_VIO_SELECT_NO_RETEST 0x4000 /* uppermostt bit set */ #define ROAR_VIO_SELECT_ACTION_NONE 0x00 #define ROAR_VIO_SELECT_ACTION_SELECT 0x01 #define ROAR_VIO_SELECT_ACTION_POLL 0x02 #define ROAR_VIO_SELECT_ACTION_VIOS 0x04 /* VIO Select */ #define ROAR_VIO_SELECT_SETVIO(d,v,q) ((d)->vio = (v)); ((d)->fh = -1); ((d)->eventsq = (q)) #define ROAR_VIO_SELECT_SETSYSIO(d,f,q) ((d)->vio = NULL); ((d)->fh = (f)); ((d)->eventsq = (q)) struct roar_vio_select_internal { int action; int fh[3]; }; struct roar_vio_select { struct roar_vio_calls * vio; int fh; int eventsq; int eventsa; union { int si; void * vp; } ud; struct roar_vio_select_internal internal; }; struct roar_vio_selectctl { int strategy; }; struct roar_vio_selecttv { int64_t sec; int32_t nsec; }; ssize_t roar_vio_select(struct roar_vio_select * vios, size_t len, struct roar_vio_selecttv * rtv, struct roar_vio_selectctl * ctl); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_socket.h����������������������������������������������������0000644�0001750�0001750�00000006174�12264733474�020076� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_socket.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_SOCKET_H_ #define _LIBROARVIO_SOCKET_H_ #include "libroar.h" struct roar_vio_defaults; int roar_vio_open_def_socket (struct roar_vio_calls * calls, struct roar_vio_defaults * def, char * opts); int roar_vio_socket_init_socket_def (struct roar_vio_defaults * def, int domain, int type); int roar_vio_socket_init_dstr_def (struct roar_vio_defaults * def, char * dstr, int hint, int type, struct roar_vio_defaults * odef); int roar_vio_socket_conv_def (struct roar_vio_defaults * def, int domain); int roar_vio_socket_get_port (char * service, int domain, int type); int roar_vio_socket_init_unix_def (struct roar_vio_defaults * def, const char * path); int roar_vio_socket_init_decnetnode_def(struct roar_vio_defaults * def); int roar_vio_socket_init_decnet_def (struct roar_vio_defaults * def, const char * node, int object, char * objname); int roar_vio_socket_init_inet4host_def(struct roar_vio_defaults * def); int roar_vio_socket_init_inet4_def (struct roar_vio_defaults * def, const char * host, int port, int type); int roar_vio_socket_init_tcp4_def (struct roar_vio_defaults * def, const char * host, int port); int roar_vio_socket_init_udp4_def (struct roar_vio_defaults * def, const char * host, int port); int roar_vio_socket_init_inet6host_def(struct roar_vio_defaults * def); int roar_vio_socket_init_inet6_def (struct roar_vio_defaults * def, const char * host, int port, int type); int roar_vio_socket_init_tcp6_def (struct roar_vio_defaults * def, const char * host, int port); int roar_vio_socket_init_udp6_def (struct roar_vio_defaults * def, const char * host, int port); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_stack.h�����������������������������������������������������0000644�0001750�0001750�00000004613�12264733474�017707� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_stack.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_STACK_H_ #define _LIBROARVIO_STACK_H_ #include "libroar.h" #define ROAR_VIO_STACK_MAX 32 struct roar_vio_stack { int next; void (*free)(void*); struct roar_vio_calls * cur; struct roar_vio_calls * calls[ROAR_VIO_STACK_MAX]; }; int roar_vio_open_stack (struct roar_vio_calls * calls); int roar_vio_open_stack2 (struct roar_vio_calls * calls, void (*func)(void*)); int roar_vio_stack_add (struct roar_vio_calls * calls, struct roar_vio_calls * vio); ssize_t roar_vio_stack_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_stack_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_stack_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int roar_vio_stack_sync (struct roar_vio_calls * vio); int roar_vio_stack_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_stack_close (struct roar_vio_calls * vio); #endif //ll ���������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_stdio.h�����������������������������������������������������0000644�0001750�0001750�00000005417�12264733475�017730� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_stdio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_STDIO_H_ #define _LIBROARVIO_STDIO_H_ #include "libroar.h" int roar_vio_open_stdio (struct roar_vio_calls * calls, FILE * dst); FILE * roar_vio_to_stdio (struct roar_vio_calls * calls, int flags); #if defined(ROAR_HAVE_FOPENCOOKIE) || defined(ROAR_HAVE_FUNOPEN) int roar_vio_to_stdio_close (void *__cookie); #endif #if defined(ROAR_HAVE_FOPENCOOKIE) ssize_t roar_vio_to_stdio_read (void *__cookie, char *__buf, size_t __nbytes); ssize_t roar_vio_to_stdio_write (void *__cookie, __const char *__buf, size_t __n); int roar_vio_to_stdio_lseek (void *__cookie, _IO_off64_t *__pos, int __w); #elif defined(ROAR_HAVE_FUNOPEN) int roar_vio_to_stdio_read(void *__cookie, char *__buf, int __nbytes); int roar_vio_to_stdio_write(void *__cookie, const char *__buf, int __n); fpos_t roar_vio_to_stdio_lseek(void *__cookie, fpos_t __pos, int __w); #endif // stdio ssize_t roar_vio_stdio_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_stdio_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t roar_vio_stdio_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int roar_vio_stdio_sync (struct roar_vio_calls * vio); int roar_vio_stdio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_stdio_close (struct roar_vio_calls * vio); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_stdvios.h���������������������������������������������������0000644�0001750�0001750�00000003630�12264733475�020274� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_stdvios.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_STDVIOS_H_ #define _LIBROARVIO_STDVIOS_H_ #include "libroar.h" #ifndef ROAR_TARGET_WIN32 extern struct roar_vio_calls * roar_stdin; extern struct roar_vio_calls * roar_stdout; extern struct roar_vio_calls * roar_stderr; #else struct roar_vio_calls ** libroar_stdvio_win32workaround(int fh); #define roar_stdin (*libroar_stdvio_win32workaround(0)) #define roar_stdout (*libroar_stdvio_win32workaround(1)) #define roar_stderr (*libroar_stdvio_win32workaround(2)) #endif #endif //ll ��������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_string.h����������������������������������������������������0000644�0001750�0001750�00000004214�12264733475�020106� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_string.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_STRING_H_ #define _LIBROARVIO_STRING_H_ #include "libroar.h" // some alias functions: #define roar_vio_puts(vio,s) roar_vio_write((vio), (s), roar_mm_strlen((s))) //#define roar_vio_putc(vio,c) roar_vio_write((vio), &(c), 1) int roar_vio_putc (struct roar_vio_calls * vio, char c) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_getc (struct roar_vio_calls * vio) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; char * roar_vio_fgets (struct roar_vio_calls * vio, char * s, size_t size) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL_ALL; int roar_vio_printf (struct roar_vio_calls * vio, const char *format, ...) _LIBROAR_ATTR_NONNULL(1, 2) _LIBROAR_ATTR_PRINTF(2, 3); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_tantalos.h��������������������������������������������������0000644�0001750�0001750�00000003450�12264733476�020427� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_tantalos.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARTANTALOS_H_ #define _LIBROARTANTALOS_H_ #include "libroar.h" #define ROAR_SLP_URL_TYPE_DOWNLOAD_HTTP "service:download.fellig:http" #define ROAR_SLP_URL_TYPE_DOWNLOAD_HTTP_LEN 28 int roar_vio_open_tantalos (struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * key, struct roar_vio_defaults * odef); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_winsock.h���������������������������������������������������0000644�0001750�0001750�00000003665�12264733476�020267� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_winsock.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_WINSOCK_H_ #define _LIBROARVIO_WINSOCK_H_ #include "libroar.h" #ifdef ROAR_TARGET_WIN32 ssize_t roar_vio_winsock_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_winsock_write (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_winsock_sync (struct roar_vio_calls * vio); int roar_vio_winsock_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int roar_vio_winsock_close (struct roar_vio_calls * vio); #endif #endif //ll ���������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vio_zlib.h������������������������������������������������������0000644�0001750�0001750�00000003142�12264733476�017540� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_gzip.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVIO_GZIP_H_ #define _LIBROARVIO_GZIP_H_ #include "libroar.h" int roar_vio_open_zlib(struct roar_vio_calls * calls, struct roar_vio_calls * dst, int level, int gzip); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/vs.h������������������������������������������������������������0000644�0001750�0001750�00000034427�12264733476�016365� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vs.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illegal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARVS_H_ #define _LIBROARVS_H_ #include "libroar.h" #define _LIBROAR_VS_STDATTRS _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1) struct roar_vs; typedef struct roar_vs roar_vs_t; typedef signed long int roar_mus_t; /* return readable string describing the problem */ const char * roar_vs_strerr(int error) _LIBROAR_ATTR_PURE _LIBROAR_ATTR_USE_RESULT; /* create a new VS object from normal RoarAudio connection object * The connection must not be closed caller before roar_vs_close() is called. * The connection is not closed by roar_vs_close(). */ roar_vs_t * roar_vs_new_from_con(struct roar_connection * con, int * error) _LIBROAR_VS_STDATTRS; /* create a new VS object with a new connection */ roar_vs_t * roar_vs_new(const char * server, const char * name, int * error) _LIBROAR_ATTR_USE_RESULT; /* start a the stream in the VS object */ int roar_vs_stream(roar_vs_t * vss, const struct roar_audio_info * info, int dir, int * error) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1, 2); /* connect to server and start stream in once * this is basically roar_vs_new() and roar_vs_stream() in one function. */ roar_vs_t * roar_vs_new_simple(const char * server, const char * name, int rate, int channels, int codec, int bits, int dir, int * error) _LIBROAR_ATTR_USE_RESULT; /* create a VS object for playback. * This is roar_vs_new_simple() with direction set to 'playback' (wave form data) */ #define roar_vs_new_playback(s,n,r,c,e,b,error) roar_vs_new_simple((s), (n), (r), (c), (e), (b), ROAR_DIR_PLAY, (error)) /* Attach a open file. */ int roar_vs_file(roar_vs_t * vss, struct roar_vio_calls * vio, int closefile, int * error) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1, 2); /* Open a file and attach it. */ int roar_vs_file_simple(roar_vs_t * vss, const char * filename, int * error) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1, 2); /* Connects to a server to just play a file. */ roar_vs_t * roar_vs_new_from_file(const char * server, const char * name, const char * filename, int * error) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(3); /* Switch to buffered mode. * After swiching to buffered mode you can use the buffered * mode functions. You must use roar_vs_iterate() to send data * from local buffer to server. * This is currently not thread safe but you may implement it in * diffrent thread if you do the locking yourself. * Takes the size for the used buffers as argument. * Buffer size should be a value of 2^n. Typical values are 2048 and 4096. */ int roar_vs_buffer(roar_vs_t * vss, size_t buffer, int * error) _LIBROAR_VS_STDATTRS; /* Boolean TRUE for VS functions */ #define ROAR_VS_TRUE 1 /* Boolean FALSE for VS functions */ #define ROAR_VS_FALSE 0 /* Boolean TOGGLE for VS functions */ #define ROAR_VS_TOGGLE -1 /* Boolean value used to ask for a value, do not change the value only ask for current value */ #define ROAR_VS_ASK -2 /* close and free the VS object * This does all needed cleanup. * If server connection was made by VS it is closed, too. * If server connection was provided by caller it is untouched. */ int roar_vs_close(roar_vs_t * vss, int killit, int * error) _LIBROAR_ATTR_NONNULL(1); /* write data to a stream * This function writes some data to the stream. * return is number of bytes written or -1 on error. * return value can be zero to indicate no data can be written but no error. * this may be the case with non-blocking streams. * returned value can be less then requested value. indicates a short write. * you should wait some (short!) time (for example one main loop iteration) and try again. */ ssize_t roar_vs_write(roar_vs_t * vss, const void * buf, size_t len, int * error) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1, 2); /* read data from a stream * This function reads some data from the stream. * return is number of bytes read or -1 on error. * return value can be zero to indicate no data can be read but no error. * this may be the case with non-blocking streams. * returned value can be less then requested value. indicates a short read. * you should wait some (short!) time (for example one main loop iteration) and try again. */ ssize_t roar_vs_read (roar_vs_t * vss, void * buf, size_t len, int * error) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1, 2); /* wait value for waiting */ #define ROAR_VS_WAIT 1 /* wait value for no waiting */ #define ROAR_VS_NOWAIT 0 /* Trigger action but do not wait for it to complet */ #define ROAR_VS_ASYNC -1 /* sync a stream with the server (flush buffers) * Returns 0 on no error and -1 on error. */ int roar_vs_sync (roar_vs_t * vss, int wait, int * error) _LIBROAR_ATTR_NONNULL(1); /* set blocking mode of stream * returns old blocking state */ int roar_vs_blocking (roar_vs_t * vss, int val, int * error) _LIBROAR_VS_STDATTRS; /* do not supply backend offset */ #define ROAR_VS_BACKEND_NONE -1 /* use first found primary stream of same mixer as offset source */ #define ROAR_VS_BACKEND_FIRST -2 /* use mean of primary streams of same mixer as offset source */ #define ROAR_VS_BACKEND_MEAN -3 /* default backend, now handled at runtime, old value was hard coded to _FIRST */ #define ROAR_VS_BACKEND_DEFAULT -4 /* get server's position of stream * returns server's position of the stream or -1 on error. * The returned server position is the position in samples * plus a offset provided by the selected backend */ ssize_t roar_vs_position(roar_vs_t * vss, int backend, int * error) _LIBROAR_VS_STDATTRS; /* get latency between playback and local write counter * This function may fail because the used codec uses * non-fixed bitrate. * if this function fails it returns zero and sets error or * clear error to ROAR_ERROR_NONE. * If non-zero is returned error is untouched. * return value is in mu-sec (units of 10^-6s). * Note that the returned value may be negative (the server being * ahead of us). This is normal in case we read a stream. */ roar_mus_t roar_vs_latency(roar_vs_t * vss, int backend, int wait, int * error) _LIBROAR_VS_STDATTRS; /* set pause flag * The pause flag should be set whenever the user presses the pause button or similar. * The stream may be come blocking after the pause flag has been set. * returns old pause setting (useful with ROAR_VS_TOGGLE) */ int roar_vs_pause(roar_vs_t * vss, int val, int * error) _LIBROAR_ATTR_NONNULL(1); /* set the mute flag of the stream * The pause flag should be set whenever the user mutes the stream in some way. * This flag is used so the volume is not changed and can be restored by the server * while unmuting. * It is very recommended to use this flag and not just set the volume to zero * returns old mute setting (useful with ROAR_VS_TOGGLE) */ int roar_vs_mute (roar_vs_t * vss, int val, int * error) _LIBROAR_ATTR_NONNULL(1); /* set volume of stream (all channels to the same value) * volume c is float from 0 ('muted', see above) to 1 (full volume). * Returns 0 on no error and -1 on error. */ int roar_vs_volume_mono (roar_vs_t * vss, float c, int * error) _LIBROAR_ATTR_NONNULL(1); /* set volume of stream (like volume + balance, stereo mode) * volume l and r are floats from 0 ('muted', see above) to 1 (full volume). * Returns 0 on no error and -1 on error. */ int roar_vs_volume_stereo (roar_vs_t * vss, float l, float r, int * error) _LIBROAR_ATTR_NONNULL(1); /* get volume from stream (like volume + balance, stereo mode) * volume pointers l and r are floats from 0 ('muted', see above) to 1 (full volume). * Returns 0 on no error and -1 on error. * NOTE: if you want a 'mono' volume (like roar_vs_volume_mono() takes) * you can just use: c = (*l + *r)/2 */ int roar_vs_volume_get (roar_vs_t * vss, float * l, float * r, int * error) _LIBROAR_ATTR_USE_RESULT _LIBROAR_ATTR_NONNULL(1, 2, 3); /* set an array of meta data for the stream * This sets an array of meta data stored in kv of length len for * the stream. * This should be called before streaming is started using read or write functions * but may be called at any time (for example to updata meta data). * Returns 0 on no error and -1 on error. * Example: * struct roar_keyval kv = {.key = "TITLE", .value = "Some title"}; * ret = roar_vs_meta(vss, &kv, 1, &err); */ int roar_vs_meta (roar_vs_t * vss, struct roar_keyval * kv, size_t len, int * error) _LIBROAR_ATTR_NONNULL(1, 2); /* sets the stream role * see ../roaraudio/stream.h for possible roles * Returns 0 on no error and -1 on error. */ int roar_vs_role (roar_vs_t * vss, int role, int * error) _LIBROAR_ATTR_NONNULL(1); /* Run a single iteration. * This will try to read data from source, write it to the stream * and flush the buffer in buffered mode. * Returns -1 on error, 0 on EOF and positive true value on no error. */ int roar_vs_iterate (roar_vs_t * vss, int wait, int * error) _LIBROAR_ATTR_NONNULL(1); /* Iterate until EOF or error. * Very simple main loop. * Returns 0 on no error and -1 on error. */ int roar_vs_run (roar_vs_t * vss, int * error) _LIBROAR_ATTR_NONNULL(1); ssize_t roar_vs_get_avail_read(roar_vs_t * vss, int * error) _LIBROAR_VS_STDATTRS; ssize_t roar_vs_get_avail_write(roar_vs_t * vss, int * error) _LIBROAR_VS_STDATTRS; /* If in buffered mode drop all data from internal buffer. * This drops all data in current ringbuffers. You can * select if data is only droped in write or read buffer. * This may be usefull in case of seeking and such * but should be avoided as it may break the bitstream. */ int roar_vs_reset_buffer(roar_vs_t * vss, int writering, int readring, int * error) _LIBROAR_VS_STDATTRS _LIBROAR_ATTR_DEPRECATED; /* Misc controls. * Use of this should be avoided by application. */ enum roar_vs_ctlcmd { ROAR_VS_CMD_NOOP = 0, #define ROAR_VS_CMD_NOOP ROAR_VS_CMD_NOOP ROAR_VS_CMD_SET_MIXER, #define ROAR_VS_CMD_SET_MIXER ROAR_VS_CMD_SET_MIXER ROAR_VS_CMD_GET_MIXER, #define ROAR_VS_CMD_GET_MIXER ROAR_VS_CMD_GET_MIXER ROAR_VS_CMD_SET_FIRST_PRIM, #define ROAR_VS_CMD_SET_FIRST_PRIM ROAR_VS_CMD_SET_FIRST_PRIM ROAR_VS_CMD_GET_FIRST_PRIM, #define ROAR_VS_CMD_GET_FIRST_PRIM ROAR_VS_CMD_GET_FIRST_PRIM // Latency control: ROAR_VS_CMD_SET_LATC_P, #define ROAR_VS_CMD_SET_LATC_P ROAR_VS_CMD_SET_LATC_P ROAR_VS_CMD_GET_LATC_P, #define ROAR_VS_CMD_GET_LATC_P ROAR_VS_CMD_GET_LATC_P ROAR_VS_CMD_SET_LATC_TARGET, #define ROAR_VS_CMD_SET_LATC_TARGET ROAR_VS_CMD_SET_LATC_TARGET ROAR_VS_CMD_GET_LATC_TARGET, #define ROAR_VS_CMD_GET_LATC_TARGET ROAR_VS_CMD_GET_LATC_TARGET ROAR_VS_CMD_SET_LATC_WINDOW, #define ROAR_VS_CMD_SET_LATC_WINDOW ROAR_VS_CMD_SET_LATC_WINDOW ROAR_VS_CMD_GET_LATC_WINDOW, #define ROAR_VS_CMD_GET_LATC_WINDOW ROAR_VS_CMD_GET_LATC_WINDOW ROAR_VS_CMD_SET_LATC_MINLAG, #define ROAR_VS_CMD_SET_LATC_MINLAG ROAR_VS_CMD_SET_LATC_MINLAG ROAR_VS_CMD_GET_LATC_MINLAG, #define ROAR_VS_CMD_GET_LATC_MINLAG ROAR_VS_CMD_GET_LATC_MINLAG // Volume: ROAR_VS_CMD_SET_FREE_VOLUME, #define ROAR_VS_CMD_SET_FREE_VOLUME ROAR_VS_CMD_SET_FREE_VOLUME ROAR_VS_CMD_GET_FREE_VOLUME, #define ROAR_VS_CMD_GET_FREE_VOLUME ROAR_VS_CMD_GET_FREE_VOLUME // auto pause flag, needed for sync streams: ROAR_VS_CMD_SET_DEFAULT_PAUSED, #define ROAR_VS_CMD_SET_DEFAULT_PAUSED ROAR_VS_CMD_SET_DEFAULT_PAUSED ROAR_VS_CMD_GET_DEFAULT_PAUSED, #define ROAR_VS_CMD_GET_DEFAULT_PAUSED ROAR_VS_CMD_GET_DEFAULT_PAUSED // Async operation: ROAR_VS_CMD_SET_ASYNC, #define ROAR_VS_CMD_SET_ASYNC ROAR_VS_CMD_SET_ASYNC ROAR_VS_CMD_GET_ASYNC, #define ROAR_VS_CMD_GET_ASYNC ROAR_VS_CMD_GET_ASYNC ROAR_VS_CMD_LOCK_ASYNC, #define ROAR_VS_CMD_LOCK_ASYNC ROAR_VS_CMD_LOCK_ASYNC ROAR_VS_CMD_UNLOCK_ASYNC, #define ROAR_VS_CMD_UNLOCK_ASYNC ROAR_VS_CMD_UNLOCK_ASYNC }; typedef enum roar_vs_ctlcmd roar_vs_ctlcmd; #define ROAR_VS_ASYNCLEVEL_NONE 0 #define ROAR_VS_ASYNCLEVEL_ENABLE 1 #define ROAR_VS_ASYNCLEVEL_AUTO 2 int roar_vs_ctl (roar_vs_t * vss, roar_vs_ctlcmd cmd, void * argp, int * error) _LIBROAR_VS_STDATTRS; /* Get used connection object * This may be useful if you want to use functions from the main API. * Returns used connection object or NULL on error. */ struct roar_connection * roar_vs_connection_obj(roar_vs_t * vss, int * error) _LIBROAR_VS_STDATTRS; /* Get used stream object * This may be useful if you want to use functions from the main API. * Returns used stream object or NULL on error. */ struct roar_stream * roar_vs_stream_obj (roar_vs_t * vss, int * error) _LIBROAR_VS_STDATTRS; /* Get used VIO object * This may be useful if you want to use functions from the main API. * For example this can be used in non-blocking mode * to test if we can read or write. To test that use roar_vio_select(). * Returns used VIO object or NULL on error. */ struct roar_vio_calls * roar_vs_vio_obj (roar_vs_t * vss, int * error) _LIBROAR_VS_STDATTRS; /* send NOOP command to server * This can be used to ping the server. * This is of no use normally. * Returns 0 on no error and -1 on error. */ #define roar_vs_noop(v, error) roar_noop(roar_vs_connection_obj((v), (error))) #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroar/watchdog.h������������������������������������������������������0000644�0001750�0001750�00000005251�12264733476�017526� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//watchdog.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARWATCHDOG_H_ #define _LIBROARWATCHDOG_H_ #include "libroar.h" enum roar_watchdog_event { ROAR_WATCHDOG_START = 0, ROAR_WATCHDOG_STOP, ROAR_WATCHDOG_TRIGGER, ROAR_WATCHDOG_TICK, ROAR_WATCHDOG_TIMEOUT, ROAR_WATCHDOG_DOUBLETIMEOUT, }; #define ROAR_WATCHDOG_CONF_DEFAULTS -1 #define ROAR_WATCHDOG_CONF_RESTART -2 #define ROAR_WATCHDOG_CONF_STOPPABLE 0x0001 #define ROAR_WATCHDOG_CONF_CLOCK_INTERNAL 0x0000 #define ROAR_WATCHDOG_CONF_CLOCK_EXTERNAL 0x0010 #define ROAR_WATCHDOG_CONF_CLOCK_ROUND_DOWN 0x0000 #define ROAR_WATCHDOG_CONF_CLOCK_ROUND_UP 0x0020 #define ROAR_WATCHDOG_CONF_EVENTS_ONLY_MAJOR 0x0000 #define ROAR_WATCHDOG_CONF_EVENTS_ALSO_MINOR 0x0100 // start the watchdog. // timeout is in ms. int roar_watchdog_start(int config, int_least32_t timeout, int (*callback)(enum roar_watchdog_event event)); // Get timeout for watchdog. // This may be diffrent from the requested time. int_least32_t roar_watchdog_gettime(void); // stop it, if stopping is enabled. int roar_watchdog_stop(void); // Trigger the watchdog to show that we are still alive. int roar_watchdog_trigger(void); // Trigger the watchdog clock. This is only used if configured to run with external clock source. int roar_watchdog_tick(void); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio.h�������������������������������������������������������������0000644�0001750�0001750�00000020531�12264733452�016251� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roaraudio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_H_ #define _ROARAUDIO_H_ #define _ROAR_MKVERSION(a,b,c) (((uint32_t)(a) << 16) + ((uint32_t)(b) << 8) + (uint32_t)(c)) #include <roaraudio/config.h> #include <roaraudio/compilerhacks.h> #include <roaraudio/targethacks.h> #include <roaraudio/muconthacks.h> #include <roaraudio/win32hacks.h> // we include this at the beginning of the file // so we can define well known standard types known to everyone // and everywhere but win32 here #define ROAR_VERSION _ROAR_MKVERSION(ROAR_VERSION_MAJOR, ROAR_VERSION_MINOR, ROAR_VERSION_REV) #if defined(DEBUG) && !defined(ROAR_SUPPORT_TRAP) #define ROAR_SUPPORT_TRAP #endif // consts we need to set depending on the OS and features: #if defined(ROAR_NEED_GNU_SOURCE) && !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif #if defined(ROAR_NEED_BSD_VISIBLE) && !defined(__BSD_VISIBLE) #define __BSD_VISIBLE 1 #endif #ifdef ROAR_HAVE_H_STDINT #include <stdint.h> #endif #include <stdlib.h> #ifdef ROAR_HAVE_H_UNISTD #include <unistd.h> #endif #include <stdio.h> #include <string.h> #include <errno.h> #ifdef ROAR_HAVE_H_SYS_TYPES #include <sys/types.h> #endif #include <limits.h> #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) #include <sys/mman.h> #endif #ifdef ROAR_HAVE_H_SYS_STAT #include <sys/stat.h> #endif // NOTE: we need this macro in some of our header files. // TODO: This is oubslute, we will remove it soon. #if INT_MAX >= 32767 #define roar_intm16 int #define roar_uintm16 unsigned int #else #define roar_intm16 int16_t #define roar_uintm16 uint16_t #endif // this is to avoid warning messages on platforms // where sizeof(void*) == 8 and szeof(int) == 4 #ifdef __LP64__ #define ROAR_INSTINT long int #else #define ROAR_INSTINT int #endif #ifndef __BEGIN_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } #else # define __BEGIN_DECLS # define __END_DECLS #endif #endif __BEGIN_DECLS #include <roaraudio/license.h> #include <roaraudio/vendors.h> #include <roaraudio/proto.h> #include <roaraudio/caps.h> #include <roaraudio/error.h> #include <roaraudio/audio.h> #include <roaraudio/stream.h> #include <roaraudio/client.h> #include <roaraudio/sample.h> #include <roaraudio/beep.h> #include <roaraudio/meta.h> #include <roaraudio/genre.h> #include <roaraudio/acl.h> #include <roaraudio/misc.h> #include <roaraudio/byteorder.h> #include <roaraudio/socket.h> #include <roaraudio/ltm.h> #include <roaraudio/notify.h> #include <libroar/libroar.h> // Some settings for roard: #ifndef ROAR_ROARD_BITS #define ROAR_ROARD_BITS 32 #endif // Some glocal network defaults: #ifndef ROAR_NET_INET4_LOCALHOST #define ROAR_NET_INET4_LOCALHOST "localhost" #endif #ifndef ROAR_NET_INET4_ANYHOST #define ROAR_NET_INET4_ANYHOST "0.0.0.0" #endif #ifndef ROAR_NET_INET6_LOCALHOST #define ROAR_NET_INET6_LOCALHOST "ipv6-localhost" #endif #ifndef ROAR_NET_INET6_ANYHOST #define ROAR_NET_INET6_ANYHOST "::" #endif // IP: #define ROAR_DEFAULT_PORT 16002 // IPv4 #define ROAR_DEFAULT_INET4_PORT ROAR_DEFAULT_PORT #define ROAR_DEFAULT_INET4_HOST ROAR_NET_INET4_LOCALHOST // aliases: #define ROAR_DEFAULT_HOST ROAR_DEFAULT_INET4_HOST #define ROAR_DEFAULT_HOSTPORT ROAR_DEFAULT_HOST ":16002" // IPv6: #define ROAR_DEFAULT_INET6_PORT ROAR_DEFAULT_PORT #define ROAR_DEFAULT_INET6_HOST ROAR_NET_INET6_LOCALHOST // UNIX Domain Sockets #define ROAR_DEFAULT_SOCK_GLOBAL "/tmp/roar" #define ROAR_DEFAULT_SOCK_USER ".roar" // DECnet #define ROAR_DEFAULT_OBJECT "roar" #define ROAR_DEFAULT_NUM 0 #define ROAR_DEFAULT_LISTEN_OBJECT "::" ROAR_DEFAULT_OBJECT // now handled by configure: //#define ROAR_DEFAULT_SOCKGRP "audio" // defines for emulations: // ESD: #define ROAR_DEFAULT_ESD_GSOCK "/tmp/.esd/socket" #define ROAR_DEFAULT_ESD_PORT 16001 // RSound: #define ROAR_DEFAULT_RSOUND_GSOCK "/tmp/rsound" #define ROAR_DEFAULT_RSOUND_PORT 12345 #define ROAR_DEFAULT_RSOUND_OBJECT "::rsound" // PulseAudio: #define ROAR_DEFAULT_PA_PORT 4712 // RPlay: #define ROAR_DEFAULT_RPLAY_PORT 5556 // Gopher: #define ROAR_DEFAULT_GOPHER_PORT 70 // WWW/HTTP: #define ROAR_DEFAULT_HTTP_PORT 80 #if defined(ROAR_HAVE_LIBWSOCK32) && defined(ROAR_HAVE_LIBWS2_32) #define ROAR_LIBS_WIN32 " -lwsock32 -lws2_32" #else #define ROAR_LIBS_WIN32 "" #endif #ifdef ROAR_HAVE_LIBSOCKET #define ROAR_LIBS_LIBSOCKET " -lsocket" #else #define ROAR_LIBS_LIBSOCKET "" #endif #ifdef ROAR_HAVE_LIBSENDFILE #define ROAR_LIBS_LIBSENDFILE " -lsendfile" #else #define ROAR_LIBS_LIBSENDFILE "" #endif #define ROAR_LIBS_NET_LIBS ROAR_LIBS_LIBSOCKET ROAR_LIBS_WIN32 #define ROAR_LIBS "-lroar" ROAR_LIBS_LIBSENDFILE ROAR_LIBS_NET_LIBS #define ROAR_LIBS_DSP "-lroardsp " ROAR_LIBS #define ROAR_LIBS_MIDI "-lroarmidi " ROAR_LIBS_DSP #define ROAR_LIBS_LIGHT "-lroarlight " ROAR_LIBS #define ROAR_LIBS_EIO "-lroareio " ROAR_LIBS #define ROAR_CFLAGS "" // comp libs: #define ROAR_LIBS_C_ESD "-lroaresd " ROAR_LIBS #define ROAR_LIBS_C_ARTSC "-lroarartsc " ROAR_LIBS #define ROAR_LIBS_C_PULSE "-lroarpulse " ROAR_LIBS #define ROAR_LIBS_C_PULSE_SIMPLE "-lroarpulse-simple " ROAR_LIBS_C_PULSE #define ROAR_LIBS_C_SNDIO "-lroarsndio " ROAR_LIBS #define ROAR_LIBS_C_YIFF "-lroaryiff " ROAR_LIBS //some basic macros: #define ROAR_STDIN 0 #define ROAR_STDOUT 1 #define ROAR_STDERR 2 #define ROAR_DEBUG_OUTFH stderr #ifndef ROAR_DBG_PREFIX #define ROAR_DBG_PREFIX "roaraudio" #endif #define ROAR_DBG_FULLPREFIX "(" ROAR_DBG_PREFIX ": " __FILE__ ":%i): " // some default info levels: #define ROAR_DBG_INFO_NONE 0 #define ROAR_DBG_INFO_NOTICE 1 #define ROAR_DBG_INFO_INFO 2 #define ROAR_DBG_INFO_VERBOSE 3 #if !defined(__GNUC__) #define ROAR_DBG(format, ...) #define ROAR_ERR(format, ...) #define ROAR_WARN(format, ...) #define ROAR_INFO(format, level, ...) #elif __GNUC__ < 3 #define ROAR_DBG(format, args...) #define ROAR_ERR(format, args...) #define ROAR_WARN(format, args...) #define ROAR_INFO(format, level, args...) #else #ifdef DEBUG #define ROAR_DBG(format, args...) roar_debug_msg(ROAR_DEBUG_TYPE_DEBUG, __LINE__, __FILE__, ROAR_DBG_PREFIX, format, ## args) #else #define ROAR_DBG(format, args...) #endif #define ROAR_ERR(format, args...) roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, __LINE__, __FILE__, ROAR_DBG_PREFIX, format, ## args) #define ROAR_WARN(format, args...) roar_debug_msg(ROAR_DEBUG_TYPE_WARNING, __LINE__, __FILE__, ROAR_DBG_PREFIX, format, ## args) // INFO function: #ifdef DEBUG #define ROAR_INFO(format, level, args...) roar_debug_msg(ROAR_DEBUG_TYPE_INFO, __LINE__, __FILE__, ROAR_DBG_PREFIX, format, ## args) #elif defined(ROAR_DBG_INFOVAR) #define ROAR_INFO(format, level, args...) if ( (ROAR_DBG_INFOVAR) >= (level) ) roar_debug_msg(ROAR_DEBUG_TYPE_INFO, __LINE__, __FILE__, ROAR_DBG_PREFIX, format, ## args) #else #define ROAR_INFO(format, level, args...) #endif #endif #ifdef ROAR_HAVE_SAFE_OVERFLOW #define ROAR_MATH_OVERFLOW_ADD(a, b) ((a)+(b)) #else #define ROAR_MATH_OVERFLOW_ADD(a, b) ((4294967295U - (a)) + 1 + (b)) #endif #ifdef ROAR_HAVE_STRCASESTR #define _roar_strcasestr(a,b) strcasestr((a), (b)) #else #define _roar_strcasestr(a,b) NULL #endif __END_DECLS #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/�������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016255� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/channels.h���������������������������������������������������0000644�0001750�0001750�00000013042�12264733477�020226� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//channels.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_CHANNELS_H_ #define _LIBROARDSP_CHANNELS_H_ #include "libroardsp.h" /* Channel map: * Standard marix: * * # Left | Center | Right # * ======#============#==============#=============# * Front # FRONT_LEFT | FRONT_CENTER | FRONT_RIGHT # * # LEFT | CENTER/MONO | RIGHT # * ------#------------+--------------+-------------# * Side # SIDE_LEFT | SIDE_CENTER$ | SIDE_RIGH # * ------#------------+--------------+-------------# * Back # BACK_LEFT | BACK_CENTER | BACK_RIGHT # * ======#============#==============#=============# * $ = Side Center has null-vector possion and because of this * arg(Pos) is undefined. This means that the channel does * not have a defined phase and therefor can not exist. * we include it just to have the matrix complet. * * * Low Frequency Effects: * * LFE is location independ. * * * Mid-Side (MS): * * Mid = Left + Right * Side = Left - Right * Left = (Mid + Side) / 2 * Right = (Mid - Side) / 2 * */ #define ROARDSP_CHAN_EOL -1 #define ROARDSP_CHAN_NONE 0 #define ROARDSP_CHAN_FRONT_LEFT 1 #define ROARDSP_CHAN_FRONT_RIGHT 2 #define ROARDSP_CHAN_SIDE_LEFT 3 #define ROARDSP_CHAN_SIDE_RIGHT 4 #define ROARDSP_CHAN_BACK_LEFT 5 #define ROARDSP_CHAN_BACK_RIGHT 6 #define ROARDSP_CHAN_FRONT_CENTER 7 #define ROARDSP_CHAN_SIDE_CENTER 8 #define ROARDSP_CHAN_BACK_CENTER 9 #define ROARDSP_CHAN_LEFT ROARDSP_CHAN_FRONT_LEFT #define ROARDSP_CHAN_RIGHT ROARDSP_CHAN_FRONT_RIGHT #define ROARDSP_CHAN_CENTER ROARDSP_CHAN_FRONT_CENTER #define ROARDSP_CHAN_MONO ROARDSP_CHAN_CENTER #define ROARDSP_CHAN_MS_MID 10 #define ROARDSP_CHAN_MS_SIDE 11 #define ROARDSP_CHAN_LFE 12 // MIDI Channels: #define ROARDSP_CHAN_MIDI0 64 #define ROARDSP_CHAN_MIDI1 65 #define ROARDSP_CHAN_MIDI2 66 #define ROARDSP_CHAN_MIDI3 67 #define ROARDSP_CHAN_MIDI4 68 #define ROARDSP_CHAN_MIDI5 69 #define ROARDSP_CHAN_MIDI6 70 #define ROARDSP_CHAN_MIDI7 71 #define ROARDSP_CHAN_MIDI8 72 #define ROARDSP_CHAN_MIDI9 73 #define ROARDSP_CHAN_MIDI10 74 #define ROARDSP_CHAN_MIDI11 75 #define ROARDSP_CHAN_MIDI12 76 #define ROARDSP_CHAN_MIDI13 77 #define ROARDSP_CHAN_MIDI14 78 #define ROARDSP_CHAN_MIDI15 79 #define ROARDSP_CHANLIST_MAP_ROARAUDIO 0 #define ROARDSP_CHANLIST_MAP_VORBIS 1 #define ROARDSP_CHANLIST_MAP_FLAC 2 #define ROARDSP_CHANLIST_MAP_RIFF_WAVE 3 #define ROARDSP_CHANLIST_MAP_OSS 4 #define ROARDSP_CHANLIST_MAP_ALSA 5 #define ROARDSP_CHANLIST_MAP_ESD 6 #define ROARDSP_CHANLIST_MAP_MIDI 7 #define ROARDSP_CHANMAP_IN 0 #define ROARDSP_CHANMAP_OUT 1 #define ROARDSP_CHANMAP_MAP 2 #define ROARDSP_CHANMAP_INVMAP 3 struct roardsp_chanmap { char in [ROAR_MAX_CHANNELS]; char out[ROAR_MAX_CHANNELS]; char map[ROAR_MAX_CHANNELS]; }; char * roardsp_chan2str (int chan); int roardsp_str2chan(char * str); int roardsp_chanlist2str(char * list, size_t len, char * str, size_t strlen); int roardsp_chanlist_init(char * list, int channels, int map); int roardsp_chanmap_calc(struct roardsp_chanmap * map, int what, int err_on_none); int roardsp_chanmap_mappcm8 (char * out, char * in, size_t len, size_t chans, struct roardsp_chanmap * map); int roardsp_chanmap_mappcm16(int16_t * out, int16_t * in, size_t len, size_t chans, struct roardsp_chanmap * map); int roardsp_chanmap_mappcm24(void * out, void * in, size_t len, size_t chans, struct roardsp_chanmap * map); int roardsp_chanmap_mappcm32(int32_t * out, int32_t * in, size_t len, size_t chans, struct roardsp_chanmap * map); int roardsp_chanmap_mappcm (void * out, void * in, size_t len, size_t chans, struct roardsp_chanmap * map, int bits); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/amp.h��������������������������������������������������������0000644�0001750�0001750�00000003752�12264733477�017217� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//amp.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_AMP_H_ #define _LIBROARDSP_AMP_H_ #include "libroardsp.h" int roar_amp_pcm (void * output, int bits, void * input, size_t samples, int channels, struct roar_mixer_settings * set); int roar_amp_pcm_8bit (int8_t * output, int8_t * input, size_t samples, int channels, struct roar_mixer_settings * set); int roar_amp_pcm_16bit (int16_t * output, int16_t * input, size_t samples, int channels, struct roar_mixer_settings * set); int roar_amp_pcm_32bit (int32_t * output, int32_t * input, size_t samples, int channels, struct roar_mixer_settings * set); #endif //ll ����������������������roaraudio-1.0beta11/include/libroardsp/codecs.h�����������������������������������������������������0000644�0001750�0001750�00000003644�12264733477�017702� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//codecs.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_CODECS_H_ #define _LIBROARDSP_CODECS_H_ #include "libroardsp.h" int roardsp_conv_alaw2pcm16 (int16_t * out, char * in, size_t len); int roardsp_conv_pcm162alaw (char * out, int16_t * in, size_t len); int roardsp_conv_autlaw2pcm32 (int32_t * out, int16_t * in, size_t len); int roardsp_conv_pcm322autlaw (int16_t * out, int32_t * in, size_t len); int roardsp_conv_mulaw2pcm16 (int16_t * out, char * in, size_t len); int roardsp_conv_pcm162mulaw (char * out, int16_t * in, size_t len); #endif //ll ��������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/convert.h����������������������������������������������������0000644�0001750�0001750�00000016642�12264733500�020107� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//convert.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_CONVERT_H_ #define _LIBROARDSP_CONVERT_H_ #include "libroardsp.h" int roar_conv_bits (void * out, void * in, int samples, int from, int to); // implemnted? int roar_conv_bits_8to16 (void * out, void * in, int samples); // yes int roar_conv_bits_8to24 (void * out, void * in, int samples); int roar_conv_bits_8to32 (void * out, void * in, int samples); // yes int roar_conv_bits_16to8 (void * out, void * in, int samples); // yes int roar_conv_bits_16to24 (void * out, void * in, int samples); int roar_conv_bits_16to32 (void * out, void * in, int samples); // yes int roar_conv_bits_24to8 (void * out, void * in, int samples); int roar_conv_bits_24to16 (void * out, void * in, int samples); int roar_conv_bits_24to32 (void * out, void * in, int samples); // yes int roar_conv_bits_32to8 (void * out, void * in, int samples); // yes int roar_conv_bits_32to16 (void * out, void * in, int samples); // yes int roar_conv_bits_32to24 (void * out, void * in, int samples); int roar_conv_chans (void * out, void * in, int samples, int from, int to, int bits); // implmented? working Needed? int roar_conv_chans_1ton8 (void * out, void * in, int samples, int to); // yes ? yes int roar_conv_chans_1ton16 (void * out, void * in, int samples, int to); // yes yes yes int roar_conv_chans_1ton32 (void * out, void * in, int samples, int to); // yes ? yes int roar_conv_chans_1to28 (void * out, void * in, int samples); // yes yes no int roar_conv_chans_1to216 (void * out, void * in, int samples); // yes yes no int roar_conv_chans_nto18 (void * out, void * in, int samples, int from); // yes yes? yes int roar_conv_chans_nto116 (void * out, void * in, int samples, int from); // yes yes? yes int roar_conv_chans_nto132 (void * out, void * in, int samples, int from); // yes ? yes int roar_conv_chans_2to18 (void * out, void * in, int samples); // yes yes no int roar_conv_chans_2to116 (void * out, void * in, int samples); // yes yes no int roar_conv_chans_2to38 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_2to316 (void * out, void * in, int samples); // yes yes yes int roar_conv_chans_2to48 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_2to416 (void * out, void * in, int samples); // yes yes yes int roar_conv_chans_2to58 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_2to516 (void * out, void * in, int samples); // yes yes yes int roar_conv_chans_2to68 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_2to616 (void * out, void * in, int samples); // yes yes yes // FIXME: in this block we need to add a lot funcs more int roar_conv_chans_3to28 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_3to216 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_4to28 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_4to216 (void * out, void * in, int samples); // yes ? yes int roar_conv_chans_5to28 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_5to216 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_6to28 (void * out, void * in, int samples); // no ? yes int roar_conv_chans_6to216 (void * out, void * in, int samples); // no ? yes int roar_conv_rate (void * out, void * in, int samples, int from, int to, int bits, int channels); int roar_conv_rate_8 (void * out, void * in, int samples, int from, int to, int channels); int roar_conv_rate_16 (void * out, void * in, int samples, int from, int to, int channels); int roar_conv_rate_161zoh(void * out, void * in, int samples, int from, int to); int roar_conv_rate_162zoh(void * out, void * in, int samples, int from, int to); int roar_conv_rate_16nzoh(void * out, void * in, int samples, int from, int to, int channels); int roar_conv_rate_SRC (void * out, void * in, int samples, int from, int to, int bits, int channels); int roar_conv_rate2 (void * out, void * in, int outsamples, int samples, int bits, int channels); int roar_conv_codec (void * out, void * in, int samples, int from, int to, int bits); int roar_conv_signedness (void * out, void * in, int samples, int from, int to, int bits); int roar_conv_codec_s2u8 (void * out, void * in, int samples); int roar_conv_codec_s2u16 (void * out, void * in, int samples); int roar_conv_codec_s2u32 (void * out, void * in, int samples); int roar_conv_codec_u2s8 (void * out, void * in, int samples); int roar_conv_codec_u2s16 (void * out, void * in, int samples); int roar_conv_codec_u2s32 (void * out, void * in, int samples); int roar_conv_endian (void * out, void * in, int samples, int from, int to, int bits); // implemnted? int roar_conv_endian_16 (void * out, void * in, int samples); // yes int roar_conv_endian_24 (void * out, void * in, int samples); // yes int roar_conv_endian_32 (void * out, void * in, int samples); // yes int roar_conv (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to); int roar_conv2(void * out, void * in, size_t inlen, struct roar_audio_info * from, struct roar_audio_info * to, size_t bufsize); int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen); int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step); #endif //ll ����������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/dtmf.h�������������������������������������������������������0000644�0001750�0001750�00000004312�12264733500�017350� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//dtmf.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_DTMF_H_ #define _LIBROARDSP_DTMF_H_ #include "libroardsp.h" #define ROAR_DTMF_OPTIONS_NONE 0 #define ROAR_DTMF_CHAR_DTMF(x) (((x) & 0x00FF) + 0x0000) #define ROAR_DTMF_CHAR_ROAR(x) (((x) & 0x00FF) + 0x0100) #define ROAR_DTMF_CHAR_BYTE(x) (((x) & 0x00FF) + 0x0200) #define ROAR_DTMF_CHAR_BREAK ((uint16_t)0) #define ROAR_DTMF_CHAR_NOOP ROAR_DTMF_CHAR_ROAR(0) #define ROAR_DTMF_CHAR_ESCAPE ROAR_DTMF_CHAR_ROAR(27) ssize_t roar_dtmf_mus2samples(const int_least32_t t, const uint32_t rate); int roar_dtmf_break(int16_t * samples, const size_t len, const uint32_t rate, const int options); int roar_dtmf_tone (int16_t * samples, const size_t len, const uint32_t rate, const int options, const uint16_t c); uint16_t roar_dtmf_freqs2char(const int options, float f0, float f1); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/fader.h������������������������������������������������������0000644�0001750�0001750�00000004373�12264733500�017506� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//fader.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_FADER_H_ #define _LIBROARDSP_FADER_H_ #include "libroardsp.h" #define ROAR_FADER_MAX_COEFF 4 struct roar_fader_state { int rate; ssize_t pcmoffset; ssize_t start; ssize_t stop; float poly[ROAR_FADER_MAX_COEFF]; int coeff; }; int roar_fader_init (struct roar_fader_state * state, const float * poly, int coeff); int roar_fader_set_rate (struct roar_fader_state * state, int rate); int roar_fader_set_startstop(struct roar_fader_state * state, ssize_t start, ssize_t stop); int roar_fader_has_started (struct roar_fader_state * state); int roar_fader_has_ended (struct roar_fader_state * state); int roar_fader_calcpcm_i16n(struct roar_fader_state * state, int16_t * data, size_t frames, int channels); int roar_fader_calcpcm_i161(struct roar_fader_state * state, int16_t * data, size_t frames); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/filter.h�����������������������������������������������������0000644�0001750�0001750�00000013026�12264733501�017706� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_FILTER_H_ #define _LIBROARDSP_FILTER_H_ #include "libroardsp.h" /* implemented? */ #define ROARDSP_FILTER_NONE 0 #define ROARDSP_FILTER_AMP 1 /* yes */ #define ROARDSP_FILTER_LOWP 2 /* yes */ #define ROARDSP_FILTER_HIGHP 3 /* yes */ #define ROARDSP_FILTER_MODULATE 4 #define ROARDSP_FILTER_QUANTIFY 5 /* yes */ #define ROARDSP_FILTER_CLIP 6 /* yes */ #define ROARDSP_FILTER_ADD 7 /* yes */ #define ROARDSP_FILTER_DOWNMIX 8 /* yes */ #define ROARDSP_FILTER_DCBLOCK 9 #define ROARDSP_FILTER_SWAP 10 /* yes */ #define ROARDSP_FILTER_SPEEX_PREP 11 /* yes */ #define ROARDSP_FILTER_AGC 12 #define ROARDSP_FILTER_NOISEGATE 13 #define ROARDSP_FILTER_RESPONSE_CURVE 14 #define ROARDSP_FILTER_GOERTZEL 15 // filter CTLs: #define ROARDSP_FCTL_FREQ 1 /* float */ #define ROARDSP_FCTL_TIME 2 #define ROARDSP_FCTL_MUL 3 /* int32_t */ #define ROARDSP_FCTL_DIV 4 /* int32_t */ #define ROARDSP_FCTL_N 5 /* int32_t */ #define ROARDSP_FCTL_LIMIT 6 /* int32_t */ #define ROARDSP_FCTL_PHASE 7 #define ROARDSP_FCTL_Q 8 /* int32_t */ #define ROARDSP_FCTL_MODE 9 /* int32_t */ #define ROARDSP_FCTL_PACKET_SIZE 10 /* size_t */ // consts for filter flags: #define ROARDSP_FFLAG_NONE 0x0000 #define ROARDSP_FFLAG_FREE 0x0001 // consts for filter(chain) reset: #define ROARDSP_RESET_NONE 0 #define ROARDSP_RESET_FULL 1 #define ROARDSP_RESET_STATE 2 // filter specific constants: #define ROARDSP_DOWNMIX_LEFT 1 #define ROARDSP_DOWNMIX_RIGHT 2 #define ROARDSP_DOWNMIX_ARITHMETIC 3 #define ROARDSP_DOWNMIX_RMS 4 #define ROARDSP_DOWNMIX_ARITHMETIC_INVERSE 5 #define ROARDSP_DCBLOCK_NUMBLOCKS 100 #define ROARDSP_SPEEX_PREP_ON 0x0001 #define ROARDSP_SPEEX_PREP_OFF 0x0002 #define ROARDSP_SPEEX_PREP_MASK (ROARDSP_SPEEX_PREP_ON|ROARDSP_SPEEX_PREP_OFF) // Config Bit Vector #define ROARDSP_SPEEX_PREP_CBV(opt,sw) ((sw)<<((opt)*2)) #define ROARDSP_SPEEX_PREP_CTB(opt,val) (((val) & ROARDSP_SPEEX_PREP_CBV((opt),ROARDSP_SPEEX_PREP_MASK)) >> ((opt)*2)) #define ROARDSP_SPEEX_PREP_DENOISE 0 #define ROARDSP_SPEEX_PREP_AGC 1 #define ROARDSP_SPEEX_PREP_VAD 2 #define ROARDSP_SPEEX_PREP_DENOISE_ON ROARDSP_SPEEX_PREP_CBV(ROARDSP_SPEEX_PREP_DENOISE, ROARDSP_SPEEX_PREP_ON) #define ROARDSP_SPEEX_PREP_DENOISE_OFF ROARDSP_SPEEX_PREP_CBV(ROARDSP_SPEEX_PREP_DENOISE, ROARDSP_SPEEX_PREP_OFF) #define ROARDSP_SPEEX_PREP_AGC_ON ROARDSP_SPEEX_PREP_CBV(ROARDSP_SPEEX_PREP_AGC, ROARDSP_SPEEX_PREP_ON) #define ROARDSP_SPEEX_PREP_AGC_OFF ROARDSP_SPEEX_PREP_CBV(ROARDSP_SPEEX_PREP_AGC, ROARDSP_SPEEX_PREP_OFF) #define ROARDSP_SPEEX_PREP_VAD_ON ROARDSP_SPEEX_PREP_CBV(ROARDSP_SPEEX_PREP_VAD, ROARDSP_SPEEX_PREP_ON) #define ROARDSP_SPEEX_PREP_VAD_OFF ROARDSP_SPEEX_PREP_CBV(ROARDSP_SPEEX_PREP_VAD, ROARDSP_SPEEX_PREP_OFF) // types: struct roardsp_filter { int channels; int bits; int rate; void * inst; uint_least16_t flags; int (*calc )(struct roardsp_filter * filter, void * data, size_t samples); int (*uninit)(struct roardsp_filter * filter); int (*ctl )(struct roardsp_filter * filter, int cmd, void * data); int (*reset )(struct roardsp_filter * filter, int what); }; // funcs: int roardsp_filter_str2id(const char * str); const char * roardsp_filter_id2str(const int id); int roardsp_filter_new (struct roardsp_filter ** filter, struct roar_stream * stream, int id); #define roardsp_filter_free(x) roardsp_filter_uninit((x)) int roardsp_filter_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_filter_uninit(struct roardsp_filter * filter); int roardsp_filter_calc (struct roardsp_filter * filter, void * data, size_t len); int roardsp_filter_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_filter_reset (struct roardsp_filter * filter, int what); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/filterchain.h������������������������������������������������0000644�0001750�0001750�00000004166�12264733501�020716� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filterchain.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_FILTERCHAIN_H_ #define _LIBROARDSP_FILTERCHAIN_H_ #include "libroardsp.h" #define ROARDSP_MAX_FILTERS_PER_CHAIN 8 // types: struct roardsp_filterchain { int filters; struct roardsp_filter * filter[ROARDSP_MAX_FILTERS_PER_CHAIN]; }; // funcs: int roardsp_fchain_init (struct roardsp_filterchain * chain); int roardsp_fchain_uninit(struct roardsp_filterchain * chain); int roardsp_fchain_add (struct roardsp_filterchain * chain, struct roardsp_filter * filter); int roardsp_fchain_calc (struct roardsp_filterchain * chain, void * data, size_t len); int roardsp_fchain_reset (struct roardsp_filterchain * chain, int what); int roardsp_fchain_num (struct roardsp_filterchain * chain); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/filters.h����������������������������������������������������0000644�0001750�0001750�00000022566�12264733501�020102� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filters.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_FILTERS_H_ #define _LIBROARDSP_FILTERS_H_ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBM struct roardsp_lowp { uint32_t freq; // in mHz (0Hz..4MHz) uint16_t a, b; int32_t old[ROAR_MAX_CHANNELS]; }; struct roardsp_highp { uint32_t freq; // in mHz (0Hz..4MHz) int32_t a, b, c; int32_t oldout[ROAR_MAX_CHANNELS]; int32_t oldin[ROAR_MAX_CHANNELS]; }; #endif struct roardsp_amp { int32_t mul; int32_t div; }; struct roardsp_dcblock { int cur; int32_t dc[ROARDSP_DCBLOCK_NUMBLOCKS]; }; enum roardsp_clip_mode { ROARDSP_CLIP_MODE_LIMIT = 0, ROARDSP_CLIP_MODE_ZERO = 1, ROARDSP_CLIP_MODE_WARP = 2, ROARDSP_CLIP_MODE_NOISE = 3 }; struct roardsp_clip { enum roardsp_clip_mode mode; int32_t limit; }; struct roardsp_swap { int map[ROAR_MAX_CHANNELS]; }; struct roardsp_agc { struct roardsp_filter * amp; uint32_t target_amp; }; struct roardsp_speex_prep { #ifdef _SPEEX_TYPES_H SpeexPreprocessState *preprocess; int frame_size; #else char dummy[8]; #endif }; enum roardsp_responsecurve_mode { ROARDSP_RESPONSECURVE_MODE_PASS = 0, /* pass: o = i */ ROARDSP_RESPONSECURVE_MODE_LIN = 1, /* linear: o = -(1-i)^(N+1) + 1 */ ROARDSP_RESPONSECURVE_MODE_ILIN = 2, /* inverse linear: o = i**(N+1) */ ROARDSP_RESPONSECURVE_MODE_SIN = 3, /* sin: o = sin(pi/2 * i)^N */ ROARDSP_RESPONSECURVE_MODE_ISIN = 4, /* inverse sin: o = 1-sin((1-i)*pi/2)^N */ ROARDSP_RESPONSECURVE_MODE_COS = 5, /* cos: o = 0.5-cos(i*pi)/2 */ ROARDSP_RESPONSECURVE_MODE_ICOS = 6, /* inverse cos: o = 2*i-0.5+cos(i*pi)/2 */ }; struct roardsp_responsecurve { enum roardsp_responsecurve_mode mode_pos, mode_neg; int32_t N; }; // filter: #ifdef ROAR_HAVE_LIBM int roardsp_lowp_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_lowp_uninit(struct roardsp_filter * filter); int roardsp_lowp_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_lowp_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_lowp_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_lowp_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_lowp_reset (struct roardsp_filter * filter, int what); int roardsp_highp_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_highp_uninit(struct roardsp_filter * filter); int roardsp_highp_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_highp_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_highp_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_highp_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_highp_reset (struct roardsp_filter * filter, int what); #endif int roardsp_amp_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_amp_uninit(struct roardsp_filter * filter); int roardsp_amp_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_amp_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_amp_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_amp_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_amp_reset (struct roardsp_filter * filter, int what); int roardsp_add_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_add_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_add_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_add_reset (struct roardsp_filter * filter, int what); int roardsp_quantify_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_quantify_uninit(struct roardsp_filter * filter); int roardsp_quantify_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_quantify_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_quantify_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_quantify_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_quantify_reset (struct roardsp_filter * filter, int what); int roardsp_clip_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_clip_uninit(struct roardsp_filter * filter); int roardsp_clip_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_clip_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_clip_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_clip_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_clip_reset (struct roardsp_filter * filter, int what); int roardsp_downmix_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_downmix_calc162(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_downmix_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_downmix_reset (struct roardsp_filter * filter, int what); int roardsp_dcblock_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_dcblock_uninit (struct roardsp_filter * filter); int roardsp_dcblock_calc16 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_dcblock_reset (struct roardsp_filter * filter, int what); int roardsp_swap_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_swap_uninit (struct roardsp_filter * filter); int roardsp_swap_calc322(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_swap_calc162(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_swap_calc82 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_swap_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_swap_reset (struct roardsp_filter * filter, int what); int roardsp_agc_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_agc_uninit (struct roardsp_filter * filter); int roardsp_agc_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_agc_reset (struct roardsp_filter * filter, int what); #ifdef _SPEEX_TYPES_H #define ROAR_HAVE_SPEEX_FILTER int roardsp_speex_prep_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_speex_prep_uninit (struct roardsp_filter * filter); int roardsp_speex_prep_calc161(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_speex_prep_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_speex_prep_reset (struct roardsp_filter * filter, int what); #endif #ifdef ROAR_HAVE_LIBM int roardsp_responsecurve_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_responsecurve_uninit(struct roardsp_filter * filter); int roardsp_responsecurve_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_responsecurve_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_responsecurve_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_responsecurve_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_responsecurve_reset (struct roardsp_filter * filter, int what); int roardsp_goertzel_init (struct roardsp_filter * filter, struct roar_stream * stream, int id); int roardsp_goertzel_uninit(struct roardsp_filter * filter); int roardsp_goertzel_calc32(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_goertzel_calc16(struct roardsp_filter * filter, void * data, size_t samples); int roardsp_goertzel_calc8 (struct roardsp_filter * filter, void * data, size_t samples); int roardsp_goertzel_ctl (struct roardsp_filter * filter, int cmd, void * data); int roardsp_goertzel_reset (struct roardsp_filter * filter, int what); #endif #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/float.h������������������������������������������������������0000644�0001750�0001750�00000003531�12264733501�017526� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//float.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_FLOAT_H_ #define _LIBROARDSP_FLOAT_H_ #include "libroardsp.h" int roar_conv_int32_float(float * dst, const int32_t * src, size_t len); int roar_conv_float_int32(int32_t * dst, const float * src, size_t len); int roar_conv_int32_float_deint(float ** dst, const int32_t * src, size_t len, size_t channels); int roar_conv_float_int32_enint(int32_t * dst, const float ** src, size_t len, size_t channels); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/interleave.h�������������������������������������������������0000644�0001750�0001750�00000004336�12264733501�020563� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//interleave.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_INTERLEAVE_H_ #define _LIBROARDSP_INTERLEAVE_H_ #include "libroardsp.h" #define ROAR_INTERLEAVE_CTL_GET 0x00 #define ROAR_INTERLEAVE_CTL_SET 0x01 #define ROAR_INTERLEAVE_CTL_SET_MAX_BUFFER (ROAR_INTERLEAVE_CTL_SET|0x10) #define ROAR_INTERLEAVE_MAX_CHANNELS 16 struct roar_interleave { size_t channels; size_t bits; }; int roar_interl_init (struct roar_interleave * state, size_t channels, size_t bits); int roar_interl_uninit(struct roar_interleave * state); int roar_interl_ctl (struct roar_interleave * state, int cmd, void * data); int roar_interl_encode_ext(struct roar_interleave * state, void ** in, void * out, size_t len); int roar_interl_decode_ext(struct roar_interleave * state, void * in, void ** out, size_t len); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/libroardsp.h�������������������������������������������������0000644�0001750�0001750�00000003537�12264733502�020571� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroardsp.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _LIBROARDSP_H_ #define _LIBROARDSP_H_ #include <roaraudio.h> __BEGIN_DECLS // enable Speex preprocessing and better type handling if speex > 1.1.8 #ifdef ROAR_HAVE_LIBSPEEX #include <speex/speex.h> #ifdef _SPEEX_TYPES_H #include <speex/speex_preprocess.h> #endif #endif #include "channels.h" #include "interleave.h" #include "midi.h" #include "synth.h" #include "poly.h" #include "fader.h" #include "mixer.h" #include "amp.h" #include "resampler_poly3.h" #include "convert.h" #include "midside.h" #include "point.h" #include "remove.h" #include "rms.h" #include "float.h" #include "filter.h" #include "filterchain.h" #include "filters.h" #include "codecs.h" #include "dtmf.h" #include "transcode.h" #include "vio_transcode.h" #ifdef ROAR_HAVE_LIBCELT #include "transcode_celt.h" #endif #ifdef ROAR_HAVE_LIBSPEEX #include "transcode_speex.h" #endif #ifdef ROAR_HAVE_LIBSAMPLERATE #include <samplerate.h> #endif __END_DECLS #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/midi.h�������������������������������������������������������0000644�0001750�0001750�00000005507�12264733502�017351� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//midi.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _LIBROARMIDI_H_ #define _LIBROARMIDI_H_ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBM #include <math.h> #endif #define ROAR_MIDI_NOTE_NONE -1 #define ROAR_MIDI_NOTE_C 26162 #define ROAR_MIDI_NOTE_Cs 27718 #define ROAR_MIDI_NOTE_D 29366 #define ROAR_MIDI_NOTE_Ds 31112 #define ROAR_MIDI_NOTE_E 32962 #define ROAR_MIDI_NOTE_F 34922 #define ROAR_MIDI_NOTE_Fs 36999 #define ROAR_MIDI_NOTE_G 39199 #define ROAR_MIDI_NOTE_Gs 41530 #define ROAR_MIDI_NOTE_A 44000 #define ROAR_MIDI_NOTE_As 46616 #define ROAR_MIDI_NOTE_B 49388 #define ROAR_MIDI_MAX_NOTENAME_LEN (1+8) #define ROAR_MIDI_TYPE_SINE 1 struct roar_midi_len { int mul; int div; }; struct roar_note_octave { uint16_t note; char name[ROAR_MIDI_MAX_NOTENAME_LEN+1]; int octave; float freq; struct roar_midi_len len; }; struct roar_midi_basic_state { struct roar_midi_len len; struct roar_note_octave note; }; char * roar_midi_note2name (uint16_t note); uint16_t roar_midi_name2note (char * note); uint16_t roar_midi_midi2note (unsigned char midiid); float roar_midi_note2freq (uint16_t note); //int roar_midi_free_no (struct roar_note_octave * note); int roar_midi_note_from_midiid(struct roar_note_octave * note, unsigned char midiid); int roar_midi_find_octave (char * note); int roar_midi_add_octave (struct roar_note_octave * note); int roar_midi_notefill (struct roar_note_octave * note); int roar_midi_gen_tone (struct roar_note_octave * note, int16_t * samples, float t, int rate, int channels, int type, void * opts); int roar_midi_play_note (struct roar_stream * stream, struct roar_note_octave * note, float len); int roar_midi_basic_init (struct roar_midi_basic_state * state); int roar_midi_basic_play (struct roar_stream * stream, struct roar_midi_basic_state * state, char * notes); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/midside.h����������������������������������������������������0000644�0001750�0001750�00000003721�12264733502�020041� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//midside.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_MIDSIDE_H_ #define _LIBROARDSP_MIDSIDE_H_ #include "libroardsp.h" // implemnted? int roar_conv_s2ms_8 (void * out, void * in, int samples); int roar_conv_s2ms_16 (void * out, void * in, int samples); int roar_conv_s2ms_32 (void * out, void * in, int samples); int roar_conv_ms2s_8 (void * out, void * in, int samples); int roar_conv_ms2s_16 (void * out, void * in, int samples); int roar_conv_ms2s_32 (void * out, void * in, int samples); #endif //ll �����������������������������������������������roaraudio-1.0beta11/include/libroardsp/mixer.h������������������������������������������������������0000644�0001750�0001750�00000003452�12264733502�017550� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//mixer.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_MIXER_H_ #define _LIBROARDSP_MIXER_H_ #include "libroardsp.h" int roar_mix_pcm (void * output, int bits, void ** input, int samples); int roar_mix_pcm_8bit (int8_t * output, int8_t ** input, int samples); int roar_mix_pcm_16bit (int16_t * output, int16_t ** input, int samples); int roar_mix_pcm_32bit (int32_t * output, int32_t ** input, int samples); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/point.h������������������������������������������������������0000644�0001750�0001750�00000003373�12264733503�017560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//point.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_POINT_H_ #define _LIBROARDSP_POINT_H_ #include "libroardsp.h" struct roar_point { int32_t x, y, z; }; #define roar_point_init(p) ((p)->x = (p)->y = (p)->z = 0) #define roar_point_zeroz(p) ((p)->z = 0) #define roar_point_to2d(p) roar_point_zeroz(p) #define roar_point_to3d(p) roar_point_zeroz(p) #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/poly.h�������������������������������������������������������0000644�0001750�0001750�00000004071�12264733503�017406� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//poly.h: // was math.h /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARMATH_H_ #define _LIBROARMATH_H_ #include "libroardsp.h" int roar_math_mkpoly (float * poly, float * data, int len); int roar_math_mkpoly_2x2 (float * poly, float * data); int roar_math_mkpoly_3x3 (float * poly, float * data); int roar_math_mkpoly_4x4 (float * poly, float * data); int roar_math_mkpoly_5x5 (float * poly, float * data); float roar_math_cvpoly (float * poly, float t, int len); float roar_math_cvpoly_4x4 (float * poly, float t); int roar_math_diffpoly(float * poly, int len); int roar_math_intpoly(float * poly, int len, float c); float roar_math_numintpoly(float * poly, int len, float st, float et); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/remove.h�����������������������������������������������������0000644�0001750�0001750�00000004677�12264733503�017734� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//remove.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_REMOVE_H_ #define _LIBROARDSP_REMOVE_H_ #include "libroardsp.h" struct roar_remove_state { uint16_t a, b; uint16_t old; }; int roar_remove_init (struct roar_remove_state * state); int roar_remove (void * inout, void * subs, int samples, int bits, struct roar_remove_state * state); int roar_remove_8 (int8_t * inout, int8_t * subs, int samples, struct roar_remove_state * state); int roar_remove_16 (int16_t * inout, int16_t * subs, int samples, struct roar_remove_state * state); int roar_remove_32 (int32_t * inout, int32_t * subs, int samples, struct roar_remove_state * state); int roar_remove_so (void * subout, void * in, int samples, int bits, struct roar_remove_state * state); int roar_remove_so8 (int8_t * subout, int8_t * in, int samples, struct roar_remove_state * state); int roar_remove_so16 (int16_t * subout, int16_t * in, int samples, struct roar_remove_state * state); int roar_remove_so32 (int32_t * subout, int32_t * in, int samples, struct roar_remove_state * state); #endif //ll �����������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/resampler_poly3.h��������������������������������������������0000644�0001750�0001750�00000003636�12264733503�021551� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//resampler_poly3.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_RESAMPLER_POLY3_H_ #define _LIBROARDSP_RESAMPLER_POLY3_H_ #include "libroardsp.h" // ilen and olen are in samples, not frames. int roar_conv_poly3_8 (int8_t * out, int8_t * in, size_t olen, size_t ilen, int channels); int roar_conv_poly3_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen, int channels); int roar_conv_poly3_32 (int32_t * out, int32_t * in, size_t olen, size_t ilen, int channels); #endif //ll ��������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/rms.h��������������������������������������������������������0000644�0001750�0001750�00000004320�12264733503�017221� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//rms.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_RMS_H_ #define _LIBROARDSP_RMS_H_ #include "libroardsp.h" int64_t roar_rms2_1_8 (int8_t * data, size_t samples); int64_t roar_rms2_1_16 (int16_t * data, size_t samples); int64_t roar_rms2_1_32 (int32_t * data, size_t samples); int roar_rms2_1_8_2 (int8_t * data, size_t samples, int64_t * rms); int roar_rms2_1_16_2 (int16_t * data, size_t samples, int64_t * rms); int roar_rms2_1_32_2 (int32_t * data, size_t samples, int64_t * rms); int roar_rms2_1_8_n (int8_t * data, size_t samples, int64_t * rms, size_t n); int roar_rms2_1_16_n (int16_t * data, size_t samples, int64_t * rms, size_t n); int roar_rms2_1_32_n (int32_t * data, size_t samples, int64_t * rms, size_t n); int roar_rms2_1_b_n (void * data, size_t samples, int64_t * rms, size_t n, size_t bits); #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/synth.h������������������������������������������������������0000644�0001750�0001750�00000006552�12264733504�017577� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//synth.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_SYNTH_H_ #define _LIBROARDSP_SYNTH_H_ #include "libroardsp.h" #define ROAR_SYNTH_FUNC_TYPE(name) float (*name)(float t, struct roar_synth_state * state) #define ROAR_SYNTH_FUNC_CAST(name) ((float (* )(float t, struct roar_synth_state * state)) name) // SYNF -> Synthesis Function #define ROAR_SYNTH_SYNF_RECT ROAR_SYNTH_FUNC_CAST(roar_synth_synf_rect) #define ROAR_SYNTH_SYNF_SAW ROAR_SYNTH_FUNC_CAST(roar_synth_synf_saw) #define ROAR_SYNTH_SYNF_TRI ROAR_SYNTH_FUNC_CAST(roar_synth_synf_tri) #define ROAR_SYNTH_SYNF_TRAP ROAR_SYNTH_FUNC_CAST(roar_synth_synf_trap) // those use sin*() #ifdef ROAR_HAVE_LIBM #define ROAR_SYNTH_SYNF_SIN ROAR_SYNTH_FUNC_CAST(sinf) #define ROAR_SYNTH_SYNF_S2S ROAR_SYNTH_FUNC_CAST(roar_synth_synf_s2s) #endif #ifdef ROAR_HAVE_LIBM #define ROAR_SYNTH_SYNF_DEFAULT ROAR_SYNTH_SYNF_SIN #else #define ROAR_SYNTH_SYNF_DEFAULT ROAR_SYNTH_SYNF_TRAP #endif struct roar_synth_state { int rate; struct roar_note_octave * note; ROAR_SYNTH_FUNC_TYPE(func); size_t pcmoffset; float volume; }; int roar_synth_init(struct roar_synth_state * state, struct roar_note_octave * note, int rate); int roar_synth_set_offset(struct roar_synth_state * state, size_t offset); int roar_synth_set_func (struct roar_synth_state * state, ROAR_SYNTH_FUNC_TYPE(func)); int roar_synth_set_volume(struct roar_synth_state * state, float volume); int roar_synth_pcmout_i16n(struct roar_synth_state * state, int16_t * out, size_t frames, int channels); int roar_synth_pcmout_i161(struct roar_synth_state * state, int16_t * out, size_t frames); // some basic SYNFs: float roar_synth_synf_rect (float t, struct roar_synth_state * state); float roar_synth_synf_saw (float t, struct roar_synth_state * state); float roar_synth_synf_tri (float t, struct roar_synth_state * state); float roar_synth_synf_trap (float t, struct roar_synth_state * state); #ifdef ROAR_HAVE_LIBM float roar_synth_synf_s2s (float t, struct roar_synth_state * state); #endif #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/transcode.h��������������������������������������������������0000644�0001750�0001750�00000011151�12264733504�020403� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//transcode.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_TRANSCODE_H_ #define _LIBROARDSP_TRANSCODE_H_ #include "libroardsp.h" #define ROAR_XCODER_STAGE_NONE 0 #define ROAR_XCODER_STAGE_INITED 0 #define ROAR_XCODER_STAGE_WAIT 1 #define ROAR_XCODER_STAGE_MAGIC 2 #define ROAR_XCODER_STAGE_OPENING 3 #define ROAR_XCODER_STAGE_OPENED 4 #define ROAR_XCODER_STAGE_CLOSING 5 #define ROAR_XCODER_STAGE_CLOSED 6 #define ROAR_BIXCODER_FLAGS_NONE 0x0000 #define ROAR_BIXCODER_FLAGS_ENCODE 0x0001 #define ROAR_BIXCODER_FLAGS_DECODE 0x0002 struct roar_xcoder; struct roar_xcoder_entry { int codec; int (*init)(struct roar_xcoder * state); int (*uninit)(struct roar_xcoder * state); int (*packet_size)(struct roar_xcoder * state, int samples); int (*encode)(struct roar_xcoder * state, void * buf, size_t len); int (*decode)(struct roar_xcoder * state, void * buf, size_t len); int (*proc_header)(struct roar_xcoder * state); }; struct roar_xcoder { void * inst; struct roar_xcoder_entry * entry; struct roar_vio_calls * backend; int encode; int flags; int stage; ssize_t packet_len; struct roar_buffer * iobuffer; struct { struct roar_audio_info coded; struct roar_audio_info pcm; } info; }; struct roar_bixcoder { struct roar_xcoder encoder, decoder; int flags; }; struct roar_transcoder { struct roar_xcoder encoder, decoder; }; int roar_xcoder_init(struct roar_xcoder * state, int encoder, struct roar_audio_info * info, struct roar_vio_calls * vio); int roar_xcoder_set_backend(struct roar_xcoder * state, struct roar_vio_calls * vio); int roar_xcoder_packet_size(struct roar_xcoder * state, int samples); int roar_xcoder_close (struct roar_xcoder * state); int roar_xcoder_proc_header(struct roar_xcoder * state); int roar_xcoder_proc_packet(struct roar_xcoder * state, void * buf, size_t len); int roar_xcoder_proc (struct roar_xcoder * state, void * buf, size_t len); int roar_bixcoder_init(struct roar_bixcoder * state, struct roar_audio_info * info, struct roar_vio_calls * vio); int roar_bixcoder_packet_size (struct roar_bixcoder * state, int samples); int roar_bixcoder_close (struct roar_bixcoder * state); int roar_bixcoder_read_header (struct roar_bixcoder * state); int roar_bixcoder_read_packet (struct roar_bixcoder * state, void * buf, size_t len); int roar_bixcoder_read (struct roar_bixcoder * state, void * buf, size_t len); int roar_bixcoder_write_header(struct roar_bixcoder * state); int roar_bixcoder_write_packet(struct roar_bixcoder * state, void * buf, size_t len); int roar_bixcoder_write (struct roar_bixcoder * state, void * buf, size_t len); // dummy functions used by some de/encoders: int roar_xcoder_dummy_inituninit(struct roar_xcoder * state); int roar_xcoder_dummy_packet_size_any(struct roar_xcoder * state, int samples); int roar_xcoder_dummy_proc_header(struct roar_xcoder * state); // prototypes for some simple xcoders: int roar_xcoder_alaw_encode(struct roar_xcoder * state, void * buf, size_t len); int roar_xcoder_alaw_decode(struct roar_xcoder * state, void * buf, size_t len); int roar_xcoder_mulaw_encode(struct roar_xcoder * state, void * buf, size_t len); int roar_xcoder_mulaw_decode(struct roar_xcoder * state, void * buf, size_t len); #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/transcode_celt.h���������������������������������������������0000644�0001750�0001750�00000004125�12264733504�021415� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//transcode_celt.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_TRANSCODE_CELT_H_ #define _LIBROARDSP_TRANSCODE_CELT_H_ #include "libroardsp.h" #include <celt/celt.h> #include <celt/celt_header.h> struct roar_xcoder_celt { CELTMode * mode; CELTEncoder * encoder; CELTDecoder * decoder; int frame_size; void * iobuffer; size_t bufferlen; }; int roar_xcoder_celt_init (struct roar_xcoder * state); int roar_xcoder_celt_uninit (struct roar_xcoder * state); int roar_xcoder_celt_packet_size(struct roar_xcoder * state, int samples); int roar_xcoder_celt_encode (struct roar_xcoder * state, void * buf, size_t len); int roar_xcoder_celt_decode (struct roar_xcoder * state, void * buf, size_t len); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/transcode_speex.h��������������������������������������������0000644�0001750�0001750�00000004560�12264733504�021615� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//transcode_speex.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_TRANSCODE_SPEEX_H_ #define _LIBROARDSP_TRANSCODE_SPEEX_H_ #include "libroardsp.h" #include <speex/speex.h> #include <speex/speex_stereo.h> #include <speex/speex_callbacks.h> struct roar_xcoder_speex { SpeexBits bits; SpeexStereoState stereo_state; void * xcoder; uint16_t mode; int stereo; int frame_size; char cc[ROAR_SPEEX_MAX_CC+2]; /* buffer for read() and write() + 2 byte for pkg length */ struct roar_libroar_config_codec * codec_config; int max_cc; }; int roar_xcoder_speex_init (struct roar_xcoder * state); int roar_xcoder_speex_uninit (struct roar_xcoder * state); int roar_xcoder_speex_packet_size(struct roar_xcoder * state, int samples); int roar_xcoder_speex_proc_header(struct roar_xcoder * state); int roar_xcoder_speex_encode (struct roar_xcoder * state, void * buf, size_t len); int roar_xcoder_speex_decode (struct roar_xcoder * state, void * buf, size_t len); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroardsp/vio_transcode.h����������������������������������������������0000644�0001750�0001750�00000004440�12264733504�021263� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_transcode.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARDSP_VIO_TRANSCODE_H_ #define _LIBROARDSP_VIO_TRANSCODE_H_ #include "libroardsp.h" int roar_vio_open_xcode (struct roar_vio_calls * calls, int encoder, struct roar_audio_info * info, struct roar_vio_calls * dst); ssize_t roar_vio_xcode_proc (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_xcode_sync (struct roar_vio_calls * vio); int roar_vio_xcode_close (struct roar_vio_calls * vio); int roar_vio_open_bixcode (struct roar_vio_calls * calls, struct roar_audio_info * info, struct roar_vio_calls * dst); ssize_t roar_vio_bixcode_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t roar_vio_bixcode_write (struct roar_vio_calls * vio, void *buf, size_t count); int roar_vio_bixcode_sync (struct roar_vio_calls * vio); int roar_vio_bixcode_close (struct roar_vio_calls * vio); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroareio/�������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016243� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroareio/driver.h�����������������������������������������������������0000644�0001750�0001750�00000004536�12264733505�017714� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//driver.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAREIO_DRIVER_H_ #define _LIBROAREIO_DRIVER_H_ #include <roaraudio.h> struct roar_cdriver { const char * name; int (*open)(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir); }; int roar_cdriver_open(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir); int roar_cdriver_open2(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen); ssize_t roar_cdriver_list (const char ** list, size_t len, size_t offset) _LIBROAR_STREAM_STDATTRS; // driver prototypes: int roar_cdriver_oss (struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir); int roar_cdriver_roar(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroareio/ff_ssdp.h����������������������������������������������������0000644�0001750�0001750�00000005401�12264733505�020035� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ff_ssdp.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroareio a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAREIO_FF_SSDP_H_ #define _LIBROAREIO_FF_SSDP_H_ #include "libroareio.h" /* > NOTIFY * HTTP/1.1 > SERVER: Linux/2.6.15.2 UPnP/1.0 Mediaserver/1.0 > CACHE-CONTROL: max-age=1800 > LOCATION: http://192.168.0.10:8080/description.xml > NTS: ssdp:alive > NT: urn:schemas-upnp-org:service:ConnectionManager:1 > USN: uuid:550e8400-e29b-11d4-a716-446655440000::urn:schemas-upnp-org:service:ConnectionManager:1 > HOST: 239.255.255.250:1900 */ #define ROAR_FF_SSDP_M_NOTIFY 1 #define ROAR_FF_SSDP_M_M_SEARCH 2 #define ROAR_FF_SSDP_MS_NOTIFY "NOTIFY" #define ROAR_FF_SSDP_MS_M_SEARCH "M-SEARCH" #define ROAR_FF_SSDP_A_ALIVE 1 #define ROAR_FF_SSDP_A_BYEBYE 2 #define ROAR_FF_SSDP_A_REG ROAR_FF_SSDP_A_ALIVE #define ROAR_FF_SSDP_A_UNREG ROAR_FF_SSDP_A_BYEBYE #define ROAR_FF_SSDP_AS_ALIVE "ssdp:alive" #define ROAR_FF_SSDP_AS_BYEBYE "ssdp:byebye" #define ROAR_FF_SSDP_HOST_UPNP "239.255.255.250:1900" struct roar_ff_ssdp { int method; char * server; int max_age; char * location; int nst; char * nt; char * usn; int usn_nt_suffix; char * host; }; void roar_ff_ssdp_init (struct roar_ff_ssdp * c); void roar_ff_ssdp_free (struct roar_ff_ssdp * c); int roar_ff_ssdp_write(struct roar_vio_calls * vio, struct roar_ff_ssdp * c); int roar_ff_ssdp_read (struct roar_vio_calls * vio, struct roar_ff_ssdp * c); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroareio/httpd.h������������������������������������������������������0000644�0001750�0001750�00000006520�12264733505�017537� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//httpd.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroareio a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAREIO_HTTPD_H_ #define _LIBROAREIO_HTTPD_H_ #include "libroareio.h" #define _ROAR_EIO_HTTPD_VERSION(major,minor) (((major)<<8)|(minor)) #define _ROAR_EIO_HTTPD_VERSION_MAJOR(x) ((x)>>8) #define _ROAR_EIO_HTTPD_VERSION_MINOR(x) ((x)&0xFF) #define ROAR_HTTPD_VERSION_HTTP09 _ROAR_EIO_HTTPD_VERSION(0,9) #define ROAR_HTTPD_VERSION_HTTP10 _ROAR_EIO_HTTPD_VERSION(1,0) #define ROAR_HTTPD_VERSION_HTTP11 _ROAR_EIO_HTTPD_VERSION(1,1) #define ROAR_HTTPD_METHOD_NONE 0 #define ROAR_HTTPD_METHOD_GET 1 #define ROAR_HTTPD_METHOD_POST 2 #define ROAR_HTTPD_METHOD_PUT 3 #define ROAR_HTTPD_METHOD_HEAD 4 #define ROAR_HTTPD_METHOD_DELETE 5 #define ROAR_HTTPD_METHOD_TRACE 6 #define ROAR_HTTPD_METHOD_OPTIONS 7 #define ROAR_HTTPD_METHOD_CONNECT 8 //#define ROAR_HTTPD_METHOD_ 9 #define ROAR_HTTPD_STATUS_OK 200 #define ROAR_HTTPD_STATUS_NOT_FOUND 404 #define ROAR_HTTPD_STATUS_INTSERVERR 500 #define ROAR_HTTPD_STATUS_NOT_IMPL 501 #define ROAR_HTTPD_STATUS_VERNOTSUP 505 #define ROAR_HTTPD_STATE_REQ 1 #define ROAR_HTTPD_STATE_EOH 2 #define ROAR_HTTPD_STATE_RESP 3 struct roar_httpd_request { int method; char * resource; char * query_string; int version; struct roar_keyval * header; }; struct roar_httpd_response { int version; int status; struct roar_vio_calls * file; struct roar_keyval * header; }; struct roar_httpd { int state; struct roar_httpd_request request; struct roar_httpd_response response; int (*cb_eoh)(struct roar_httpd * httpd); struct roar_vio_calls * client; struct roar_vio_calls viostore[1]; struct roar_buffer * header; struct roar_buffer * iobuffer; }; struct roar_httpd * roar_http_new(struct roar_vio_calls * client, int (*cb_eoh)(struct roar_httpd * httpd)); int roar_http_free(struct roar_httpd * httpd); int roar_http_update(struct roar_httpd * httpd); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroareio/libroareio.h�������������������������������������������������0000644�0001750�0001750�00000003061�12264733505�020540� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroareio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroareio a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROAREIO_H_ #define _LIBROAREIO_H_ #include <roaraudio.h> #include "driver.h" #include "ff_ssdp.h" #include "httpd.h" #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroaresd/�������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016242� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroaresd/libroaresd.h�������������������������������������������������0000644�0001750�0001750�00000004512�12264733506�020541� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroaresd.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from EsounD. * They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude) * <ericmit@ix.netcom.com>. For more information see AUTHORS.esd. * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARESD_H_ #define _LIBROARESD_H_ #include <roaraudio.h> #include <esd.h> #ifdef ROAR_HAVE_H_SYS_TIME #include <sys/time.h> #endif #ifdef ROAR_HAVE_H_TIME #include <time.h> #endif #define ROAR_BC2ESD(b,c) (((b) == 8 ? ESD_BITS8 : ESD_BITS16) | ((c) == 1 ? ESD_MONO : ESD_STEREO)) #define ROAR_DIR2ESD(d) ((d) == ROAR_DIR_PLAY ? ESD_PLAY : (d) == ROAR_DIR_MONITOR ? ESD_MONITOR : \ (d) == ROAR_DIR_RECORD ? ESD_RECORD : \ ESD_MONITOR /* ESD implements FILTER a diffrent way, think MONITOR ist most simular */ ) #define ROAR_S2ESD(s) (ROAR_BC2ESD((s)->info.bits, (s)->info.channels) | ROAR_DIR2ESD((s)->dir)) #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarlight/�����������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016576� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarlight/colors.h���������������������������������������������������0000644�0001750�0001750�00000011701�12264733506�020246� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//colors.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARLIGHT_COLORS_H_ #define _LIBROARLIGHT_COLORS_H_ #include "libroarlight.h" #define ROAR_COLOR_TYPE_NONE 0x00000000 #define ROAR_COLOR_TYPE_GRAY 0x00000001 /* ??? */ #define ROAR_COLOR_TYPE_ALPHA 0x00000002 /* Alpha */ #define ROAR_COLOR_TYPE_DOUBLE 0x00000004 /* use 16 bit per channel */ #define ROAR_COLOR_TYPE_A ROAR_COLOR_TYPE_ALPHA #define ROAR_COLOR_TYPE_K 0x00000010 /* black (Key) */ #define ROAR_COLOR_TYPE_R 0x00000020 /* red */ #define ROAR_COLOR_TYPE_G 0x00000040 /* green */ #define ROAR_COLOR_TYPE_B 0x00000080 /* blue or ??? */ #define ROAR_COLOR_TYPE_H 0x00000100 #define ROAR_COLOR_TYPE_S 0x00000200 #define ROAR_COLOR_TYPE_V 0x00000400 //#define ROAR_COLOR_TYPE_B 0x00000800 #define ROAR_COLOR_TYPE_L 0x00001000 #define ROAR_COLOR_TYPE_I 0x00002000 #define ROAR_COLOR_TYPE_C 0x00004000 /* Cyan */ #define ROAR_COLOR_TYPE_M 0x00008000 /* Magenta */ #define ROAR_COLOR_TYPE_Y 0x00010000 /* Yellow or ??? */ #define ROAR_COLOR_TYPE_U 0x00020000 //#define ROAR_COLOR_TYPE_ 0x0100 #define ROAR_COLORSYSTEM_NONE (ROAR_COLOR_TYPE_NONE) #define ROAR_COLORSYSTEM_GRAY (ROAR_COLOR_TYPE_K) #define ROAR_COLORSYSTEM_RGB (ROAR_COLOR_TYPE_R|ROAR_COLOR_TYPE_G|ROAR_COLOR_TYPE_B) #define ROAR_COLORSYSTEM_RGBA (ROAR_COLOR_TYPE_R|ROAR_COLOR_TYPE_G|ROAR_COLOR_TYPE_B|ROAR_COLOR_TYPE_ALPHA) #define ROAR_COLORSYSTEM_YUV (ROAR_COLOR_TYPE_Y|ROAR_COLOR_TYPE_U|ROAR_COLOR_TYPE_V) #define ROAR_COLORSYSTEM_HSV (ROAR_COLOR_TYPE_H|ROAR_COLOR_TYPE_S|ROAR_COLOR_TYPE_V) #define ROAR_COLORSYSTEM_HSL (ROAR_COLOR_TYPE_H|ROAR_COLOR_TYPE_S|ROAR_COLOR_TYPE_L) #define ROAR_COLORSYSTEM_HSB (ROAR_COLOR_TYPE_H|ROAR_COLOR_TYPE_S|ROAR_COLOR_TYPE_B) #define ROAR_COLORSYSTEM_HSI (ROAR_COLOR_TYPE_H|ROAR_COLOR_TYPE_S|ROAR_COLOR_TYPE_I) #define ROAR_COLORSYSTEM_CMYK (ROAR_COLOR_TYPE_C|ROAR_COLOR_TYPE_M|ROAR_COLOR_TYPE_Y|ROAR_COLOR_TYPE_K) struct roar_color_gray { unsigned char k; }; struct roar_color_rgb { unsigned char r, g, b; }; struct roar_color_rgba { unsigned char r, g, b, a; }; struct roar_color_yuv { unsigned char y, u, v; }; struct roar_color_cmyk { unsigned char c, m, y, k; }; struct roar_color { uint32_t system; union { struct roar_color_gray gray; struct roar_color_rgb rgb; struct roar_color_rgba rgba; struct roar_color_yuv yuv; struct roar_color_cmyk cmyk; } color; }; //#define roar_color_new_rgb(color,r,g,b) (color)->system = ROAR_COLORSYSTEM_RGB; (color)->color.rgb.r = (r); (color)->color.rgb.b = (g); (color)->color.rgb.b = (b) int roar_color_new (struct roar_color * c); int roar_color_new_gray (struct roar_color * c, unsigned char k); int roar_color_new_rgb (struct roar_color * c, unsigned char r, unsigned char g, unsigned char b); int roar_color_copy (struct roar_color * dst, struct roar_color * src); int roar_color_conv (struct roar_color * c, uint32_t system); int roar_color_conv_gray (struct roar_color * c, uint32_t system); int roar_color_conv_rgb (struct roar_color * c, uint32_t system); int roar_color_to_string (struct roar_color * c, char * str, size_t len); int roar_color_to_blob (struct roar_color * c, char * blob, size_t len); int roar_color_from_blob (struct roar_color * c, char * blob, size_t len); #endif //ll ���������������������������������������������������������������roaraudio-1.0beta11/include/libroarlight/laser.h����������������������������������������������������0000644�0001750�0001750�00000003324�12264733507�020056� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//laser.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARLIGHT_LASER_H_ #define _LIBROARLIGHT_LASER_H_ #include "libroarlight.h" struct roar_laser_point { struct roar_point point; struct roar_color color; }; struct roar_laser_frame { uint_least32_t pps; size_t points; struct roar_laser_point * data; }; #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarlight/libroarlight.h���������������������������������������������0000644�0001750�0001750�00000003151�12264733507�021430� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarlight.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARLIGHT_H_ #define _LIBROARLIGHT_H_ #include <roaraudio.h> #include <libroardsp/libroardsp.h> #include "colors.h" #include "roardmx.h" #include "pwm.h" #include "laser.h" #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarlight/pwm.h������������������������������������������������������0000644�0001750�0001750�00000003461�12264733510�017547� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//pwm.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARLIGHT_PWM_H_ #define _LIBROARLIGHT_PWM_H_ #include "libroarlight.h" struct roar_lpwm_state { int bits; int fill; int value; uint64_t s; }; int roar_light_pwm_new (struct roar_lpwm_state * state, int bits ); int roar_light_pwm_set (struct roar_lpwm_state * state, int value); int roar_light_pwm_send(struct roar_lpwm_state * state, struct roar_vio_calls * vio, size_t len); #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarlight/roardmx.h��������������������������������������������������0000644�0001750�0001750�00000016100�12266500711�020407� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roardmx.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARLIGHT_ROARDMX_H_ #define _LIBROARLIGHT_ROARDMX_H_ #include "libroarlight.h" #define ROAR_ROARDMX_VERSION 0x00 #define ROAR_ROARDMX_MASK_FLAGS 0xF0 #define ROAR_ROARDMX_MASK_TYPE 0x0F #define ROAR_ROARDMX_DATA_LENGTH ((1<<(sizeof(char)*8))-1) /* 255 */ // we have a offset of one nibble, see ROAR_ROARDMX_MASK_FLAGS #define ROAR_ROARDMX_FLAG_PACKED 0x10 #define ROAR_ROARDMX_TYPE_SSET 0x00 /* simple set */ #define ROAR_ROARDMX_TYPE_IPO1 0x01 /* linear interploation */ #define ROAR_ROARDMX_TYPE_IPOLIN ROAR_ROARDMX_TYPE_IPO1 #define ROAR_ROARDMX_TYPE_IPO4 0x02 /* poly5 interpolation (a*t^4 + b*t^3 + c*t^2 + d*t + e) */ #define ROAR_ROARDMX_TYPE_INC8S 0x03 /* signed 8 bit increment */ #define ROAR_ROARDMX_TYPE_RANGESET 0x04 /* like simple set but set ranges of channels */ #define ROAR_ROARDMX_TYPE_EVENT 0x0E /* used to transmit simple events like step, blackout and stuff */ #define ROAR_ROARDMX_TYPE_CONTROL 0x0F /* Used to transmit other control information like codec version */ // Events: // event types (ETYPE) will be bit or-ed with event. #define ROAR_ROARDMX_MASK_EVENT 0x3F #define ROAR_ROARDMX_MASK_ETYPE 0xC0 #define ROAR_ROARDMX_ETYPE_BEAT 0x00 /* event happens NOW */ #define ROAR_ROARDMX_ETYPE_OFF 0x40 /* event ended */ #define ROAR_ROARDMX_ETYPE_ON 0x80 /* event started */ #define ROAR_ROARDMX_ETYPE_HOLD 0xC0 /* event is still running, used as keep-alive */ // events: must be in range 0x00 to 0x3F. #define ROAR_ROARDMX_EVENT_NONE 0x00 /* can be used as keep-alive or padding */ #define ROAR_ROARDMX_EVENT_STEP 0x01 #define ROAR_ROARDMX_EVENT_TAP 0x02 #define ROAR_ROARDMX_EVENT_BEAT 0x03 /* audio signal generated beat */ #define ROAR_ROARDMX_EVENT_BLACKOUT 0x04 /* set all light channels to zero */ #define ROAR_ROARDMX_EVENT_FULLON 0x05 /* set all light channels to full intensity */ #define ROAR_ROARDMX_EVENT_FLASH 0x06 /* like fullon but can also use strobe. */ #define ROAR_ROARDMX_EVENT_STROBE 0x07 /* triggers all strobes */ #define ROAR_ROARDMX_EVENT_STROBEREADY 0x08 /* strobe is ready */ #define ROAR_ROARDMX_EVENT_STROBELOAD 0x09 /* strobe is loading */ #define ROAR_ROARDMX_EVENT_FOG 0x0A /* triggers all fog machines */ #define ROAR_ROARDMX_EVENT_FOGREADY 0x0B /* Fog machine is ready */ #define ROAR_ROARDMX_EVENT_FOGHEAT 0x0C /* Fog machine is heating up */ // Data format on the wire: /* * All packets consist of a header and a body. * The header has the size of 3 Bytes: * 0) version. Must be ROAR_ROARDMX_VERSION. * 1) packet type and flags. * 2) length of body in bytes. * * the type-flags byte consists of the packet type in the lower nibble and * the flags in the upper nibble. * * the header is followd by a body of zero to 255 bytes length. * the content of the body depends on the used type of packet. * * SSET: (simple set) Sets channels to values. * The body consists of {channel, value}-pairs. * every entry is 3 byte: hi byte of channel, low byte of channel, value. * * IPO1: not implemented. * IPO4: not implemented. * INC8S: not implemented. * RANGESET: not implemented. * EVENT: transmit simple yet abstract events. * The body is an array of bytes. Each byte represents one event. * Each event has the upper two bits set to the meta type of the event * (beat, on, off, hold) and the lower 6 bits to the type of te event. * * CONTROL: not implemented. */ struct roar_roardmx_message { unsigned char version; unsigned char flags; unsigned char type; size_t length; unsigned char data[3 /* header */ + ROAR_ROARDMX_DATA_LENGTH /* data */]; }; // database access: int roar_roardmx_str2event(const char * event); const char * roar_roardmx_event2str(const int event); // generic things: int roar_roardmx_message_new (struct roar_roardmx_message * mes); // low level: //int roar_roardmx_message_set_flag(struct roar_roardmx_message * mes, unsigned char flag); //int roar_roardmx_message_set_len (struct roar_roardmx_message * mes, size_t type); //int roar_roardmx_message_get_data(struct roar_roardmx_message * mes, unsigned char ** data); // mdium level: int roar_roardmx_message_set_type(struct roar_roardmx_message * mes, unsigned char type); int roar_roardmx_message_get_flag(struct roar_roardmx_message * mes, unsigned char * flag); int roar_roardmx_message_get_type(struct roar_roardmx_message * mes, unsigned char * type); int roar_roardmx_message_get_len (struct roar_roardmx_message * mes, size_t * length); // IO: int roar_roardmx_message_send(struct roar_roardmx_message * mes, struct roar_vio_calls * vio); int roar_roardmx_message_recv(struct roar_roardmx_message * mes, struct roar_vio_calls * vio); // Data/high level: // * *: int roar_roardmx_message_numchannels(struct roar_roardmx_message * mes); int roar_roardmx_message_add_chanval(struct roar_roardmx_message * mes, uint16_t channel, unsigned char val); int roar_roardmx_message_get_chanval(struct roar_roardmx_message * mes, uint16_t * channel, unsigned char * val, int index); // * SSET: int roar_roardmx_message_new_sset (struct roar_roardmx_message * mes); // * IPO1: // Not yet supported. // * IPO4: // Not yet supported. // * INC8S: // Not yet supported. // * RANGESET: // Not yet supported. // * EVENT: int roar_roardmx_message_new_event(struct roar_roardmx_message * mes); int roar_roardmx_message_add_events(struct roar_roardmx_message * mes, const uint8_t * events, size_t len); #define roar_roardmx_message_add_event(mes,event) roar_roardmx_message_add_events((mes), &(uint8_t){(event)}, 1) int roar_roardmx_message_get_events(struct roar_roardmx_message * mes, const uint8_t ** events, size_t * len); // * CONTROL: // Not yet supported. #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarmidi/������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016411� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarmidi/libroarmidi.h�����������������������������������������������0000644�0001750�0001750�00000002765�12264733510�021062� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarmidi.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARMIDI_H_ #define _LIBROARMIDI_H_ #include <roaraudio.h> #endif //ll �����������roaraudio-1.0beta11/include/libroarpulse/�����������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016617� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarpulse/libroarpulse.h���������������������������������������������0000644�0001750�0001750�00000005157�12264733511�021475� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarpulse.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARPULSE_H_ #define _LIBROARPULSE_H_ #include <roaraudio.h> #include <pulse/pulseaudio.h> #include <pulse/simple.h> #include <libroarpulse/simple.h> #define ROAR_PA_DEFAULT_SINK "RoarAudio_default_sink" #define ROAR_PA_DEFAULT_SOURCE "RoarAudio_default_source" // POSIX does not clearly specify what happens on NULL #define ROAR_STRDUP(x) ((x) == NULL ? NULL : strdup((x))) int roar_codec_pulse2roar (int codec); int roar_pa_sspec2auinfo (struct roar_audio_info * info, const pa_sample_spec * ss); int roar_pa_auinfo2sspec (pa_sample_spec * ss, const struct roar_audio_info * info); const char * roar_pa_find_server (const char * server); int roar_pa_raerror2paerror(int error); struct roar_connection * roar_pa_context_get_con(pa_context * c); pa_mainloop_api * roar_pa_context_get_api(pa_context * c); pa_operation *roar_pa_operation_new(pa_operation_state_t initstate); #define roar_pa_op_new_done() roar_pa_operation_new(PA_OPERATION_DONE) #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarpulse/simple.h���������������������������������������������������0000644�0001750�0001750�00000003456�12264733511�020263� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//simple.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _LIBROARPULSE_SIMPLE_H_ #define _LIBROARPULSE_SIMPLE_H_ #include <libroarpulse/libroarpulse.h> // this file is currently not needed. #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarrsound/����������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�017001� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarrsound/libroarrsound.h�������������������������������������������0000644�0001750�0001750�00000003226�12264733512�022035� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarrsound.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from RSound. * They are copyrighted by Hans-Kristian 'maister' Arntzen. * * This file is part of libroarrsound a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #ifndef _LIBROARRSOUND_H_ #define _LIBROARRSOUND_H_ #include <roaraudio.h> #include <rsound.h> #define LIBROARRSOUND_FLAGS_NONE 0x00 #define LIBROARRSOUND_FLAGS_CONNECTED 0x01 #define LIBROARRSOUND_FLAGS_STREAMING 0x02 struct libroarrsound { rsound_t rsound; int flags; struct roar_connection con; struct roar_stream stream; struct roar_vio_calls vio; }; #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarsndio/�����������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016603� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarsndio/libroarsndio.h���������������������������������������������0000644�0001750�0001750�00000006445�12264733513�021450� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarsndio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #ifndef _LIBROARSNDIO_H_ #define _LIBROARSNDIO_H_ #include <roaraudio.h> #ifdef __cplusplus extern "C" { #endif #if defined(ROAR_HAVE_LIBSNDIO) && !defined(_ROAR_EMUL_LIBSNDIO) && !defined(ROAR_USE_OWN_SNDIO_HDL) #include <sndio.h> #else #define sio_hdl roar_sio_hdl #define mio_hdl roar_sio_hdl #include "sndiosym.h" #endif #if !defined(ROAR_HAVE_LIBSNDIO) || defined(ROAR_USE_OWN_SNDIO_HDL) #ifdef sio_hdl #undef sio_hdl #endif #define sio_hdl roar_sio_hdl #ifdef mio_hdl #undef mio_hdl #endif #define mio_hdl roar_sio_hdl #endif struct roar_sio_hdl { char * device; // int fh; int stream_opened; int dir; int nonblock; int ioerror; struct roar_vio_calls svio; struct roar_connection con; struct roar_stream stream; struct roar_audio_info info; struct sio_par para; void (*on_move)(void * arg, int delta); void * on_move_arg; void (*on_vol )(void * arg, unsigned vol); void * on_vol_arg; }; #ifdef __cplusplus } #endif #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroarsndio/sndiosym.h�������������������������������������������������0000644�0001750�0001750�00000014446�12264733515�020630� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//sndiosym.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #ifndef _LIBROARSNDIO_SNDIOSYM_H_ #define _LIBROARSNDIO_SNDIOSYM_H_ #include <roaraudio.h> #ifdef ROAR_HAVE_H_POLL #include <poll.h> #else struct pollfd; #endif #define SIO_PLAY 1 #define SIO_REC 2 #define MIO_OUT 4 #define MIO_IN 8 #define SIO_IGNORE 0 /* pause during xrun */ #define SIO_SYNC 1 /* resync after xrun */ #define SIO_ERROR 2 /* terminate on xrun */ #define SIO_XSTRINGS {"ignore", "sync", "error"} #define SIO_NENC 16 #define SIO_NCHAN 8 #define SIO_NRATE 16 #define SIO_NCONF 4 #define SIO_ENCMAX 10 #if BYTE_ORDER == BIG_ENDIAN && !defined(ROAR_TARGET_WIN32) #define SIO_LE_NATIVE 0 #else #if BYTE_ORDER == LITTLE_ENDIAN #define SIO_LE_NATIVE 1 #else #error Byte Order of this system is not supported within the sndio interface. #endif #endif #define SIO_BPS(bits) (((bits) <= 8) ? 1 : (((bits) <= 16) ? 2 : 4)) #define SIO_SUN_PATH NULL #define SIO_AUCAT_PATH NULL #define SIO_MAXVOL 127 struct sio_par { unsigned bits; /* bits per sample */ unsigned bps; /* bytes per sample */ unsigned sig; /* 1 = signed, 0 = unsigned */ unsigned le; /* 1 = LE, 0 = BE byte order */ unsigned msb; /* 1 = MSB, 0 = LSB aligned */ unsigned rchan; /* number channels for recording */ unsigned pchan; /* number channels for playback */ unsigned rate; /* frames per second */ unsigned appbufsz; /* minimum buffer size without xruns */ unsigned bufsz; /* end-to-end buffer size (read-only) */ unsigned round; /* optimal buffer size divisor */ unsigned xrun; /* what to do on overrun/underrun */ }; struct sio_cap { struct sio_enc { /* allowed encodings */ unsigned bits; /* bits per sample */ unsigned bps; /* bytes per sample */ unsigned sig; /* 1 = signed, 0 = unsigned */ unsigned le; /* 1 = LE, 0 = BE byte order */ unsigned msb; /* 1 = MSB, 0 = LSB aligned */ } enc[SIO_NENC]; unsigned rchan[SIO_NCHAN]; /* allowed rchans */ unsigned pchan[SIO_NCHAN]; /* allowed pchans */ unsigned rate[SIO_NRATE]; /* allowed rates */ unsigned nconf; /* num. of confs[] */ struct sio_conf { unsigned enc; /* bitmask of enc[] indexes */ unsigned rchan; /* bitmask of rchan[] indexes */ unsigned pchan; /* bitmask of pchan[] indexes */ unsigned rate; /* bitmask of rate[] indexes */ } confs[SIO_NCONF]; }; struct sio_hdl * sio_open(const char * name, unsigned mode, int nbio_flag); void sio_close (struct sio_hdl * hdl); void sio_initpar(struct sio_par * par); int sio_setpar (struct sio_hdl * hdl, struct sio_par * par); int sio_getpar (struct sio_hdl * hdl, struct sio_par * par); int sio_getcap (struct sio_hdl * hdl, struct sio_cap * cap); int sio_start (struct sio_hdl * hdl); int sio_stop (struct sio_hdl * hdl); size_t sio_read (struct sio_hdl * hdl, void * addr, size_t nbytes); size_t sio_write (struct sio_hdl * hdl, const void * addr, size_t nbytes); void sio_onmove (struct sio_hdl * hdl, void (*cb)(void * arg, int delta), void * arg); int sio_nfds (struct sio_hdl * hdl); int sio_pollfd (struct sio_hdl * hdl, struct pollfd * pfd, int events); int sio_revents(struct sio_hdl * hdl, struct pollfd * pfd); int sio_eof (struct sio_hdl * hdl); int sio_setvol (struct sio_hdl * hdl, unsigned vol); void sio_onvol (struct sio_hdl * hdl, void (*cb)(void * arg, unsigned vol), void * arg); // MIDI: struct mio_hdl * mio_open (const char * name, unsigned mode, int nbio_flag); void mio_close (struct mio_hdl * hdl); size_t mio_write (struct mio_hdl * hdl, const void * addr, size_t nbytes); size_t mio_read (struct mio_hdl * hdl, void * addr, size_t nbytes); int mio_nfds (struct mio_hdl * hdl); int mio_pollfd (struct mio_hdl * hdl, struct pollfd * pfd, int events); int mio_revents(struct mio_hdl * hdl, struct pollfd * pfd); int mio_eof (struct mio_hdl * hdl); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroaryiff/������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553172�016424� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/libroaryiff/libroaryiff.h�����������������������������������������������0000644�0001750�0001750�00000002455�12264733516�021112� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroaryiff.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _LIBROARYIFF_H_ #define _LIBROARYIFF_H_ #include <roaraudio.h> #include <Y2/Y.h> /* Basic Y types and constants. */ #include <Y2/Ylib.h> /* YLib functions and structs. */ #include <unistd.h> #include <string.h> #include <stdlib.h> // YID 0 is error like -1 on libroar! #define ROARYIFF_YID2ROAR(x) ((x)-1) #define ROARYIFF_ROAR2YID(x) ((x)+1) #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/��������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�016100� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/acl.h���������������������������������������������������������0000644�0001750�0001750�00000004404�12264733517�017013� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//acl.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_ACL_H_ #define _ROARAUDIO_ACL_H_ // basic rule constants #define ROAR_ACL_DENY 0 #define ROAR_ACL_REJECT ROAR_ACL_DENY #define ROAR_ACL_ALLOW 1 #define ROAR_ACL_ALLOW_OWN 2 struct roar_acl_target { int connect; int stream; int connect_to; int exit; int standby; int kick; int list; int meta; int volume; int get_client; int get_stream; int beep; }; #define ROAR_ACL_CHK(r,w,o) (( ((r)->w) == ROAR_ACL_ALLOW || (((r)->w) == ROAR_ACL_ALLOW_OWN && (o)) ) ? 1 : 0) #define ROAR_ACL_CMP_NOT 0x10 #define ROAR_ACL_CMP_EQ 0x01 #define ROAR_ACL_TYPE_ID 1 #define ROAR_ACL_TYPE_INT 1 #define ROAR_ACL_TYPE_VOID 1 struct roar_acl_cmp { int op; int type; union { id_t id; int i; void * p; } data; int datalen; }; // A rule. // All entrys may be NULL to indicate not to compare them. // The only option is addr_use_inet_port which is used to disable checking of // the remote IP. struct roar_acl_rule { pid_t * pid; uid_t * uid; gid_t * gid; char * username; int * cookie; struct sockaddr * addr; socklen_t addrlen; int addr_use_inet_port; }; #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/audio.h�������������������������������������������������������0000644�0001750�0001750�00000024042�12264733517�017355� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//audio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_AUDIO_H_ #define _ROARAUDIO_AUDIO_H_ // TODO: move this block to a more logical location. #define ROAR_CODEC_PCM_LE ROAR_CODEC_PCM_S_LE #define ROAR_CODEC_PCM_BE ROAR_CODEC_PCM_S_BE #define ROAR_CODEC_PCM_PDP ROAR_CODEC_PCM_S_PDP /* Bits: 76543210 |||||||\---\ byte- ||||||\----/ order |||||\-----> unsigned? ||||\------> PCM(0) or MIDI(1)? |||\-------> PCM/MIDI(0) or hi-level codecs(1) ||\--------> MISC(0) or RIFF/WAVE like(1) |\---------> first set(0) or second set(1) \----------> (0) BB = Byte order / MSB/LSB -- First Set: MIDI 0x08: 76543210 000 0x08 -> MIDI File hi-level 0x10: 76543210 0000 0x10 -> Ogg Vorbis 0001 0x11 -> Native FLAC 0010 0x12 -> Ogg Speex 0011 0x13 -> Reserved for CELT 0100 0x14 -> Ogg FLAC 0101 0x15 -> Ogg General 0110 0x16 -> Ogg CELT 0111 0x17 -> Ogg [...] **** 0x1a -> ROAR CELT **** 0x1b -> ROAR SPEEX **** 0x1c -> RAUM **** 0x1d -> RAUM Vorbis **** 0x1e -> RAUM FLAC RIFF/WAVE like 0x20: 76543210 0000 0x20 -> RIFF/WAVE LOG Codecs 0x30: 76543210 00BB 0x30 -> A-Law (base) 01BB 0x34 -> mu-Law (base) -- Second Set: Bits: 76543210 |||||||\---\ byte- ||||||\----/ order |||||\-----> unsigned? (or other flags) ||||\------> META: text(0) or binary(1) |||\-------> META(0)/CONTAINER(1) ||\--------> Specal codecs(0) |\---------> second set(1) \----------> (0) Meta Codecs 0x40: 76543210 0000 0x40 -> Meta Text: Vorbis Comment Like [...] 0100 0x44 -> Meta Text: RoarAudio Like [...] 11BB 0x4c -> Meta Binary: RoarAudio Like Container 0x50: 76543210 0000 0x50 -> Null container: pass 0001 0x51 -> Gzip 0010 0x52 -> Bzip2 0011 0x53 -> OpenPGP bin 0100 0x54 -> OpenPGP asc 0101 0x55 -> TAR Bits: 76543210 |||||||\---\ byte- ||||||\----/ order |||||\-----> unsigned? (or other flags) ||||\------> (0) |||\-------> MIDI(0)/Light(1) ||\--------> MIDI and Light(1) |\---------> second set(1) \----------> (0) MIDI 0x60: 76543210 0000 -> MIDI Light 0x70: 76543210 0000 -> DMX512 0001 -> RoarDMX Bits: 76543210 |||||||\---\ byte- ||||||\----/ order |||||\-----> unsigned? (or other flags) ||||\------> ID |||\-------> RDTCS(0) / User/Vendor Specific(1) ||\--------> first subset(0) |\---------> first set(0) \----------> (1) RDTCS 0x80: 76543210 0000 -> RDS User 0x90: 76543210 0000 -> USER0 [...] 1111 -> USER15 */ #define ROAR_CODEC_IS_SIGNED(x) (((x) & ROAR_CODEC_UNSIGNED) == 0 ? 1 : 0) #define ROAR_CODEC_BYTE_ORDER(x) ((x) & 0x03) #define ROAR_CODEC_UNSIGNED (1 << 2) #define ROAR_CODEC_LE 0x01 #define ROAR_CODEC_BE 0x02 #define ROAR_CODEC_PDP 0x03 #define ROAR_CODEC_MSB 0x00 #define ROAR_CODEC_LSB 0x01 #define ROAR_CODEC_PCM 0x00 #define ROAR_CODEC_PCM_S_LE (ROAR_CODEC_PCM | ROAR_CODEC_LE ) #define ROAR_CODEC_PCM_S_BE (ROAR_CODEC_PCM | ROAR_CODEC_BE ) #define ROAR_CODEC_PCM_S_PDP (ROAR_CODEC_PCM | ROAR_CODEC_PDP) #define ROAR_CODEC_PCM_U_LE (ROAR_CODEC_PCM_S_LE | ROAR_CODEC_UNSIGNED) #define ROAR_CODEC_PCM_U_BE (ROAR_CODEC_PCM_S_BE | ROAR_CODEC_UNSIGNED) #define ROAR_CODEC_PCM_U_PDP (ROAR_CODEC_PCM_S_PDP | ROAR_CODEC_UNSIGNED) #define ROAR_CODEC_MIDI_FILE 0x08 #define ROAR_CODEC_OGG_VORBIS 0x10 #define ROAR_CODEC_FLAC 0x11 /* native FLAC without Ogg container */ #define ROAR_CODEC_OGG_SPEEX 0x12 /* #define ROAR_CODEC_CELT/OGG_CELT 0x13 Reserved for CELT */ #define ROAR_CODEC_OGG_FLAC 0x14 #define ROAR_CODEC_OGG_GENERAL 0x15 #define ROAR_CODEC_OGG_CELT 0x16 #define ROAR_CODEC_OGG 0x17 #define ROAR_CODEC_OGG_OPUS 0x18 #define ROAR_CODEC_ROAR_OPUS 0x19 #define ROAR_CODEC_ROAR_CELT 0x1a #define ROAR_CODEC_ROAR_SPEEX 0x1b #define ROAR_CODEC_RAUM 0x1c #define ROAR_CODEC_RAUM_VORBIS 0x1d #define ROAR_CODEC_RAUM_FLAC 0x1e #define ROAR_CODEC_RIFF_WAVE 0x20 #define ROAR_CODEC_RIFX (ROAR_CODEC_RIFF_WAVE | ROAR_CODEC_BE) #define ROAR_CODEC_AU 0x24 #define ROAR_CODEC_AIFF 0x28 #define ROAR_CODEC_ALAW 0x30 #define ROAR_CODEC_AUTLAW_LE (ROAR_CODEC_ALAW|ROAR_CODEC_LE) #define ROAR_CODEC_AUTLAW_BE (ROAR_CODEC_ALAW|ROAR_CODEC_BE) #define ROAR_CODEC_AUTLAW ROAR_CODEC_AUTLAW_BE #define ROAR_CODEC_MULAW 0x34 #define ROAR_CODEC_MUUTLAW_LE (ROAR_CODEC_MULAW|ROAR_CODEC_LE) #define ROAR_CODEC_MUUTLAW_BE (ROAR_CODEC_MULAW|ROAR_CODEC_BE) #define ROAR_CODEC_MUUTLAW ROAR_CODEC_MUUTLAW_BE #define ROAR_CODEC_GSM 0x38 #define ROAR_CODEC_GSM49 0x39 #define ROAR_CODEC_BRR 0x3c /* SPC-700 Bit Rate Reduction of */ /* Super Nintendo Entertainment System (SNES) */ // Meta Codecs: #define ROAR_CODEC_META_VCLT 0x40 /* VCLT = Vorbis Comment Like Text */ #define ROAR_CODEC_META_RALT 0x44 /* RALT = RoarAudio Like Text */ #define ROAR_CODEC_META_RALB 0x4c /* RALB = RoarAudio Like Binary */ /* if no byte order is given then you should assume BE as it is network byte order */ #define ROAR_CODEC_META_RALB_LE (ROAR_CODEC_META_RALB | ROAR_CODEC_LE ) #define ROAR_CODEC_META_RALB_BE (ROAR_CODEC_META_RALB | ROAR_CODEC_BE ) #define ROAR_CODEC_META_RALB_PDP (ROAR_CODEC_META_RALB | ROAR_CODEC_PDP) // Container Codecs: /* Container 0x50: 76543210 0000 0x50 -> Null container: pass 0001 0x51 -> Gzip 0010 0x52 -> Bzip2 0011 0x53 -> OpenPGP bin 0100 0x54 -> OpenPGP asc 0101 0x55 -> TAR */ #define ROAR_CODEC_CONT_NULL 0x50 #define ROAR_CODEC_CONT_BASE ROAR_CODEC_CONT_NULL #define ROAR_CODEC_CONT_GZIP 0x51 #define ROAR_CODEC_CONT_BZIP2 0x52 #define ROAR_CODEC_CONT_OPGPBIN 0x53 #define ROAR_CODEC_CONT_OPGPASC 0x54 #define ROAR_CODEC_CONT_TAR 0x55 // MIDI: #define ROAR_CODEC_MIDI 0x60 #define ROAR_CODEC_ROARMIDI 0x64 // Light Control: #define ROAR_CODEC_DMX512 0x70 #define ROAR_CODEC_ROARDMX 0x71 // RDTCS: #define ROAR_CODEC_RDS 0x80 // User specific: #define ROAR_CODEC_USER0 0x90 #define ROAR_CODEC_USER1 0x91 #define ROAR_CODEC_USER2 0x92 #define ROAR_CODEC_USER3 0x93 #define ROAR_CODEC_USER4 0x94 #define ROAR_CODEC_USER5 0x95 #define ROAR_CODEC_USER6 0x96 #define ROAR_CODEC_USER7 0x97 #define ROAR_CODEC_USER8 0x98 #define ROAR_CODEC_USER9 0x99 #define ROAR_CODEC_USER10 0x9a #define ROAR_CODEC_USER11 0x9b #define ROAR_CODEC_USER12 0x9c #define ROAR_CODEC_USER13 0x9d #define ROAR_CODEC_USER14 0x9e #define ROAR_CODEC_USER15 0x9f #if BYTE_ORDER == BIG_ENDIAN #define ROAR_CODEC_NATIVE_ENDIAN ROAR_CODEC_BE #define ROAR_CODEC_PCM_S ROAR_CODEC_PCM_S_BE #define ROAR_CODEC_PCM_U ROAR_CODEC_PCM_U_BE #define ROAR_BE2DEF(x) (x) #elif BYTE_ORDER == LITTLE_ENDIAN #define ROAR_CODEC_NATIVE_ENDIAN ROAR_CODEC_LE #define ROAR_CODEC_PCM_S ROAR_CODEC_PCM_S_LE #define ROAR_CODEC_PCM_U ROAR_CODEC_PCM_U_LE #define ROAR_LE2DEF(x) (x) #else #define ROAR_CODEC_NATIVE_ENDIAN ROAR_CODEC_PDP #define ROAR_CODEC_PCM_S ROAR_CODEC_PCM_S_PDP #define ROAR_CODEC_PCM_U ROAR_CODEC_PCM_U_PDP #define ROAR_PDP2DEF(x) (x) #endif #define ROAR_CODEC_DEFAULT ROAR_CODEC_PCM_S #define ROAR_CODEC_NATIVE ROAR_CODEC_DEFAULT #define ROAR_BITS_MAX 32 #ifndef ROAR_BITS_DEFAULT #define ROAR_BITS_DEFAULT 16 #endif #ifndef ROAR_CHANNELS_DEFAULT #define ROAR_CHANNELS_DEFAULT 2 #endif #ifndef ROAR_RATE_DEFAULT #define ROAR_RATE_DEFAULT 44100 #endif #define ROAR_MIDI_TICKS_PER_BEAT 96 #define ROAR_MIDI_BITS 8 #define ROAR_MIDI_CHANNELS_DEFAULT 16 #define ROAR_MAX_CHANNELS 64 #define ROAR_SET_VOL_ALL 1 #define ROAR_SET_VOL_ONE 2 #define ROAR_SET_VOL_MS 3 #define ROAR_SET_VOL_UNMAPPED 4 #define ROAR_SPEEX_MAX_CC 256 #define ROAR_SPEEX_MAGIC "RoarSpeex" #define ROAR_SPEEX_MAGIC_LEN 9 #define ROAR_SPEEX_MODE_NB 1 #define ROAR_SPEEX_MODE_WB 2 #define ROAR_SPEEX_MODE_UWB 3 #define ROAR_CELT_MAGIC_0 "RoarCELT0" #define ROAR_CELT_MAGIC_1 "RoarCELT1" #define ROAR_CELT_MAGIC_LEN 9 #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 #define ROAR_CELT_MAGIC ROAR_CELT_MAGIC_1 #else #define ROAR_CELT_MAGIC ROAR_CELT_MAGIC_0 #endif #define ROAR_AUDIO_INFO_TYPE uint32_t #define ROAR_AUDIO_INFO_INVALID ((ROAR_AUDIO_INFO_TYPE)-1) struct roar_audio_info { ROAR_AUDIO_INFO_TYPE rate; ROAR_AUDIO_INFO_TYPE bits; ROAR_AUDIO_INFO_TYPE channels; ROAR_AUDIO_INFO_TYPE codec; }; struct roar_mixer_settings { //unsigned channels; uint16_t scale; uint16_t rpg_mul; // rpg = ReplayGain uint16_t rpg_div; uint16_t mixer[ROAR_MAX_CHANNELS]; }; #define ROAR_MIXER(x) ((struct roar_mixer_settings *)x) #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/beep.h��������������������������������������������������������0000644�0001750�0001750�00000003231�12264733520�017156� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//beep.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_BEEP_H_ #define _ROARAUDIO_BEEP_H_ #define ROAR_BEEP_MAX_VOL 65535 #define ROAR_BEEP_MAX_TIME 65535 /* ms */ #define ROAR_BEEP_MAX_FREQ 65535 /* Hz */ #define ROAR_BEEP_MAX_POS 32767 #define ROAR_BEEP_DEFAULT_VOL (ROAR_BEEP_MAX_VOL/4) #define ROAR_BEEP_DEFAULT_TIME 256 /* ms */ #define ROAR_BEEP_DEFAULT_FREQ 440 /* Hz */ #define ROAR_BEEP_DEFAULT_TYPE ROAR_BEEP_TYPE_DEFAULT #define ROAR_BEEP_TYPE_DEFAULT 0 #define ROAR_BEEP_TYPE_CBELL 1 #define ROAR_BEEP_TYPE_XBELL 2 #define ROAR_BEEP_TYPE_ERROR 3 #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/byteorder.h���������������������������������������������������0000644�0001750�0001750�00000006360�12264733521�020251� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//byteorder.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_BYTEORDER_H_ #define _ROARAUDIO_BYTEORDER_H_ #define _ROAR_MOVE_BYTE(x,p,n) ( \ ((uint_least64_t)( \ ((uint_least64_t)((uint_least64_t)(x) & ((uint_least64_t)0xFFUL << (8*(p))))) >> (8*(p)) \ )) << ((n)-8*((p)+1)) \ ) #if BYTE_ORDER == BIG_ENDIAN && !defined(ROAR_TARGET_WIN32) #define ROAR_NET2HOST64(x) (x) #define ROAR_HOST2NET64(x) (x) #define ROAR_NET2HOST32(x) (x) #define ROAR_HOST2NET32(x) (x) #define ROAR_NET2HOST16(x) (x) #define ROAR_HOST2NET16(x) (x) #define ROAR_BE2HOST64(x) (x) #define ROAR_HOST2BE64(x) (x) #define ROAR_BE2HOST32(x) (x) #define ROAR_HOST2BE32(x) (x) #define ROAR_BE2HOST16(x) (x) #define ROAR_HOST2BE16(x) (x) #define ROAR_LE2HOST32(x) ROAR_HOST2LE32(x) #define ROAR_HOST2LE32(x) (_ROAR_MOVE_BYTE((x), 0, 32) | _ROAR_MOVE_BYTE((x), 1, 32) | \ _ROAR_MOVE_BYTE((x), 2, 32) | _ROAR_MOVE_BYTE((x), 3, 32) ) #define ROAR_LE2HOST16(x) ROAR_HOST2LE16(x) #define ROAR_HOST2LE16(x) (_ROAR_MOVE_BYTE((x), 0, 16) | _ROAR_MOVE_BYTE((x), 1, 16) ) //#elif BYTE_ORDER == LITTLE_ENDIAN #else #if BYTE_ORDER == LITTLE_ENDIAN #define ROAR_NET2HOST64(x) ROAR_HOST2NET64(x) #define ROAR_HOST2NET64(x) ((uint_least64_t) \ (_ROAR_MOVE_BYTE((x), 0, 64) | _ROAR_MOVE_BYTE((x), 1, 64) | \ _ROAR_MOVE_BYTE((x), 2, 64) | _ROAR_MOVE_BYTE((x), 3, 64) | \ _ROAR_MOVE_BYTE((x), 4, 64) | _ROAR_MOVE_BYTE((x), 5, 64) | \ _ROAR_MOVE_BYTE((x), 6, 64) | _ROAR_MOVE_BYTE((x), 7, 64) ) ) #else /* PDP byte order */ #endif #define ROAR_NET2HOST32(x) ntohl((x)) #define ROAR_HOST2NET32(x) htonl((x)) #define ROAR_NET2HOST16(x) ntohs((x)) #define ROAR_HOST2NET16(x) htons((x)) #define ROAR_BE2HOST32(x) ntohl(x) #define ROAR_HOST2BE32(x) htonl(x) #define ROAR_BE2HOST16(x) ntohs(x) #define ROAR_HOST2BE16(x) htons(x) #define ROAR_LE2HOST64(x) (x) #define ROAR_HOST2LE64(x) (x) #define ROAR_LE2HOST32(x) (x) #define ROAR_HOST2LE32(x) (x) #define ROAR_LE2HOST16(x) (x) #define ROAR_HOST2LE16(x) (x) #endif #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/caps.h��������������������������������������������������������0000644�0001750�0001750�00000004241�12264733521�017174� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//caps.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_CAPS_H_ #define _ROARAUDIO_CAPS_H_ // cap flags: #define ROAR_CF_REQUEST 0x0001 // cap types: #define ROAR_CT_CAPS 0 #define ROAR_CT_STANDARDS 1 // standard vendors: #define ROAR_STDV_ROARAUDIO ((uint32_t)0) #define ROAR_STDV_PROTO ((uint32_t)1) #define ROAR_STDV_RFC ((uint32_t)2) // data macros for standards: #define ROAR_STD_MASK_VENDOR ((uint32_t)0xFF000000) #define ROAR_STD_MASK_STD ((uint32_t)0x00FFFF00) #define ROAR_STD_MASK_VERSION ((uint32_t)0x000000FF) #define ROAR_STD_MAKE(vendor,standard,version) ((((uint32_t)(vendor) & 0x00FF) << 24) | \ (((uint32_t)(standard) & 0xFFFF) << 8) | \ ((uint32_t)(version) & 0x00FF) ) #define ROAR_STD_MAKE_RFC(rfc) ROAR_STD_MAKE(ROAR_STDV_RFC, (rfc), 0) #define ROAR_STD_VENDOR(x) (((x) & ROAR_STD_MASK_VENDOR) >> 24) #define ROAR_STD_STD(x) (((x) & ROAR_STD_MASK_STD) >> 8) #define ROAR_STD_VERSION(x) ( (x) & ROAR_STD_MASK_VERSION ) #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/client.h������������������������������������������������������0000644�0001750�0001750�00000006061�12264733522�017527� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//client.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_CLIENT_H_ #define _ROARAUDIO_CLIENT_H_ #define ROAR_BUFFER_NAME 80 #define ROAR_CLIENTS_MAX 64 #define ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT 12 #define ROAR_PROTO_NONE 0 #define ROAR_PROTO_ROARAUDIO 1 #define ROAR_PROTO_ESOUND 2 #define ROAR_PROTO_AUTO 3 /* auto detect */ #define ROAR_PROTO_HTTP 4 #define ROAR_PROTO_GOPHER 5 #define ROAR_PROTO_ICY 7 /* Nullsoft ICY */ #define ROAR_PROTO_SIMPLE 8 /* PulseAudio Simple */ #define ROAR_PROTO_RSOUND 9 #define ROAR_PROTO_RPLAY 10 #define ROAR_PROTO_IRC 11 /* ID just for fun */ #define ROAR_PROTO_DCC 12 #define ROAR_PROTO_ECHO 13 /* for testing and stuff */ #define ROAR_PROTO_DISCARD 14 /* RFC 863 */ #define ROAR_PROTO_WHOIS 15 #define ROAR_PROTO_FINGER 16 #define ROAR_PROTO_QUOTE 17 /* RFC 865: Quote of the Day Protocol */ #define ROAR_PROTO_DAYTIME 18 #define ROAR_PROTO_GAME 19 /* a game, may be any game */ #define ROAR_PROTO_TELNET 20 #define ROAR_PROTO_DHCP 21 #define ROAR_PROTO_SSH 22 #define ROAR_PROTO_TIME 23 /* Time protocol, RFC 868 */ #define ROAR_PROTO_RLOGIN 24 #define ROAR_PROTO_RPLD 25 /* RoarAudio Playlist Daemon Protocol */ #define ROAR_PROTO_MPD 26 /* Music Player Daemon */ #define ROAR_BYTEORDER_UNKNOWN 0x00 #define ROAR_BYTEORDER_LE ROAR_CODEC_LE #define ROAR_BYTEORDER_BE ROAR_CODEC_BE #define ROAR_BYTEORDER_PDP ROAR_CODEC_PDP #define ROAR_BYTEORDER_NETWORK ROAR_BYTEORDER_BE #if BYTE_ORDER == BIG_ENDIAN #define ROAR_BYTEORDER_NATIVE ROAR_CODEC_BE #elif BYTE_ORDER == LITTLE_ENDIAN #define ROAR_BYTEORDER_NATIVE ROAR_CODEC_LE #else #define ROAR_BYTEORDER_NATIVE ROAR_CODEC_PDP #endif #define ROAR_CLIENTPASS_FLAG_NONE 0x0000 #define ROAR_CLIENTPASS_FLAG_LISTEN 0x0001 #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/compilerhacks.h�����������������������������������������������0000644�0001750�0001750�00000005411�12264733522�021073� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//compilerhacks.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_COMPILERHACKS_H_ #define _ROARAUDIO_COMPILERHACKS_H_ // just informative macros: #define _LIBROAR_GOOD_CAST #define _LIBROAR_BAD_CAST #if defined(__GNUC__) && __GNUC__ >= 4 #define _LIBROAR_ATTR_DEPRECATED __attribute__((deprecated)) #define _LIBROAR_ATTR_PURE __attribute__ ((pure)) #define _LIBROAR_ATTR_USE_RESULT __attribute__ ((warn_unused_result)) #define _LIBROAR_ATTR_PRINTF(str,args) __attribute__ ((format (printf, str, args))) // gcc does not only add a warning on NULL argument for the following // but also asumes they are never NULL (but allows them to be NULL) // and breaks our check this way. #if 0 #define _LIBROAR_ATTR_NONNULL(x, index...) __attribute__((nonnull ( x, ##index ))) #define _LIBROAR_ATTR_NONNULL_ALL __attribute__((nonnull)) #endif #endif // add more defintions for other compilers here. #ifndef _LIBROAR_ATTR_DEPRECATED #define _LIBROAR_ATTR_DEPRECATED #endif #ifndef _LIBROAR_ATTR_NONNULL #define _LIBROAR_ATTR_NONNULL(index...) #endif #ifndef _LIBROAR_ATTR_NONNULL_ALL #define _LIBROAR_ATTR_NONNULL_ALL #endif #ifndef _LIBROAR_ATTR_PURE #define _LIBROAR_ATTR_PURE #endif #ifndef _LIBROAR_ATTR_USE_RESULT #define _LIBROAR_ATTR_USE_RESULT #endif #ifndef _LIBROAR_ATTR_PRINTF #define _LIBROAR_ATTR_PRINTF(str,args) #endif #ifndef _LIBROAR_IGNORE_RET #define _LIBROAR_IGNORE_RET(x) ((void)((x)+1)) #endif #ifndef _LIBROAR_NOATTR_TO_STATIC #define _LIBROAR_ATTR_TO_STATIC _LIBROAR_ATTR_DEPRECATED #else #define _LIBROAR_ATTR_TO_STATIC #endif #ifdef _LIBROAR_NOATTR_WARNINGS #undef _LIBROAR_ATTR_DEPRECATED #define _LIBROAR_ATTR_DEPRECATED #undef _LIBROAR_ATTR_USE_RESULT #define _LIBROAR_ATTR_USE_RESULT #endif #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/error.h�������������������������������������������������������0000644�0001750�0001750�00000016600�12264733523�017403� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//error.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_ERROR_H_ #define _ROARAUDIO_ERROR_H_ #define ROAR_ERROR_UNKNOWN -1 /* Unknown (maybe no) error */ #define ROAR_ERROR_NONE 0 /* No error */ #define ROAR_ERROR_PERM 1 /* Operation not permitted */ #define ROAR_ERROR_NOENT 2 /* No such file or directory */ #define ROAR_ERROR_BADMSG 3 /* Bad message */ #define ROAR_ERROR_BUSY 4 /* Device or resource busy */ #define ROAR_ERROR_CONNREFUSED 5 /* Connection refused */ #define ROAR_ERROR_NOSYS 6 /* Function not implemented */ #define ROAR_ERROR_NOTSUP 7 /* Operation not supported */ #define ROAR_ERROR_PIPE 8 /* Broken pipe */ #define ROAR_ERROR_PROTO 9 /* Protocol error */ #define ROAR_ERROR_RANGE 10 /* Result too large/general out of range */ #define ROAR_ERROR_MSGSIZE 11 /* Message too long */ #define ROAR_ERROR_NOMEM 12 /* Not enough space */ #define ROAR_ERROR_INVAL 13 /* Invalid argument */ #define ROAR_ERROR_ALREADY 14 /* Connection already in progress */ #define ROAR_ERROR_BADRQC 15 /* Invalid request code */ #define ROAR_ERROR_DOM 16 /* Mathematics argument out of domain of function */ #define ROAR_ERROR_EXIST 17 /* File or object exists */ #define ROAR_ERROR_FAULT 18 /* Bad address */ #define ROAR_ERROR_IO 19 /* I/O-Error */ #define ROAR_ERROR_KEYEXPIRED 20 /* Key has expired */ #define ROAR_ERROR_KEYREJECTED 21 /* Key was rejected by service */ #define ROAR_ERROR_LOOP 22 /* Too many recursions */ #define ROAR_ERROR_MFILE 23 /* Too many open files or objects */ #define ROAR_ERROR_NAMETOOLONG 24 /* File or object name too long */ #define ROAR_ERROR_NODATA 25 /* No message is available on the read queue */ #define ROAR_ERROR_NODEV 26 /* No such device */ #define ROAR_ERROR_NODRV 27 /* No such driver */ #define ROAR_ERROR_NOSPC 38 /* No space left on device */ #define ROAR_ERROR_TYPEMM 39 /* Type missmatch. Object of diffrent type required */ #define ROAR_ERROR_NORSYS 40 /* Feature not implemented by remote end */ #define ROAR_ERROR_NOTCONN 41 /* Socket or object not connected */ #define ROAR_ERROR_PROTONOSUP 42 /* Protocol not supported */ #define ROAR_ERROR_RIO 43 /* Remote I/O Error */ #define ROAR_ERROR_RO 45 /* File or object is read only */ #define ROAR_ERROR_TIMEDOUT 46 /* Connection timed out */ #define ROAR_ERROR_AGAIN 47 /* Resource temporarily unavailable */ #define ROAR_ERROR_NOISE 48 /* Line too noisy */ #define ROAR_ERROR_LINKDOWN 49 /* Physical or logical link down */ #define ROAR_ERROR_INTERRUPTED 50 /* Operation was interruped */ #define ROAR_ERROR_CAUSALITY 51 /* Causality error */ #define ROAR_ERROR_QUOTA 52 /* Quota exceeded */ #define ROAR_ERROR_BADLIB 53 /* Accessing a corrupted shared library */ #define ROAR_ERROR_NOMEDIUM 54 /* No medium found */ #define ROAR_ERROR_NOTUNIQ 55 /* Name not unique */ #define ROAR_ERROR_ILLSEQ 56 /* Illegal byte sequence */ #define ROAR_ERROR_ADDRINUSE 57 /* Address in use */ #define ROAR_ERROR_HOLE 58 /* Hole in data */ #define ROAR_ERROR_BADVERSION 59 /* Bad version */ #define ROAR_ERROR_NSVERSION 60 /* Not supported version */ #define ROAR_ERROR_BADMAGIC 61 /* Bad magic number */ #define ROAR_ERROR_LOSTSYNC 62 /* Lost synchronization */ #define ROAR_ERROR_BADSEEK 63 /* Can not seek to destination position */ #define ROAR_ERROR_NOSEEK 64 /* Seeking not supported on resource */ #define ROAR_ERROR_BADCKSUM 65 /* Data integrity error */ #define ROAR_ERROR_NOHORSE 66 /* Mount failed */ #define ROAR_ERROR_CHERNOBYL 67 /* Fatal device error */ #define ROAR_ERROR_NOHUG 68 /* Device needs love */ #define ROAR_ERROR_TEXTBUSY 69 /* Text file busy */ #define ROAR_ERROR_NOTEMPTY 70 /* Directory not empty */ #define ROAR_ERROR_NODEUNREACH 71 /* Node is unreachable */ #define ROAR_ERROR_IDREMOVED 72 /* Identifier removed */ #define ROAR_ERROR_INPROGRESS 73 /* Operation in progress */ #define ROAR_ERROR_NOCHILD 74 /* No child processes/object */ #define ROAR_ERROR_NETUNREACH 75 /* Network unreachable */ #define ROAR_ERROR_CANCELED 76 /* Operation canceled */ #define ROAR_ERROR_ISDIR 77 /* Is a directory */ #define ROAR_ERROR_NOTDIR 78 /* Not a directory */ #define ROAR_ERROR_BADEXEC 79 /* Executable file format error */ #define ROAR_ERROR_ISCONN 80 /* Socket/Object is connected */ #define ROAR_ERROR_DEADLOCK 81 /* Resource deadlock would occur */ #define ROAR_ERROR_CONNRST 82 /* Connection reset */ #define ROAR_ERROR_BADFH 83 /* Bad file handle */ #define ROAR_ERROR_NOTSOCK 84 /* Not a socket */ #define ROAR_ERROR_TOOMANYARGS 85 /* Argument list too long */ #define ROAR_ERROR_TOOLARGE 86 /* File/Object too large */ #define ROAR_ERROR_DESTADDRREQ 87 /* Destination address required */ #define ROAR_ERROR_AFNOTSUP 88 /* Address family not supported */ #define ROAR_ERROR_NOPOWER 89 /* Operation can not be completed because we are low on power */ #define ROAR_ERROR_USER 90 /* Error in front of screen */ #define ROAR_ERROR_NFILE 91 /* Too many files/objects open in system */ #define ROAR_ERROR_STALE 92 /* Stale file handle or object */ #define ROAR_ERROR_XDEVLINK 93 /* Cross-device link */ #define ROAR_ERROR_MLINK 94 /* Too many links to file or object */ #define ROAR_ERROR_NONET 95 /* Not connected to any network */ #define ROAR_ERROR_CONNRSTNET 96 /* Connection reset by network */ #define ROAR_ERROR_CONNABORTED 97 /* Connection aborted */ #define ROAR_ERROR_BADHOST 98 /* Bad host software or hardware */ #define ROAR_ERROR_SWITCHPROTO 99 /* Switch protocol */ #define ROAR_ERROR_MOVEDPERM 100 /* Moved Permanently */ #define ROAR_ERROR_MOVEDTEMP 101 /* Moved Temporary */ #define ROAR_ERROR_USEPROXY 102 /* Use Proxy server */ #define ROAR_ERROR_SEEOTHER 103 /* See other resource */ #define ROAR_ERROR_GONE 104 /* Resource gone */ #define ROAR_ERROR_BADLICENSE 105 /* Bad License */ #define ROAR_ERROR_NEEDPAYMENT 106 /* Payment Required */ #define ROAR_ERROR_NSTYPE 107 /* Type or Format not supported */ #define ROAR_ERROR_CENSORED 108 /* Access denied because of censorship */ #define ROAR_ERROR_BADSTATE 109 /* Object is in bad/wrong state */ #define ROAR_ERROR_DISABLED 110 /* This has been disabled by the administrator */ #endif //ll ��������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/genre.h�������������������������������������������������������0000644�0001750�0001750�00000022721�12264733523�017353� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//genre.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_GENRE_H_ #define _ROARAUDIO_GENRE_H_ // Meta genres: #define ROAR_META_GENRE_META_NONE 0x0000 #define ROAR_META_GENRE_META_OTHER 0x0001 #define ROAR_META_GENRE_META_MUSIC 0x0002 #define ROAR_META_GENRE_META_MODERATION 0x0003 #define ROAR_META_GENRE_META_TEXT 0x0004 #define ROAR_META_GENRE_META_COMMERCIAL 0x0005 // EU: #define ROAR_META_GENRE_RDS_EU_NONE 0x0020 #define ROAR_META_GENRE_RDS_EU_NEWS 0x0021 #define ROAR_META_GENRE_RDS_EU_CURRENT_AFFAIRS 0x0022 #define ROAR_META_GENRE_RDS_EU_INFORMATION 0x0023 #define ROAR_META_GENRE_RDS_EU_SPORT 0x0024 #define ROAR_META_GENRE_RDS_EU_EDUCATION 0x0025 #define ROAR_META_GENRE_RDS_EU_DRAMA 0x0026 #define ROAR_META_GENRE_RDS_EU_CULTURE 0x0027 #define ROAR_META_GENRE_RDS_EU_SCIENCE 0x0028 #define ROAR_META_GENRE_RDS_EU_VARIED 0x0029 #define ROAR_META_GENRE_RDS_EU_POP_MUSIC 0x002a #define ROAR_META_GENRE_RDS_EU_ROCK_MUSIC 0x002b #define ROAR_META_GENRE_RDS_EU_EASY_LISTENING 0x002c #define ROAR_META_GENRE_RDS_EU_LIGHT_CLASSICAL 0x002d #define ROAR_META_GENRE_RDS_EU_SERIOUS_CLASSICAL 0x002e #define ROAR_META_GENRE_RDS_EU_OTHER_MUSIC 0x002f #define ROAR_META_GENRE_RDS_EU_WEATHER 0x0030 #define ROAR_META_GENRE_RDS_EU_FINANCE 0x0031 #define ROAR_META_GENRE_RDS_EU_CHILDREN_S_PROGRAMMES 0x0032 #define ROAR_META_GENRE_RDS_EU_SOCIAL_AFFAIRS 0x0033 #define ROAR_META_GENRE_RDS_EU_RELIGION 0x0034 #define ROAR_META_GENRE_RDS_EU_PHONE_IN 0x0035 #define ROAR_META_GENRE_RDS_EU_TRAVEL 0x0036 #define ROAR_META_GENRE_RDS_EU_LEISURE 0x0037 #define ROAR_META_GENRE_RDS_EU_JAZZ_MUSIC 0x0038 #define ROAR_META_GENRE_RDS_EU_COUNTRY_MUSIC 0x0039 #define ROAR_META_GENRE_RDS_EU_NATIONAL_MUSIC 0x003a #define ROAR_META_GENRE_RDS_EU_OLDIES_MUSIC 0x003b #define ROAR_META_GENRE_RDS_EU_FOLK_MUSIC 0x003c #define ROAR_META_GENRE_RDS_EU_DOCUMENTARY 0x003d #define ROAR_META_GENRE_RDS_EU_ALARM_TEST 0x003e #define ROAR_META_GENRE_RDS_EU_ALARM 0x003f #define ROAR_META_GENRE_RDS_EU_EMERGENCY_TEST ROAR_META_GENRE_RDS_EU_ALARM_TEST #define ROAR_META_GENRE_RDS_EU_EMERGENCY ROAR_META_GENRE_RDS_EU_ALARM // North America: #define ROAR_META_GENRE_RDS_NA_NONE 0x0040 #define ROAR_META_GENRE_RDS_NA_NEWS 0x0041 #define ROAR_META_GENRE_RDS_NA_INFORMATION 0x0042 #define ROAR_META_GENRE_RDS_NA_SPORTS 0x0043 #define ROAR_META_GENRE_RDS_NA_TALK 0x0044 #define ROAR_META_GENRE_RDS_NA_ROCK 0x0045 #define ROAR_META_GENRE_RDS_NA_CLASSIC_ROCK 0x0046 #define ROAR_META_GENRE_RDS_NA_ADULT_HITS 0x0047 #define ROAR_META_GENRE_RDS_NA_SOFT_ROCK 0x0048 #define ROAR_META_GENRE_RDS_NA_TOP_40 0x0049 #define ROAR_META_GENRE_RDS_NA_COUNTRY 0x004a #define ROAR_META_GENRE_RDS_NA_OLDIES 0x004b #define ROAR_META_GENRE_RDS_NA_SOFT 0x004c #define ROAR_META_GENRE_RDS_NA_NOSTALGIA 0x004d #define ROAR_META_GENRE_RDS_NA_JAZZ 0x004e #define ROAR_META_GENRE_RDS_NA_CLASSICAL 0x004f #define ROAR_META_GENRE_RDS_NA_RHYTHM_AND_BLUES 0x0050 #define ROAR_META_GENRE_RDS_NA_SOFT_RHYTHM_AND_BLUES 0x0051 #define ROAR_META_GENRE_RDS_NA_LANGUAGE 0x0052 #define ROAR_META_GENRE_RDS_NA_RELIGIOUS_MUSIC 0x0053 #define ROAR_META_GENRE_RDS_NA_RELIGIOUS_TALK 0x0054 #define ROAR_META_GENRE_RDS_NA_PERSONALITY 0x0055 #define ROAR_META_GENRE_RDS_NA_PUBLIC 0x0056 #define ROAR_META_GENRE_RDS_NA_COLLEGE 0x0057 #define ROAR_META_GENRE_RDS_NA_UNASSIGNED_0 0x0058 #define ROAR_META_GENRE_RDS_NA_UNASSIGNED_1 0x0059 #define ROAR_META_GENRE_RDS_NA_UNASSIGNED_2 0x005a #define ROAR_META_GENRE_RDS_NA_UNASSIGNED_3 0x005b #define ROAR_META_GENRE_RDS_NA_UNASSIGNED_4 0x005c #define ROAR_META_GENRE_RDS_NA_WEATHER 0x005d #define ROAR_META_GENRE_RDS_NA_EMERGENCY_TEST 0x005e #define ROAR_META_GENRE_RDS_NA_EMERGENCY 0x005f #define ROAR_META_GENRE_RDS_NA_ALARM_TEST ROAR_META_GENRE_RDS_NA_EMERGENCY_TEST #define ROAR_META_GENRE_RDS_NA_ALARM ROAR_META_GENRE_RDS_NA_EMERGENCY // ID3, standard + winamp ext: #define ROAR_META_GENRE_ID3_BLUES 0x0100 #define ROAR_META_GENRE_ID3_CLASSIC_ROCK 0x0101 #define ROAR_META_GENRE_ID3_COUNTRY 0x0102 #define ROAR_META_GENRE_ID3_DANCE 0x0103 #define ROAR_META_GENRE_ID3_DISCO 0x0104 #define ROAR_META_GENRE_ID3_FUNK 0x0105 #define ROAR_META_GENRE_ID3_GRUNGE 0x0106 #define ROAR_META_GENRE_ID3_HIP_HOP 0x0107 #define ROAR_META_GENRE_ID3_JAZZ 0x0108 #define ROAR_META_GENRE_ID3_METAL 0x0109 #define ROAR_META_GENRE_ID3_NEW_AGE 0x010a #define ROAR_META_GENRE_ID3_OLDIES 0x010b #define ROAR_META_GENRE_ID3_OTHER 0x010c #define ROAR_META_GENRE_ID3_POP 0x010d #define ROAR_META_GENRE_ID3_R_AND_B 0x010e #define ROAR_META_GENRE_ID3_RAP 0x010f #define ROAR_META_GENRE_ID3_REGGAE 0x0110 #define ROAR_META_GENRE_ID3_ROCK 0x0111 #define ROAR_META_GENRE_ID3_TECHNO 0x0112 #define ROAR_META_GENRE_ID3_INDUSTRIAL 0x0113 #define ROAR_META_GENRE_ID3_ALTERNATIVE 0x0114 #define ROAR_META_GENRE_ID3_SKA 0x0115 #define ROAR_META_GENRE_ID3_DEATH_METAL 0x0116 #define ROAR_META_GENRE_ID3_PRANKS 0x0117 #define ROAR_META_GENRE_ID3_SOUNDTRACK 0x0118 #define ROAR_META_GENRE_ID3_EURO_TECHNO 0x0119 #define ROAR_META_GENRE_ID3_AMBIENT 0x011a #define ROAR_META_GENRE_ID3_TRIP_HOP 0x011b #define ROAR_META_GENRE_ID3_VOCAL 0x011c #define ROAR_META_GENRE_ID3_JAZZ_FUNK 0x011d #define ROAR_META_GENRE_ID3_FUSION 0x011e #define ROAR_META_GENRE_ID3_TRANCE 0x011f #define ROAR_META_GENRE_ID3_CLASSICAL 0x0120 #define ROAR_META_GENRE_ID3_INSTRUMENTAL 0x0121 #define ROAR_META_GENRE_ID3_ACID 0x0122 #define ROAR_META_GENRE_ID3_HOUSE 0x0123 #define ROAR_META_GENRE_ID3_GAME 0x0124 #define ROAR_META_GENRE_ID3_SOUND_CLIP 0x0125 #define ROAR_META_GENRE_ID3_GOSPEL 0x0126 #define ROAR_META_GENRE_ID3_NOISE 0x0127 #define ROAR_META_GENRE_ID3_ALTERNROCK 0x0128 #define ROAR_META_GENRE_ID3_BASS 0x0129 #define ROAR_META_GENRE_ID3_SOUL 0x012a #define ROAR_META_GENRE_ID3_PUNK 0x012b #define ROAR_META_GENRE_ID3_SPACE 0x012c #define ROAR_META_GENRE_ID3_MEDITATIVE 0x012d #define ROAR_META_GENRE_ID3_INSTRUMENTAL_POP 0x012e #define ROAR_META_GENRE_ID3_INSTRUMENTAL_ROCK 0x012f #define ROAR_META_GENRE_ID3_ETHNIC 0x0130 #define ROAR_META_GENRE_ID3_GOTHIC 0x0131 #define ROAR_META_GENRE_ID3_DARKWAVE 0x0132 #define ROAR_META_GENRE_ID3_TECHNO_INDUSTRIAL 0x0133 #define ROAR_META_GENRE_ID3_ELECTRONIC 0x0134 #define ROAR_META_GENRE_ID3_POP_FOLK 0x0135 #define ROAR_META_GENRE_ID3_EURODANCE 0x0136 #define ROAR_META_GENRE_ID3_DREAM 0x0137 #define ROAR_META_GENRE_ID3_SOUTHERN_ROCK 0x0138 #define ROAR_META_GENRE_ID3_COMEDY 0x0139 #define ROAR_META_GENRE_ID3_CULT 0x013a #define ROAR_META_GENRE_ID3_GANGSTA 0x013b #define ROAR_META_GENRE_ID3_TOP_40 0x013c #define ROAR_META_GENRE_ID3_CHRISTIAN_RAP 0x013d #define ROAR_META_GENRE_ID3_POP_FUNK 0x013e #define ROAR_META_GENRE_ID3_JUNGLE 0x013f #define ROAR_META_GENRE_ID3_NATIVE_AMERICAN 0x0140 #define ROAR_META_GENRE_ID3_CABARET 0x0141 #define ROAR_META_GENRE_ID3_NEW_WAVE 0x0142 #define ROAR_META_GENRE_ID3_PSYCHADELIC 0x0143 #define ROAR_META_GENRE_ID3_RAVE 0x0144 #define ROAR_META_GENRE_ID3_SHOWTUNES 0x0145 #define ROAR_META_GENRE_ID3_TRAILER 0x0146 #define ROAR_META_GENRE_ID3_LO_FI 0x0147 #define ROAR_META_GENRE_ID3_TRIBAL 0x0148 #define ROAR_META_GENRE_ID3_ACID_PUNK 0x0149 #define ROAR_META_GENRE_ID3_ACID_JAZZ 0x014a #define ROAR_META_GENRE_ID3_POLKA 0x014b #define ROAR_META_GENRE_ID3_RETRO 0x014c #define ROAR_META_GENRE_ID3_MUSICAL 0x014d #define ROAR_META_GENRE_ID3_ROCK_AND_ROLL 0x014e #define ROAR_META_GENRE_ID3_HARD_ROCK 0x014f #endif //ll �����������������������������������������������roaraudio-1.0beta11/include/roaraudio/license.h�����������������������������������������������������0000644�0001750�0001750�00000003021�12264733524�017666� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//license.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_LICENSE_H_ #define _ROARAUDIO_LICENSE_H_ #define ROAR_LICENSE_UNDEF NULL #define ROAR_LICENSE_PUBLIC_DOMAIN "public domain" #define ROAR_LICENSE_PD ROAR_LICENSE_PUBLIC_DOMAIN #define ROAR_LICENSE_GPLv3_0 "GPL-3.0" #define ROAR_LICENSE_GPLv3_0_OL "GPL-3.0 (or later)" #define ROAR_LICENSE_LGPLv3_0 "LGPL-3.0" #define ROAR_LICENSE_LGPLv3_0_OL "LGPL-3.0 (or later)" #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/ltm.h���������������������������������������������������������0000644�0001750�0001750�00000004650�12264733524�017051� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ltm.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_LTM_H_ #define _ROARAUDIO_LTM_H_ // monitoring targets: /* Vars used below: * t = time * w = window size * l = history size * S(t) = signal at time t * H{g}(n) = history of type g element n */ #define ROAR_LTM_MT_NONE 0x0000 /* const for init of lists */ #define ROAR_LTM_MT_INACT 0x0001 /* input activit */ #define ROAR_LTM_MT_OUTACT 0x0002 /* output activity */ #define ROAR_LTM_MT_ACT 0x0004 /* any (in+out+other) activity */ #define ROAR_LTM_MT_AVG 0x0008 /* signal avg: SUM{t-w->t}(S(t))/w */ #define ROAR_LTM_MT_PEAK 0x0010 /* signal min and max values: MIN(S(t-w..t)), MAX(S(t-w..t)) */ #define ROAR_LTM_MT_RMS 0x0020 /* signal RMS^2: SUM{t-w->t}(S(t)^2) */ #define ROAR_LTM_MT_RMSPEAK 0x0040 /* signal RMS^2 min and max: MIN(H{RMS}(0..l)), MAX(H{RMS}(0..l)) */ #define ROAR_LTM_MT_HISTORY 0x0080 /* request to hold a history */ #define ROAR_LTM_MTBITS 16 /* number of bits for MTs */ // pre-defined windows: #define ROAR_LTM_WIN_WORKBLOCK 0 /* The last block which the server worked on */ /* This block does not have any sub-block historys (H()) */ // command sub-sub-types: #define ROAR_LTM_SST_NOOP 0 #define ROAR_LTM_SST_REGISTER 1 #define ROAR_LTM_SST_UNREGISTER 2 #define ROAR_LTM_SST_GET_RAW 3 #endif //ll ����������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/meta.h��������������������������������������������������������0000644�0001750�0001750�00000007475�12264733525�017214� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//meta.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_META_H_ #define _ROARAUDIO_META_H_ #define ROAR_META_TYPE_NONE 0 #define ROAR_META_TYPE_TITLE 1 #define ROAR_META_TYPE_ALBUM 2 #define ROAR_META_TYPE_AUTHOR 3 #define ROAR_META_TYPE_AUTOR ROAR_META_TYPE_AUTHOR #define ROAR_META_TYPE_ARTIST ROAR_META_TYPE_AUTHOR #define ROAR_META_TYPE_VERSION 4 #define ROAR_META_TYPE_DATE 5 #define ROAR_META_TYPE_LICENSE 6 #define ROAR_META_TYPE_TRACKNUMBER 7 #define ROAR_META_TYPE_ORGANIZATION 8 #define ROAR_META_TYPE_DESCRIPTION 9 #define ROAR_META_TYPE_GENRE 10 #define ROAR_META_TYPE_LOCATION 11 #define ROAR_META_TYPE_CONTACT 12 #define ROAR_META_TYPE_STREAMURL 13 #define ROAR_META_TYPE_HOMEPAGE 14 #define ROAR_META_TYPE_THUMBNAIL 15 #define ROAR_META_TYPE_LENGTH 16 #define ROAR_META_TYPE_COMMENT 17 #define ROAR_META_TYPE_OTHER 18 #define ROAR_META_TYPE_FILENAME 19 #define ROAR_META_TYPE_FILEURL 20 #define ROAR_META_TYPE_SERVER 21 #define ROAR_META_TYPE_DURATION 22 #define ROAR_META_TYPE_WWW ROAR_META_TYPE_HOMEPAGE #define ROAR_META_TYPE_WOAF 23 /* ID3: Official audio file webpage */ #define ROAR_META_TYPE_ENCODER 24 #define ROAR_META_TYPE_ENCODEDBY ROAR_META_TYPE_ENCODER #define ROAR_META_TYPE_YEAR 25 #define ROAR_META_TYPE_DISCID 26 #define ROAR_META_TYPE_RPG_TRACK_PEAK 27 #define ROAR_META_TYPE_RPG_TRACK_GAIN 28 #define ROAR_META_TYPE_RPG_ALBUM_PEAK 29 #define ROAR_META_TYPE_RPG_ALBUM_GAIN 30 #define ROAR_META_TYPE_HASH 31 #define ROAR_META_TYPE_SIGNALINFO 32 #define ROAR_META_TYPE_AUDIOINFO ROAR_META_TYPE_SIGNALINFO #define ROAR_META_TYPE_OFFSET 33 #define ROAR_META_TYPE_PERFORMER 34 #define ROAR_META_TYPE_COPYRIGHT 35 #define ROAR_META_TYPE_LIKENESS 36 #define ROAR_META_TYPE_COMPOSER 37 #define ROAR_META_TYPE_RIGHTS 38 #define ROAR_META_TYPE_ISRC 39 #define ROAR_META_TYPE_LANGUAGE 40 #define ROAR_META_TYPE_GTIN 41 #define ROAR_META_TYPE_ISBN ROAR_META_TYPE_GTIN #define ROAR_META_TYPE_EAN ROAR_META_TYPE_GTIN #define ROAR_META_TYPE_PUBLISHER 42 #define ROAR_META_TYPE_DISCNUMBER 43 #define ROAR_META_TYPE_SOURCEMEDIA 44 #define ROAR_META_TYPE_LABEL 45 #define ROAR_META_TYPE_LABELNO 46 #define ROAR_META_MODE_SET 0 #define ROAR_META_MODE_ADD 1 #define ROAR_META_MODE_DELETE 2 #define ROAR_META_MODE_CLEAR 3 #define ROAR_META_MODE_FINALIZE 4 #define ROAR_META_MAX_NAMELEN 32 #define ROAR_META_MAX_PER_STREAM 16 struct roar_meta { int type; char key[ROAR_META_MAX_NAMELEN]; char * value; }; #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/misc.h��������������������������������������������������������0000644�0001750�0001750�00000002755�12264733525�017215� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//misc.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_MISC_H_ #define _ROARAUDIO_MISC_H_ // light: #define ROAR_LIGHT_BITS 8 // complex: #define ROAR_COMPLEX_RATE 0 #define ROAR_COMPLEX_BITS 0 #define ROAR_COMPLEX_CHANNELS 0 #define ROAR_COMPLEX_CODEC ROAR_CODEC_RAUM // complex: #define ROAR_RDTCS_RATE 0 #define ROAR_RDTCS_BITS 0 #define ROAR_RDTCS_CHANNELS 0 #define ROAR_RDTCS_CODEC ROAR_CODEC_RDS #endif //ll �������������������roaraudio-1.0beta11/include/roaraudio/muconthacks.h�������������������������������������������������0000644�0001750�0001750�00000003734�12264733526�020600� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//muconthacks.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_MUCONTHACKS_H_ #define _ROARAUDIO_MUCONTHACKS_H_ #ifdef ROAR_TARGET_MICROCONTROLLER #define SHUT_RD 0 #define SHUT_WR 1 #define SHUT_RDWR 2 #define SOCK_STREAM 1 #define SOCK_DGRAM 2 #define SOCK_RAW 3 #define SOCK_RDM 4 #define SOCK_SEQPACKET 5 #define O_RDONLY 0x01 #define O_WRONLY 0x02 #define O_RDWR (O_RDONLY|O_WRONLY) #define O_NONBLOCK 0x04 #define O_CREAT 0x08 #define O_TRUNC 0x10 #define EAGAIN 11 #define ENOSYS 38 struct sockaddr { sa_family_t sa_family; }; int bind (int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); int connect (int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); char * strerror(int errnum); // some dummy funcs: #define getpid() 2 #define getuid() 0 #define getgid() 0 #define getenv(x) NULL #endif #endif //ll ������������������������������������roaraudio-1.0beta11/include/roaraudio/notify.h������������������������������������������������������0000644�0001750�0001750�00000021076�12264733526�017570� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//notify.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_NOTIFY_H_ #define _ROARAUDIO_NOTIFY_H_ #define ROAR_EVENT_NETFLAG_NONE 0x00000000 #define ROAR_EVENT_NETFLAG_DATA 0x00000001 #define ROAR_EVENT_NETFLAG_PROXYEVENT 0x00000002 #define ROAR_NOTIFY_SPECIAL (uint32_t)0xffffffff // protocol cmds: #define ROAR_NOTIFY_OFFSET_CMD (uint32_t)0x00000000 #define ROAR_NOTIFY_MASK_CMD (uint32_t)0x000000ff // event groups (AKA meta events): #define ROAR_NOTIFY_OFFSET_EGRP (uint32_t)0x00010000 #define ROAR_NOTIFY_MASK_EGRP (uint32_t)0x0000ffff // object event: #define ROAR_NOTIFY_OFFSET_OE (uint32_t)0x00020000 #define ROAR_NOTIFY_MASK_OE (uint32_t)0x0000ffff // data events: #define ROAR_NOTIFY_OFFSET_DATA (uint32_t)0x00030000 #define ROAR_NOTIFY_MASK_DATA (uint32_t)0x0000ffff // user defined events: #define ROAR_NOTIFY_OFFSET_USER (uint32_t)0x40000000 #define ROAR_NOTIFY_MASK_USER (uint32_t)0x3fffffff #define ROAR_NOTIFY_X2EVENT(x,offset,mask) ((x) == (uint32_t)-1 ? ROAR_NOTIFY_SPECIAL : (((x) & (mask))+(offset))) #define ROAR_NOTIFY_EVENT2X(x,offset,mask) (ROAR_NOTIFY_IS_X((x),(offset),(mask)) != 1 ? (uint32_t)-1 : ((x) - (offset))) #define ROAR_NOTIFY_IS_X(x,offset,mask) ((x) == ROAR_NOTIFY_SPECIAL ? -1 : (((x) | (mask)) - (mask)) == (offset) ? 1 : 0) #define ROAR_NOTIFY_CMD2EVENT(x) ROAR_NOTIFY_X2EVENT((x), ROAR_NOTIFY_OFFSET_CMD, ROAR_NOTIFY_MASK_CMD) #define ROAR_NOTIFY_EVENT2CMD(x) ROAR_NOTIFY_EVENT2X((x), ROAR_NOTIFY_OFFSET_CMD, ROAR_NOTIFY_MASK_CMD) #define ROAR_NOTIFY_IS_CMD(x) ROAR_NOTIFY_IS_X((x), ROAR_NOTIFY_OFFSET_CMD, ROAR_NOTIFY_MASK_CMD) #define ROAR_NOTIFY_EGRP2EVENT(x) ROAR_NOTIFY_X2EVENT((x), ROAR_NOTIFY_OFFSET_EGRP, ROAR_NOTIFY_MASK_EGRP) #define ROAR_NOTIFY_EVENT2EGRP(x) ROAR_NOTIFY_EVENT2X((x), ROAR_NOTIFY_OFFSET_EGRP, ROAR_NOTIFY_MASK_EGRP) #define ROAR_NOTIFY_IS_EGRP(x) ROAR_NOTIFY_IS_X((x), ROAR_NOTIFY_OFFSET_EGRP, ROAR_NOTIFY_MASK_EGRP) #define ROAR_NOTIFY_OE2EVENT(x) ROAR_NOTIFY_X2EVENT((x), ROAR_NOTIFY_OFFSET_OE, ROAR_NOTIFY_MASK_OE) #define ROAR_NOTIFY_EVENT2OE(x) ROAR_NOTIFY_EVENT2X((x), ROAR_NOTIFY_OFFSET_OE, ROAR_NOTIFY_MASK_OE) #define ROAR_NOTIFY_IS_OE(x) ROAR_NOTIFY_IS_X((x), ROAR_NOTIFY_OFFSET_OE, ROAR_NOTIFY_MASK_OE) #define ROAR_NOTIFY_DATA2EVENT(x) ROAR_NOTIFY_X2EVENT((x), ROAR_NOTIFY_OFFSET_DATA, ROAR_NOTIFY_MASK_DATA) #define ROAR_NOTIFY_EVENT2DATA(x) ROAR_NOTIFY_EVENT2X((x), ROAR_NOTIFY_OFFSET_DATA, ROAR_NOTIFY_MASK_DATA) #define ROAR_NOTIFY_IS_DATA(x) ROAR_NOTIFY_IS_X((x), ROAR_NOTIFY_OFFSET_DATA, ROAR_NOTIFY_MASK_DATA) #define ROAR_NOTIFY_USER2EVENT(x) ROAR_NOTIFY_X2EVENT((x), ROAR_NOTIFY_OFFSET_USER, ROAR_NOTIFY_MASK_USER) #define ROAR_NOTIFY_EVENT2USER(x) ROAR_NOTIFY_EVENT2X((x), ROAR_NOTIFY_OFFSET_USER, ROAR_NOTIFY_MASK_USER) #define ROAR_NOTIFY_IS_USER(x) ROAR_NOTIFY_IS_X((x), ROAR_NOTIFY_OFFSET_USER, ROAR_NOTIFY_MASK_USER) // EGRP: #define ROAR_NOTIFY_EGRP_GROUP_BASICS 0x0000 #define ROAR_NOTIFY_EGRP_GROUP_CLIENTS (ROAR_OT_CLIENT << 8) #define ROAR_NOTIFY_EGRP_GROUP_STREAMS (ROAR_OT_STREAM << 8) #define ROAR_NOTIFY_EGRP_GROUP_SOURCES (ROAR_OT_SOURCE << 8) #define ROAR_NOTIFY_EGRP_GROUP_SAMPLES (ROAR_OT_SAMPLE << 8) #define ROAR_EGRP_ANY_EVENT ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_BASICS + 0) #define ROAR_EGRP_OBJECT_NEW ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_BASICS + 1) #define ROAR_EGRP_OBJECT_DELETE ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_BASICS + 2) #define ROAR_EGRP_OBJECT_REF ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_BASICS + 3) #define ROAR_EGRP_OBJECT_UNREF ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_BASICS + 4) #define ROAR_EGRP_ERROR ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_BASICS + 5) #define ROAR_EGRP_ANY_CLIENT_EVENT ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_CLIENTS + 0) #define ROAR_EGRP_ANY_STREAM_EVENT ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_STREAMS + 0) #define ROAR_EGRP_ANY_SOURCE_EVENT ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_SOURCES + 0) #define ROAR_EGRP_ANY_SAMPLE_EVENT ROAR_NOTIFY_EGRP2EVENT(ROAR_NOTIFY_EGRP_GROUP_SAMPLES + 0) // OE: #define ROAR_NOTIFY_OE_GROUP_BASICS 0x0000 #define ROAR_NOTIFY_OE_GROUP_CLIENTS (ROAR_OT_CLIENT << 8) #define ROAR_NOTIFY_OE_GROUP_STREAMS (ROAR_OT_STREAM << 8) #define ROAR_NOTIFY_OE_GROUP_SOURCES (ROAR_OT_SOURCE << 8) #define ROAR_NOTIFY_OE_GROUP_SAMPLES (ROAR_OT_SAMPLE << 8) #define ROAR_OE_BASICS_CHANGE_STATE ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_BASICS + 0) #define ROAR_OE_BASICS_CHANGE_FLAGS ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_BASICS + 5) #define ROAR_OE_BASICS_NEW ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_BASICS + 6) #define ROAR_OE_BASICS_DELETE ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_BASICS + 7) #define ROAR_OE_CLIENT_CONNECT ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_CLIENTS + 0) #define ROAR_OE_CLIENT_DISCONNECT ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_CLIENTS + 1) #define ROAR_OE_CLIENT_MSG ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_CLIENTS + 3) //#define ROAR_OE_STREAM_CHANGE_STATE ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 0) #define ROAR_OE_STREAM_EXEC ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 1) #define ROAR_OE_STREAM_EOF ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 2) #define ROAR_OE_STREAM_CON_STREAM ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 3) #define ROAR_OE_STREAM_PASSFH ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 4) //#define ROAR_OE_STREAM_CHANGE_FLAGS ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 5) #define ROAR_OE_STREAM_CHANGE_VOLUME ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 6) #define ROAR_OE_STREAM_XRUN ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 7) #define ROAR_OE_STREAM_META_UPDATE ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 8) #define ROAR_XRUN_NONE 0 #define ROAR_XRUN_UNDER_PRE 1 #define ROAR_XRUN_UNDER_POST 2 #define ROAR_XRUN_OVER_PRE 3 #define ROAR_XRUN_OVER_POST 4 // Data: #define ROAR_DATA_EVENT2DIR(ev) (((ev) & 0xFF00) >> 8) #define ROAR_DATA_EVENT2EVENT(ev) (((ev) & 0x00FF)) #define ROAR_DATA_GROUP(dir) ((dir) << 8) #define ROAR_DATA_GROUP_WAVEFORM ROAR_DATA_GROUP(ROAR_DIR_PLAY) #define ROAR_DATA_GROUP_MIDI ROAR_DATA_GROUP(ROAR_DIR_MIDI_IN) #define ROAR_DATA_GROUP_LIGHT ROAR_DATA_GROUP(ROAR_DIR_LIGHT_IN) #define ROAR_DATA_GROUP_RAW ROAR_DATA_GROUP(ROAR_DIR_RAW_IN) #define ROAR_DATA_GROUP_COMPLEX ROAR_DATA_GROUP(ROAR_DIR_COMPLEX_IN) #define ROAR_DATA_GROUP_RDTCS ROAR_DATA_GROUP(ROAR_DIR_RDTCS_IN) #define ROAR_DATA_DMX512_GROUP_CHANNEL (ROAR_DATA_GROUP_LIGHT + 0x00) #define ROAR_DATA_DMX512_GROUP_EVENT (ROAR_DATA_GROUP_LIGHT + 0x10) // should we really send channel updates? Latency? ...? // Emmiter: client ID, target: mixer or other stream, target_type: STREAM, // arg0: channel, arg1: new value // *: -1/NULL #define ROAR_DATA_DMX512_CHANNEL_UPDATE ROAR_NOTIFY_DATA2EVENT(ROAR_DATA_DMX512_GROUP_CHANNEL + 1) // Emmiter: client ID, target: mixer or other stream, target_type: STREAM, // arg0: event type (ROAR_ROARDMX_EVENT_*) // *: -1/NULL #define ROAR_DATA_DMX512_EVENT ROAR_NOTIFY_DATA2EVENT(ROAR_DATA_DMX512_GROUP_EVENT + 1) #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/proto.h�������������������������������������������������������0000644�0001750�0001750�00000023170�12264733527�017421� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//proto.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_PORTO_H_ #define _ROARAUDIO_PORTO_H_ #define ROAR_CMD_EOL -1 /* end of list */ #define ROAR_CMD_NOOP 0 /* do nothing */ #define ROAR_CMD_IDENTIFY 1 /* after connect we have to identify ourself */ #define ROAR_CMD_AUTH 2 /* send an auth cookie */ #define ROAR_CMD_NEW_STREAM 3 /* request a new stream id */ #define ROAR_CMD_SET_META 4 /* update meta data of streamed data */ #define ROAR_CMD_EXEC_STREAM 5 /* close all data channels and make the controll socket a raw data socket */ #define ROAR_CMD_QUIT 6 /* quits the connection */ #define ROAR_CMD_GET_STANDBY 7 #define ROAR_CMD_SET_STANDBY 8 #define ROAR_CMD_SERVER_INFO 9 /* Server version ... */ #define ROAR_CMD_SERVER_STATS 10 /* Server stats: number of clients, streams,.. */ #define ROAR_CMD_SERVER_OINFO 11 /* Output info, roar_audio_info sa */ #define ROAR_CMD_ADD_DATA 12 /* add some data to the input buffer */ //#define ROAR_CMD_ #define ROAR_CMD_EXIT 13 /* make the server quit */ #define ROAR_CMD_LIST_STREAMS 14 /* list all streams (not only playback streams like esd does) */ #define ROAR_CMD_LIST_CLIENTS 15 /* list all clients */ #define ROAR_CMD_GET_CLIENT 16 /* get infos about a client */ #define ROAR_CMD_GET_STREAM 17 /* get infos about a stream */ #define ROAR_CMD_KICK 18 /* kick a client, stream, sample or source */ #define ROAR_CMD_SET_VOL 19 /* change volume */ #define ROAR_CMD_GET_VOL 20 /* get volume */ #define ROAR_CMD_CON_STREAM 21 /* let the server connect to something to get data for a new stream */ #define ROAR_CMD_GET_META 22 /* get meta data of streamed data */ #define ROAR_CMD_LIST_META 23 /* get list of meta data of streamed data */ #define ROAR_CMD_BEEP 24 /* send an beep */ #define ROAR_AUTHCTL 25 #define ROAR_ACLCTL 26 #define ROAR_CMD_GET_STREAM_PARA 27 /* Get addition stream parameters like blocksizes */ #define ROAR_CMD_SET_STREAM_PARA 28 /* set special stream parameter */ #define ROAR_CMD_ATTACH 29 /* attach a OUTPUT or source */ #define ROAR_CMD_DETACH ROAR_CMD_KICK /* just to have an alias */ #define ROAR_CMD_PASSFH 30 /* send an fh via UNIX Domain Socket to the roard */ #define ROAR_CMD_GETTIMEOFDAY 31 /* get time of day from server */ #define ROAR_CMD_WHOAMI 32 /* returns the ID of the current client */ #define ROAR_CMD_DEVCTL 33 /* send control messages to devices */ #define ROAR_CMD_CAPS 34 /* send caps */ #define ROAR_CMD_WAIT 35 /* wait for an event */ #define ROAR_CMD_NOTIFY 36 /* asyncronus notify of events */ #define ROAR_CMD_SEEK 37 /* seek in stream */ #define ROAR_CMD_CLIENTCTL 38 /* like stream ctl, just for client connections */ #define ROAR_CMD_LOOKUP 39 /* lookup??? */ #define ROAR_CMD_CONCTL 40 /* change parameter for current connection */ #define ROAR_CMD_SHIFT_DATA 41 /* get some data from the stream */ // Reserved for RAUM project: #define ROAR_CMD_RAUM_SEEKTABLE 201 /* contains a seektable */ #define ROAR_CMD_RAUM_PICTURE 202 /* contains a picture block */ #define ROAR_CMD_RAUM_SYNC 203 /* used for raw-seeking, contains a magic pattern */ // End of reserved block #define ROAR_CMD_EPERM 252 /* error: permition denided */ #define ROAR_CMD_OK_STOP 253 /* used internaly in the serveer: */ // ROAR_CMD_OK but do not queue the client again within the block #define ROAR_CMD_OK 254 /* return value OK */ #define ROAR_CMD_ERROR 255 /* return value ERROR */ #define ROAR_STANDBY_ACTIVE 1 #define ROAR_STANDBY_INACTIVE 0 // object types... #define ROAR_OT_CLIENT 1 #define ROAR_OT_STREAM 2 #define ROAR_OT_SOURCE 3 #define ROAR_OT_SAMPLE 4 #define ROAR_OT_OUTPUT 5 #define ROAR_OT_MIXER 6 #define ROAR_OT_BRIDGE 7 #define ROAR_OT_LISTEN 8 #define ROAR_OT_ACTION 9 #define ROAR_OT_MSGQUEUE 10 #define ROAR_OT_MSGBUS 11 // filter: #define ROAR_CTL_FILTER_ANY 0 #define ROAR_CTL_FILTER_DIR 1 #define ROAR_CTL_CMP_ANY ROAR_CTL_FILTER_ANY #define ROAR_CTL_CMP_EQ 1 #define ROAR_CTL_CMP_NE 2 // auth types... #define ROAR_AUTH_T_AUTO -1 #define ROAR_AUTH_T_NONE 0 /* do not auth */ #define ROAR_AUTH_T_COOKIE 1 /* use cookie */ #define ROAR_AUTH_T_TRUST 2 /* trust: used for UNIX Domain sockets, */ /* same uid = trusted, diffrent uid = public */ #define ROAR_AUTH_T_PASSWORD 3 /* use password */ #define ROAR_AUTH_T_SYSUSER 4 /* use local/NIS/PAM userdatabase */ #define ROAR_AUTH_T_OPENPGP_SIGN 5 #define ROAR_AUTH_T_OPENPGP_ENCRYPT 6 #define ROAR_AUTH_T_OPENPGP_AUTH 7 #define ROAR_AUTH_T_KERBEROS 8 #define ROAR_AUTH_T_RHOST 9 #define ROAR_AUTH_T_XAUTH 10 #define ROAR_AUTH_T_IDENT 11 // attach types... #define ROAR_ATTACH_SIMPLE 1 /* move a stream from one to another client (attach the stream to it) */ #define ROAR_ATTACH_SOURCE 2 /* attach a new source to the server */ #define ROAR_ATTACH_OUTPUT 3 /* attach a new output stream to the server */ #define ROAR_ATTACH_MIXER 4 /* attach a new hwmixer stream to the server */ #define ROAR_ATTACH_BRIDGE 5 /* attach a new bridge stream to the server */ // modes for ROAR_CMD_?ET_STREAM_PARA... #define ROAR_STREAM_PARA_INFO 1 #define ROAR_STREAM_PARA_FLAGS 2 #define ROAR_STREAM_PARA_NAME 3 #define ROAR_STREAM_PARA_CHANMAP 4 #define ROAR_STREAM_PARA_ROLE 5 #define ROAR_STREAM_PARA_HASHTABLE 6 #define ROAR_STREAM_PARA_WININFO 7 #define ROAR_STREAM_PARA_PROPTABLE 8 #define ROAR_STREAM_PARA_LTM 9 #define ROAR_STREAM_PARA_USAGE 10 /* used by RAUM */ #define ROAR_STREAM_PARA_RADIO 11 /* used by RDTCS */ #define ROAR_STREAM_PARA_RPG 12 // modes for ROAR_STREAM_PARA_RPG: #define ROAR_RPGMODE_DEFAULT -1 #define ROAR_RPGMODE_NONE 0 #define ROAR_RPGMODE_USER 1 #define ROAR_RPGMODE_ALBUM 2 #define ROAR_RPGMODE_TRACK 3 #define ROAR_RPGMODE_ALBUMTRACK 4 #define ROAR_RPGMODE_TRACKALBUM 5 // Message flags: #define ROAR_MF_NONE 0x00000000 /* No flags set | Versions: *ALL* */ #define ROAR_MF_SID 0x00000001 /* Stream ID | Versions: 1 */ #define ROAR_MF_SPOS 0x00000002 /* Stream Possition | Versions: 1 */ #define ROAR_MF_DL 0x00000004 /* Data Length | Versions: 1 */ #define ROAR_MF_LSID 0x00000008 /* Long Stream ID | Versions: 1 */ #define ROAR_MF_LSPOS 0x00000010 /* Long Stream Possition | Versions: 1,2 */ #define ROAR_MF_LDL 0x00000020 /* Long Data Length | Versions: 1 */ #define ROAR_MF_ED 0x00000040 /* Error Detection | Versions: 1,2 */ #define ROAR_MF_MF 0x00000080 /* Meta Framing | Versions: 1 */ #define ROAR_MF_UNIID 0x00000100 /* Stream ID is Universal ID | Versions: 2 */ #define ROAR_MF_ANNOUNCE 0x00000200 /* This is an announcement | Versions: 2 */ #define ROAR_MF_CLOUD 0x00000400 /* To cloud | Versions: 2 */ // Types for SERVER_INFO: #define ROAR_IT_SERVER 1 #define ROAR_IT_COUNTERS 2 //#define ROAR_IT_LISTEN 3 // Types for ROAR_IT_SERVER (Information Type Server Type = ITST) #define ROAR_ITST_VERSION 0 #define ROAR_ITST_LOCATION 1 #define ROAR_ITST_DESCRIPTION 2 #define ROAR_ITST_CONTACT 3 #define ROAR_ITST_UN_SYSNAME 4 #define ROAR_ITST_UN_NODENAME 5 #define ROAR_ITST_UN_RELEASE 6 #define ROAR_ITST_UN_MACHINE 7 #define ROAR_ITST_SERIAL 8 #define ROAR_ITST_ADDRESS 9 #define ROAR_ITST_UIURL 10 #define ROAR_ITST_HOSTID 11 #define ROAR_ITST_LICENSE 12 #define ROAR_ITST_BUILD 13 // IDs for diffrent clocks: #define ROAR_CLOCK_DEFAULT -2 #define ROAR_CLOCK_UNKNOWN -1 #define ROAR_CLOCK_REALTIME 1 #define ROAR_CLOCK_MONOTONIC 2 #define ROAR_CLOCK_UPTIME 3 // old: do not use. struct roar_timeofday { int64_t t_sec; // secund part of system time uint64_t t_nsec; // nano-secund part of system time // we use a int64 here so all types are int64... uint64_t c_nhz; // system hi res timer freq in nHz uint64_t d_nsps; // clock drift in nano secs per sec }; #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/proto_gopher.h������������������������������������������������0000644�0001750�0001750�00000005326�12264733527�020770� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//proto_gopher.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_PROTO_GOPHER_H_ #define _ROARAUDIO_PROTO_GOPHER_H_ #define ROAR_GOPHER_FLAGS_NONE 0x0000 #define ROAR_GOPHER_FLAGS_PLUS 0x0001 // offical: #define ROAR_GOPHER_TYPE_FILE '0' #define ROAR_GOPHER_TYPE_DIR '1' #define ROAR_GOPHER_TYPE_CSO_PB '2' /* Item is a CSO phone-book server */ #define ROAR_GOPHER_TYPE_ERROR '3' #define ROAR_GOPHER_TYPE_BINHEXED '4' /* Item is a BinHexed Macintosh file. */ #define ROAR_GOPHER_TYPE_DOSBIN '5' /* Item is DOS binary archive of some sort. */ #define ROAR_GOPHER_TYPE_UUENCODED '6' /* Item is a UNIX uuencoded file. */ #define ROAR_GOPHER_TYPE_SEARCH '7' /* Item is an Index-Search server. */ #define ROAR_GOPHER_TYPE_TELNET '8' #define ROAR_GOPHER_TYPE_BIN '9' /* Item is a binary file! */ #define ROAR_GOPHER_TYPE_REDUNDANT '+' /* Item is a redundant server */ #define ROAR_GOPHER_TYPE_TN3270 'T' /* Item points to a text-based tn3270 session. */ #define ROAR_GOPHER_TYPE_GIF 'g' /* Item is a GIF format graphics file. */ #define ROAR_GOPHER_TYPE_IMAGE 'I' /* Item is some kind of image file. Client decides how to display. */ #define ROAR_GOPHER_TYPE_INFO 'i' /* text in menus */ // inoffical: #define ROAR_GOPHER_TYPE_SOUND 's' #define ROAR_GOPHER_TYPE_MOVIE ';' #define ROAR_GOPHER_TYPE_MIME 'M' #define ROAR_GOPHER_TYPE_HTML 'h' struct roar_gopher_menu_item { int flags; char type; const char * name; const char * selector; const char * host; unsigned int port; }; struct roar_gopher_menu { int flags; struct roar_gopher_menu_item * items; size_t items_len; }; #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/sample.h������������������������������������������������������0000644�0001750�0001750�00000002512�12264733527�017534� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//sample.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_SAMPLE_H_ #define _ROARAUDIO_SAMPLE_H_ // we do not need any roar_audio_info struct because it IS in servers native format struct roar_sample { char name[ROAR_BUFFER_NAME]; struct roar_buffer * data; }; #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/socket.h������������������������������������������������������0000644�0001750�0001750�00000004135�12264733530�017540� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//socket.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_SOCKET_H_ #define _ROARAUDIO_SOCKET_H_ #define ROAR_SOCKET_TYPE_NONE 0 #define ROAR_SOCKET_TYPE_UNKNOWN ROAR_SOCKET_TYPE_NONE #define ROAR_SOCKET_TYPE_INET 1 #define ROAR_SOCKET_TYPE_TCP ROAR_SOCKET_TYPE_INET #define ROAR_SOCKET_TYPE_UNIX 2 #define ROAR_SOCKET_TYPE_FORK 3 #define ROAR_SOCKET_TYPE_PIPE ROAR_SOCKET_TYPE_FORK #define ROAR_SOCKET_TYPE_FILE 4 #define ROAR_SOCKET_TYPE_UDP 5 #define ROAR_SOCKET_TYPE_GENSTR 6 /* generic stream: TCP or UNIX */ #define ROAR_SOCKET_TYPE_DECNET 7 /* DECnet */ #define ROAR_SOCKET_TYPE_TCP6 8 #define ROAR_SOCKET_TYPE_UDP6 9 #define ROAR_SOCKET_TYPE_INET6 ROAR_SOCKET_TYPE_TCP6 #define ROAR_SOCKET_TYPE_IPXSPX 10 #define ROAR_SOCKET_TYPE_IPX 11 #define ROAR_SOCKET_TYPE_LAT_SERVICE 12 #define ROAR_SOCKET_TYPE_LAT_REVERSE_PORT 13 #define ROAR_SOCKET_TYPE_MAX 13 #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/stream.h������������������������������������������������������0000644�0001750�0001750�00000011146�12264733530�017543� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stream.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_STREAM_H_ #define _ROARAUDIO_STREAM_H_ #define ROAR_DIR_DEFAULT ROAR_DIR_PLAY #define ROAR_DIR_PLAY 1 #define ROAR_DIR_RECORD 2 #define ROAR_DIR_MONITOR 3 #define ROAR_DIR_FILTER 4 #define ROAR_DIR_OUTPUT 5 #define ROAR_DIR_MIXING 6 //#define ROAR_DIR_INTERNAL 7 #define ROAR_DIR_META 8 #define ROAR_DIR_BIDIR 9 #define ROAR_DIR_THRU 10 #define ROAR_DIR_BRIDGE 11 // MIDI: #define ROAR_DIR_MIDI_IN 12 #define ROAR_DIR_MIDI_OUT 13 // Light Control: #define ROAR_DIR_LIGHT_IN 14 #define ROAR_DIR_LIGHT_OUT 15 // Raw Data: #define ROAR_DIR_RAW_IN 16 #define ROAR_DIR_RAW_OUT 17 // Complex (multi-content container): #define ROAR_DIR_COMPLEX_IN 18 #define ROAR_DIR_COMPLEX_OUT 19 // Radio Data and Transmitter Control System: #define ROAR_DIR_RDTCS_IN 20 #define ROAR_DIR_RDTCS_OUT 21 // RECORD+PLAY: #define ROAR_DIR_RECPLAY 22 // Max DIR +1: #define ROAR_DIR_DIRIDS 23 // Stream flags: #define ROAR_FLAG_NONE 0x0000 #define ROAR_FLAG_PRIMARY 0x0001 #define ROAR_FLAG_OUTPUT 0x0002 #define ROAR_FLAG_DRIVER ROAR_FLAG_OUTPUT #define ROAR_FLAG_SOURCE 0x0004 #define ROAR_FLAG_SYNC 0x0008 #define ROAR_FLAG_META 0x0010 #define ROAR_FLAG_AUTOCONF 0x0020 #define ROAR_FLAG_CLEANMETA 0x0040 #define ROAR_FLAG_HWMIXER 0x0080 #define ROAR_FLAG_PAUSE 0x0100 #define ROAR_FLAG_MUTE 0x0200 #define ROAR_FLAG_MMAP 0x0400 #define ROAR_FLAG_ANTIECHO 0x0800 #define ROAR_FLAG_VIRTUAL 0x1000 #define ROAR_FLAG_RECSOURCE 0x2000 #define ROAR_FLAG_PASSMIXER 0x4000 #define ROAR_FLAG_PRETHRU 0x8000 // next are the exteded flags (> 16 bits) //#define ROAR_FLAG_SYNC 0x08 #define ROAR_FLAG_IMMUTABLE 0x00010000 #define ROAR_FLAG_ENHANCE 0x00020000 #define ROAR_FLAG_SINGLESINK 0x00040000 #define ROAR_SET_FLAG 0 #define ROAR_RESET_FLAG 1 #define ROAR_TOGGLE_FLAG 2 #define ROAR_NOOP_FLAG 3 #define ROAR_PROTECT_FLAG 0x8000 #define ROAR_SET_FLAG_PROTECT (ROAR_SET_FLAG|ROAR_PROTECT_FLAG) #define ROAR_RESET_FLAG_PROTECT (ROAR_RESET_FLAG|ROAR_PROTECT_FLAG) // Stream states: #define ROAR_STREAMSTATE_UNKNOWN -1 #define ROAR_STREAMSTATE_NULL 0 #define ROAR_STREAMSTATE_UNUSED ROAR_STREAMSTATE_NULL #define ROAR_STREAMSTATE_INITING 1 #define ROAR_STREAMSTATE_NEW 2 #define ROAR_STREAMSTATE_OLD 3 #define ROAR_STREAMSTATE_CLOSING 4 // Stream roles: // PA currently defines: video, music, game, event, phone, animation, production, a11y // RA includes : YES YES YES YES YES NO NO NO #define ROAR_ROLE_UNKNOWN -1 #define ROAR_ROLE_NONE 0 #define ROAR_ROLE_MUSIC 1 #define ROAR_ROLE_VIDEO 2 #define ROAR_ROLE_GAME 3 #define ROAR_ROLE_EVENT 4 #define ROAR_ROLE_BEEP 5 #define ROAR_ROLE_PHONE 6 #define ROAR_ROLE_BACKGROUND_MUSIC 7 #define ROAR_ROLE_VOICE 8 #define ROAR_ROLE_INSTRUMENT 9 #define ROAR_ROLE_RHYTHM 10 #define ROAR_ROLE_CLICK 11 #define ROAR_ROLE_MIXED 12 #define ROAR_CARE_NOPOS 0 #define ROAR_CARE_POS 1 #define ROAR_STREAM(a) ((struct roar_stream*)(a)) #define ROAR_STREAMS_MAX 64 struct roar_stream { int id; int fh; int dir; int care_pos; uint32_t pos; uint32_t pos_rel_id; // TODO: why is this not int? struct roar_audio_info info; }; #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/targethacks.h�������������������������������������������������0000644�0001750�0001750�00000004054�12264733531�020551� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//targethacks.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_TARGETHACKS_H_ #define _ROARAUDIO_TARGETHACKS_H_ #ifndef ROAR_HAVE_T_ID_T #define id_t int #endif #ifndef ROAR_HAVE_T_PID_T #define pid_t int #endif #ifndef ROAR_HAVE_T_UID_T #define uid_t int #endif #ifndef ROAR_HAVE_T_GID_T #define gid_t int #endif #ifndef ROAR_HAVE_T_SOCKLEN_T #define socklen_t int #endif #ifndef ROAR_HAVE_T_MODE_T #define mode_t unsigned int #endif #ifndef ROAR_HAVE_T_OFF_T #define off_t int #endif /* #define size_t unsigned int */ #ifndef ROAR_HAVE_T_SSIZE_T #define ssize_t signed int #endif #ifndef ROAR_HAVE_T_TIME_T #define time_t int64_t #endif #ifndef ROAR_HAVE_T_SA_FAMILY_T #define sa_family_t char #endif #ifndef ROAR_HAVE_CONST_M_PI_2 #define M_PI_2 1.57079632679 /* pi/2 */ #endif // funny printf() hacks: #ifdef ROAR_TARGET_WIN32 #define LIBROAR__longlong long #define LIBROAR__ll "l" #else #define LIBROAR__longlong long long #define LIBROAR__ll "ll" #endif #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/typedefs.h����������������������������������������������������0000644�0001750�0001750�00000004711�12264733531�020074� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//typedefs.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _ROARAUDIO_TYPEDEFS_H_ #define _ROARAUDIO_TYPEDEFS_H_ #include <roaraudio.h> // IO: typedef struct roar_vio_calls VIO; // Network: typedef struct roar_nnode NNode; // Buffers, Ram, GP-Structs: typedef struct roar_keyval KeyVal; typedef struct roar_buffer * RoarBuffer; typedef void * RoarMem; // for use with roar_mm_*() // Audio: typedef struct roar_audio_info AudioInfo; typedef struct roar_mixer_settings RoarMixer; // Meta Data: typedef struct roar_meta RoarMeta; // Protocol: typedef struct roar_connection RoarConnection; typedef struct roar_message RoarMsg; typedef struct roar_beep RoarBeep; // Objects: typedef struct roar_client RoarClient; typedef struct roar_stream RoarStream; // RoarDL: typedef struct roar_dl_lhandle LHandle; // ID types: typedef int RoarSID; typedef int RoarCID; // Protocol: typedef int RoarCMD; #endif //ll �������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/units.h�������������������������������������������������������0000644�0001750�0001750�00000006044�12264733531�017414� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//units.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_UNITS_H_ #define _ROARAUDIO_UNITS_H_ /* suffix: */ #define _MICRO (1/1000000) #define _MILI (1/1000) #define _ONE 1 #define _KILO 1000 #define _MEGA ((int_least32_t)_KILO*(int_least32_t)_KILO) #define _GIGA ((int_least32_t)_KILO*_MEGA) #define _TERA ((int_least32_t)_KILO*_GIGA) /* Time: */ #ifndef _SEC #if defined(_UNITS_T_BASE_MSEC) #define _SEC_TYPE int_least32_t #define _SEC (_SEC_TYPE)1000 #elif defined(_UNITS_T_BASE_USEC) #define _SEC_TYPE int_least32_t #define _SEC (_SEC_TYPE)1000000 //#elif defined(_UNITS_T_BASE_SEC) #else #define _SEC 1 #define _SEC_TYPE int #endif #endif #ifndef _SEC_TYPE #define _SEC_TYPE int_least32_t #endif #define _MIN ((_SEC_TYPE)60*_SEC) #define _HOUR ((_SEC_TYPE)60*_MIN) #define _MSEC (_SEC*_MILI) #define _USEC (_SEC*_MICRO) /* distance */ #ifndef _METER #if defined(_UNITS_D_BASE_MMETER) #define _METER_TYPE int #define _METER 1000 #elif defined(_UNITS_D_BASE_UMETER) #define _METER_TYPE int_least32_t #define _METER (_METER_TYPE)1000000 //#elif defined(_UNITS_D_BASE_METER) #else #define _METER_TYPE int #define _METER 1 #endif #endif #ifndef _METER_TYPE #define _METER_TYPE int_least32_t #endif #define _AE ((int_least64_t)149597870691LL *_METER) #define _LJ (9460730472580800LL *_METER) #define _PC (30856804413117847LL*_METER) /* TODO: FIXME: get a more corret value */ /* speed */ #define _MPS ((double)_METER/_SEC) #define _KMPH (_KILO*_METER/_HOUR) #define _SPEED_OF_SOUND_AIR (343. *_MPS) #define _SPEED_OF_SOUND_WATER (1407.*_MPS) #define _SPEED_OF_SOUND _SPEED_OF_SOUND_AIR #define _SPEED_OF_LIGHT_VACUUM (299792458LL*_MPS) #define _SPEED_OF_LIGHT _SPEED_OF_LIGHT_VACUUM /* Bits -> Bytes: */ #define _BIT2BYTE(x) (((int)((x)/8)) + ((x) % 8 ? 1 : 0)) #define _BYTE2BIT(x) ((x)*8) #define _8BIT _BIT2BYTE(8) #define _16BIT _BIT2BYTE(16) #define _24BIT _BIT2BYTE(24) #define _32BIT _BIT2BYTE(32) #define _64BIT _BIT2BYTE(64) #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/vendors.h�����������������������������������������������������0000644�0001750�0001750�00000002662�12264733532�017735� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vendors.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_VENDORS_H_ #define _ROARAUDIO_VENDORS_H_ #define ROAR_VID_ROARAUDIO 0 #define ROAR_VNAME_ROARAUDIO "RoarAudio" #define ROAR_VSTR_ROARAUDIO "<0/" ROAR_VNAME_ROARAUDIO ">" #define ROAR_VID_BASICDEV 1 #define ROAR_VNAME_BASICDEV "BasicDevice" #define ROAR_VSTR_BASICDEV "<1/" ROAR_VNAME_BASICDEV ">" #endif //ll ������������������������������������������������������������������������������roaraudio-1.0beta11/include/roaraudio/win32hacks.h��������������������������������������������������0000644�0001750�0001750�00000003514�12264733532�020226� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//win32hacks.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: Even though this file is LGPLed it (may) include GPLed files * so the license of this file is/may therefore downgraded to GPL. * See HACKING for details. */ #ifndef _ROARAUDIO_WIN32HACKS_H_ #define _ROARAUDIO_WIN32HACKS_H_ #ifdef ROAR_TARGET_WIN32 #include <windows.h> #define SHUT_RD SD_RECEIVE #define SHUT_WR SD_SEND #define SHUT_RDWR SD_BOTH #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #endif #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 #endif #ifndef PDP_ENDIAN #define PDP_ENDIAN 3412 #endif #ifndef BYTE_ORDER #define BYTE_ORDER LITTLE_ENDIAN #endif #if !defined(ROAR_HAVE_BSDSOCKETS) && !defined(ROAR_HAVE_IPV4) #define ROAR_HAVE_IPV4 #endif #define ROAR_NETWORK_READ(x,y,z) recv((x), (y), (z), 0) #define ROAR_NETWORK_WRITE(x,y,z) send((x), (y), (z), 0) #else #define ROAR_NETWORK_READ(x,y,z) read((x), (y), (z)) #define ROAR_NETWORK_WRITE(x,y,z) write((x), (y), (z)) #endif #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/lib/����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�013236� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�014122� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/Makefile����������������������������������������������������������������0000644�0001750�0001750�00000003113�12072565214�015553� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroar SLIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) VIO_META=vio.o vio_select.o vio_ops.o vio_string.o VIO_BRIDGE=vio_bio.o vio_stdio.o VIO=$(VIO_META) $(VIO_BRIDGE) vio_cmd.o vio_magic.o vio_pipe.o vio_socket.o vio_winsock.o vio_stack.o vio_jumbo.o vio_proto.o vio_dstr.o vio_tantalos.o vio_rtp.o vio_buffer.o vio_buffer_store.o vio_stdvios.o vio_misc.o vio_zlib.o vio_stream.o vio_proxy.o HASHES=hash.o hash_tiger.o hash_sha1.o PASSWORD=passwordapi.o pinentry.o sshaskpass.o CRYPTO=crypto.o random.o $(HASHES) crc.o OBJS=libroar.o config.o debug.o error.o basic.o stream.o client.o simple.o auth.o socket.o ctl.o buffer.o meta.o file.o acl.o cdrom.o $(PASSWORD) $(VIO) stack.o slp.o nnode.o roardl.o plugincontainer.o roarx11.o beep.o proto.o env.o keyval.o vs.o ltm.o notify.o notify_proxy.o asyncctl.o enumdev.o serverinfo.o $(CRYPTO) authfile.o caps.o roarfloat.o base64.o trap.o memmgr.o time.o kstore.o uuid.o watchdog.o scheduler.o #DEFINES = -DDEBUG #DEFINES+= -D_LIBROAR_NOATTR_WARNINGS INCLUDE = -I../include -I../include/libroar CFLAGS += $(DEBUG_g) $(Wall) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) $(LDPATH) LIBS = $(LIBROAR_NS) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(LIBROAR_V) -o $(SLIB) ${OBJS} ${LIBS} $(ALIB): ${OBJS} ${AR} cru $(ALIB) ${OBJS} ${RANLIB} $(ALIB) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/acl.c�������������������������������������������������������������������0000644�0001750�0001750�00000003300�12264733532�015017� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//acl.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_acl_rule_chk_connect (struct roar_acl_rule * rule, struct sockaddr * addr, socklen_t addrlen) { if ( !rule ) return -1; if ( rule->pid || rule->uid || rule->gid || rule->cookie ) return 0; if ( rule->addr && addr != NULL ) return 0; return -1; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/asyncctl.c��������������������������������������������������������������0000644�0001750�0001750�00000005755�12264733532�016120� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//asyncctl.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_wait (struct roar_connection * con, struct roar_event * triggered, struct roar_event * events, size_t num) { struct roar_message m; uint16_t * u16 = (uint16_t *) m.data; void * vp = m.data; size_t i, len_left, len_have, tmp; if ( con == NULL || triggered == NULL ) return -1; if ( num == 0 ) return 0; if ( events == NULL ) return -1; memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_WAIT; m.stream = -1; u16[0] = ROAR_HOST2NET16(0); // version u16[1] = ROAR_HOST2NET16(0); // flags vp += 4; // we have 4 byte header (version + flags) len_left = sizeof(m.data) - 4; len_have = 4; for (i = 0; i < num; i++) { tmp = len_left; if ( roar_event_to_blob(&(events[i]), vp, &tmp) == -1 ) return -1; len_left -= tmp; len_have += tmp; vp += tmp; } m.datalen = len_have; if ( roar_req3(con, &m, NULL) != 0 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; u16[0] = ROAR_NET2HOST16(u16[0]); u16[1] = ROAR_NET2HOST16(u16[1]); // check if we have a complet header: if ( m.datalen < 2 ) return -1; // check if we have a unsupported version or flags: if ( u16[0] != 0 || u16[1] != 0 ) return -1; vp = (void*)m.data; vp += 4; len_have = tmp = m.datalen - 4; memset(triggered, 0, sizeof(struct roar_event)); if ( roar_event_from_blob(triggered, vp, &tmp) != 0 ) return -1; // test if we have a length match: if ( len_have != tmp ) return -1; // we now have an event. // we maybe have some data, need to reset this as it is of a local buffer: triggered->arg2 = NULL; triggered->arg2_len = 0; return 0; } //ll �������������������roaraudio-1.0beta11/libroar/auth.c������������������������������������������������������������������0000644�0001750�0001750�00000032550�12264733532�015232� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//auth.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illegal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" /* How auth works: * 0) set stage to zero * 1) get server address and local node name (from uname()) * 2) look up authfile/authdb/authservice for the server+local address + stage. * if no data was found send NONE-Auth. * 3) send data to server * 4) read answer from server * 5) if stage of server response is non-zero increment stage to server stage+1 * and repeat from step 2) * 6) check if we got an OK or an ERROR, return correct value */ /* The protocol: * Auth request: * Byte 0: auth type * Byte 1: stage * Byte 2: reserved (must be zero) * Byte 3: reserved (must be zero) * Byte 4-end: auth type depending data. * * If no data is to be send bytes 2 and 3 can be omitted. * If no data is to be send and stage is zero bytes 1, 2 and 3 can be omitted. * * Auth response: * The same as the auth request. * if the server sends an zero size message back it means the server accepted our connection * and no additional stage is needed. * if the message type is OK the server accepted our auth. * if the message type is ERROR the server rejected us. we may try other auth methods. * if the server accepted our data and the stage is non-zero we need to continue with the next * stage of the auth. * if the server rejected us the auth type value of the response is a suggested next auth type * we should try if possible. This may help the client to find a working auth type. */ /* The protocol by auth type: * * --- NONE: * No data is send, the server accepts the connect or rejects it depending on some * magic within the server. we do not care about this. * The data block is not used. * * --- COOKIE: * We send cookies for all stages the server ask us to provide a cookie. * if a cookie is wrong the server rejects us or asks us for another. * The cookie is send as binary data in the data block. * * --- TRUST: * We ask the server to auth us based on our UID/GID/PID. * The server may reject this because we are not allowed or because it is not * supported by the transport. * If we get rejected we may try to continue with IDENT then RHOST before we use NONE. * The data block is not used. * * --- PASSWORD: * This is technically the same as COOKIE just that the cookie is limited to * printable ASCII chars and that the user should be asked to provide the password. * This may be done via a GUI popup window. * * --- SYSUSER: * We provide a Username + Password for a system user. * The data block contains of two main parts: * The first part is a one byte long subtype. * The value must be 0x01 for username+password. * future versions may define other types. * the second part is the actual data block. * for username+password it is splited into two fields, both terminated with \0. * the first is the username the last one the password as clear text. * Example: char data[] = "\001MyUser\0MyPassword\0"; * * --- OPENPGP_SIGN: * * --- OPENPGP_ENCRYPT: * * --- OPENPGP_AUTH: * * --- KERBEROS: * We use Kerberos to auth. * * --- RHOST: * The server is asked to auth us based on our source address. * The data block is not used. * * --- XAUTH: * We send an X11 Cookie. * * --- IDENT: * The server is asked to auth us based on our source address using the IDENT protocol. * The data block is not used. * */ static int roar_auth_ask_server (struct roar_connection * con, struct roar_auth_message * authmes) { struct roar_error_frame error_frame; struct roar_message mes; char * header = mes.data; int ret; char * data = NULL; ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p{.type=%i}) = ?", con, authmes, authmes->type); roar_err_init(&error_frame); memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy! mes.cmd = ROAR_CMD_AUTH; mes.stream = -1; mes.datalen = 4 + authmes->len; if ( mes.datalen > sizeof(mes.data) ) { data = roar_mm_malloc(mes.datalen); if ( data == NULL ) return -1; header = data; } header[0] = authmes->type; header[1] = authmes->stage; header[2] = authmes->reserved.c[0]; header[3] = authmes->reserved.c[1]; if ( authmes->len ) { if ( data == NULL ) { memcpy(mes.data + 4, authmes->data, authmes->len); } else { memcpy(data + 4, authmes->data, authmes->len); } } ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p{.type=%i}) = ?", con, authmes, authmes->type); if ( (ret = roar_req2(con, &mes, &data, &error_frame)) == -1 ) { authmes->type = -1; ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p) = -1 // next: -1", con, authmes); return -1; } ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p{.type=%i}): mes->cmd=%i", con, authmes, authmes->type, mes.cmd); if ( data != NULL ) { header = data; } else { header = mes.data; } if ( mes.cmd == ROAR_CMD_ERROR ) ret = -1; ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p{.type=%i}): error_frame.data=%p", con, authmes, authmes->type, error_frame.data); if ( mes.cmd == ROAR_CMD_ERROR && error_frame.data != NULL ) { header = error_frame.data; mes.datalen = error_frame.datalen; } ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p{.type=%i}) = ?", con, authmes, authmes->type); if ( mes.datalen < 4 ) { memset(header+mes.datalen, 0, 4-mes.datalen); authmes->type = -1; } else { authmes->type = header[0]; } ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p) = ?", con, authmes); authmes->stage = header[1]; authmes->reserved.c[0] = header[2]; authmes->reserved.c[1] = header[3]; if ( data != NULL ) roar_mm_free(data); ROAR_DBG("roar_auth_ask_server(con=%p, authmes=%p) = %i // next: %i", con, authmes, ret, authmes->type); return ret; } static void roar_auth_mes_init(struct roar_auth_message * authmes, int type) { memset(authmes, 0, sizeof(struct roar_auth_message)); authmes->type = type; authmes->stage = 0; authmes->data = NULL; authmes->len = 0; } static int try_password (struct roar_connection * con, int * next) { struct roar_message mes; struct roar_auth_message authmes; char * pw; // TODO: add support for *next. roar_auth_mes_init(&authmes, ROAR_AUTH_T_PASSWORD); if ( roar_passwd_simple_ask_pw(&pw, "Password for RoarAudio Server?", NULL) == -1 ) { return -1; } authmes.len = strlen(pw); if ( roar_auth_init_mes(&mes, &authmes) == -1 ) { roar_mm_free(pw); return -1; } // do not use strcpy() because that would copy \0, too. memcpy(authmes.data, pw, authmes.len); roar_mm_free(pw); if ( roar_req(con, &mes, NULL) == -1 ) return -1; if ( mes.cmd != ROAR_CMD_OK ) return -1; if ( roar_auth_from_mes(&authmes, &mes, NULL) == -1 ) return -1; if ( authmes.stage == 0 ) return 0; return -1; } static int try_cookie (struct roar_connection * con, int * next) { struct roar_libroar_config * config = roar_libroar_get_config(); struct roar_auth_message authmes; struct roar_authfile * authfile; struct roar_authfile_key * key; int idx; int done = 0; roar_auth_mes_init(&authmes, ROAR_AUTH_T_COOKIE); if ( (authfile = roar_authfile_open(ROAR_AUTHFILE_TYPE_AUTO, config->authfile, 0, ROAR_AUTHFILE_VERSION_AUTO)) == NULL ) return -1; for (idx = 0; !done; idx++) { if ( (key = roar_authfile_lookup_key(authfile, ROAR_AUTH_T_COOKIE, idx, NULL)) == NULL ) break; authmes.data = key->data; authmes.len = key->len; if ( roar_auth_ask_server(con, &authmes) != -1 ) done = 1; roar_authfile_key_unref(key); } roar_authfile_close(authfile); return done ? 0 : -1; } #define _EOL ROAR_AUTH_T_AUTO int roar_auth (struct roar_connection * con) { struct roar_auth_message authmes; int ret; int i; int cur, next; int done; int ltt[] = { ROAR_AUTH_T_TRUST, ROAR_AUTH_T_IDENT, ROAR_AUTH_T_RHOST, // ROAR_AUTH_T_PASSWORD, ROAR_AUTH_T_COOKIE, ROAR_AUTH_T_NONE, ROAR_AUTH_T_PASSWORD, // (re-)try password if there is no guest access. _EOL }; for (i = 0; ltt[i] != _EOL; i++) { next = ltt[i]; ROAR_DBG("roar_auth(con=%p): next from ltt: %s(%i)", con, roar_autht2str(next), next); while (next != -1) { done = 1; cur = next; next = -1; ROAR_DBG("roar_auth(con=%p): cur=%s(%i)", con, roar_autht2str(cur), cur); switch (cur) { case ROAR_AUTH_T_PASSWORD: if ( (ret = try_password(con, &next)) == -1 ) done = 0; break; case ROAR_AUTH_T_TRUST: case ROAR_AUTH_T_IDENT: case ROAR_AUTH_T_RHOST: case ROAR_AUTH_T_NONE: roar_auth_mes_init(&authmes, cur); if ( (ret = roar_auth_ask_server(con, &authmes)) == -1 ) done = 0; next = authmes.type; break; case ROAR_AUTH_T_COOKIE: if ( (ret = try_cookie(con, &next)) == -1 ) done = 0; break; break; default: /* Bad error! */ return -1; break; } if ( authmes.stage != 0 ) done = 0; ROAR_DBG("roar_auth(con=%p): done=%i, next=%i", con, done, next); if ( done ) { ROAR_DBG("roar_auth(con=%p) = 0", con); return 0; } } } ROAR_DBG("roar_auth(con=%p) = -1", con); return -1; } int roar_auth_from_mes(struct roar_auth_message * ames, struct roar_message * mes, void * data) { void * ibuf; char header[4] = {0, 0, 0, 0}; if ( ames == NULL || mes == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( data != NULL ) { ibuf = data; } else { ibuf = mes->data; } memset(ames, 0, sizeof(struct roar_auth_message)); memcpy(header, ibuf, mes->datalen < 4 ? mes->datalen : 4); ames->type = header[0]; ames->stage = header[1]; ames->reserved.c[0] = header[2]; ames->reserved.c[1] = header[3]; if ( mes->datalen > 4 ) { ames->data = ibuf + 4; ames->len = mes->datalen - 4; } else { ames->data = NULL; ames->len = 0; } return 0; } int roar_auth_to_mes(struct roar_message * mes, void ** data, struct roar_auth_message * ames) { char * obuf; if ( mes == NULL || ames == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( data != NULL ) *data = NULL; memset(mes, 0, sizeof(struct roar_message)); mes->cmd = ROAR_CMD_AUTH; if ( (ames->len + 4) > sizeof(mes->data) ) { *data = roar_mm_malloc(ames->len + 4); if ( *data == NULL ) return -1; obuf = *data; } else { obuf = mes->data; } obuf[0] = ames->type; obuf[1] = ames->stage; obuf[2] = ames->reserved.c[0]; obuf[3] = ames->reserved.c[1]; memcpy(obuf + 8, ames->data, ames->len); mes->datalen = ames->len + 4; return 0; } int roar_auth_init_mes(struct roar_message * mes, struct roar_auth_message * ames) { if ( mes == NULL || ames == NULL ) return -1; if ( (ames->len + 4) > sizeof(mes->data) ) return -1; memset(mes, 0, sizeof(struct roar_message)); mes->cmd = ROAR_CMD_AUTH; mes->data[0] = ames->type; mes->data[1] = ames->stage; mes->data[2] = ames->reserved.c[0]; mes->data[3] = ames->reserved.c[1]; ames->data = &(mes->data[4]); mes->datalen = ames->len + 4; return 0; } // String functions: static struct { int type; const char * name; } _g_authts[] = { // grep ^'#define ROAR_AUTH_T_' auth.h | while read d t d; do n=$(cut -d_ -f4 <<<$t | tr A-Z a-z); printf ' {%-28s %-10s},\n' $t, \"$n\"; done {ROAR_AUTH_T_NONE, "none" }, {ROAR_AUTH_T_COOKIE, "cookie" }, {ROAR_AUTH_T_TRUST, "trust" }, {ROAR_AUTH_T_PASSWORD, "password"}, {ROAR_AUTH_T_SYSUSER, "sysuser" }, {ROAR_AUTH_T_OPENPGP_SIGN, "openpgp" }, {ROAR_AUTH_T_OPENPGP_ENCRYPT, "openpgp" }, {ROAR_AUTH_T_OPENPGP_AUTH, "openpgp" }, {ROAR_AUTH_T_KERBEROS, "kerberos"}, {ROAR_AUTH_T_RHOST, "rhost" }, {ROAR_AUTH_T_XAUTH, "xauth" }, {ROAR_AUTH_T_IDENT, "ident" }, {-1, NULL} }; int roar_str2autht(const char * str) { int i; for (i = 0; _g_authts[i].name != NULL; i++) if ( !strcasecmp(_g_authts[i].name, str) ) return _g_authts[i].type; return -1; } const char * roar_autht2str(const int auth) { int i; for (i = 0; _g_authts[i].name != NULL; i++) if ( _g_authts[i].type == auth ) return _g_authts[i].name; return "(UNKNOWN)"; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/authfile.c��������������������������������������������������������������0000644�0001750�0001750�00000015127�12264733533�016074� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//authfile.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" struct roar_authfile { size_t refc; size_t lockc; int type; int rw; int version; size_t magiclen; struct roar_vio_calls vio; }; struct roar_authfile * roar_authfile_open(int type, const char * filename, int rw, int version) { struct roar_vio_defaults def; struct roar_authfile * ret; size_t magiclen = 0; #if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT) struct stat filestat; #endif if ( type == ROAR_AUTHFILE_TYPE_AUTO ) { #if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT) if ( stat(filename, &filestat) != 0 ) return NULL; if ( filestat.st_size == 16 ) { type = ROAR_AUTHFILE_TYPE_ESD; } else if ( filestat.st_size == 256 ) { type = ROAR_AUTHFILE_TYPE_PULSE; } else { return NULL; } #else return NULL; #endif } switch (type) { case ROAR_AUTHFILE_TYPE_ESD: case ROAR_AUTHFILE_TYPE_PULSE: break; default: return NULL; break; } if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, rw ? O_RDWR|O_CREAT : O_RDONLY, 0600) == -1 ) return NULL; if ( (ret = roar_mm_malloc(sizeof(struct roar_authfile))) == NULL ) return NULL; memset(ret, 0, sizeof(struct roar_authfile)); ret->refc = 1; ret->lockc = 0; ret->type = type; ret->rw = rw; ret->version = version; ret->magiclen = magiclen; filename = roar_mm_strdup(filename); if ( roar_vio_open_dstr(&(ret->vio), filename, &def, 1) == -1 ) { roar_mm_free((void*)filename); roar_mm_free(ret); return NULL; } roar_mm_free((void*)filename); return ret; } int roar_authfile_close(struct roar_authfile * authfile) { if ( authfile == NULL ) return -1; roar_vio_close(&(authfile->vio)); roar_mm_free(authfile); return 0; } int roar_authfile_lock(struct roar_authfile * authfile) { if ( authfile == NULL ) return -1; // TODO: implement real locking here. return 0; } int roar_authfile_unlock(struct roar_authfile * authfile) { if ( authfile == NULL ) return -1; // TODO: implement real unlocking here. return 0; } int roar_authfile_sync(struct roar_authfile * authfile) { if ( authfile == NULL ) return -1; return roar_vio_sync(&(authfile->vio)); } struct roar_authfile_key * roar_authfile_key_new(int type, size_t len, const char * addr) { struct roar_authfile_key * ret; size_t addrlen; size_t retlen; if ( addr == NULL ) { addrlen = 0; } else { addrlen = strlen(addr) + 1; } retlen = sizeof(struct roar_authfile_key) + len + addrlen; if ( (ret = roar_mm_malloc(retlen)) == NULL ) return NULL; memset(ret, 0, retlen); ret->refc = 1; ret->type = type; ret->index = -1; if ( addrlen == 0 ) { ret->address = NULL; } else { ret->address = (const void *)ret+sizeof(struct roar_authfile_key); memcpy((void*)ret->address, addr, addrlen); } ret->data = (void*)ret + sizeof(struct roar_authfile_key) + addrlen; ret->len = len; return ret; } int roar_authfile_key_ref(struct roar_authfile_key * key) { if ( key == NULL ) return -1; key->refc++; return 0; } int roar_authfile_key_unref(struct roar_authfile_key * key) { if ( key == NULL ) return -1; if ( key->refc == 0 ) { ROAR_ERR("roar_authfile_key_unref(key=%p): Key has reference count of zero. This is bad. assuming refc=1", key); key->refc = 1; roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); } key->refc--; if ( key->refc > 0 ) return 0; roar_mm_free(key); return 0; } int roar_authfile_add_key(struct roar_authfile * authfile, struct roar_authfile_key * key) { if ( authfile == NULL || key == NULL ) return -1; switch (authfile->type) { case ROAR_AUTHFILE_TYPE_ESD: case ROAR_AUTHFILE_TYPE_PULSE: if ( key->type != ROAR_AUTH_T_COOKIE || (key->index != 0 && key->index != -1) ) return -1; if ( roar_authfile_sync(authfile) == -1 ) return -1; if ( roar_authfile_lock(authfile) == -1 ) return -1; if ( roar_vio_lseek(&(authfile->vio), 0, SEEK_SET) != 0 ) return -1; if ( roar_vio_write(&(authfile->vio), key->data, key->len) != (ssize_t)key->len ) return -1; if ( roar_authfile_unlock(authfile) == -1 ) return -1; return 0; break; default: return -1; break; } } struct roar_authfile_key * roar_authfile_lookup_key(struct roar_authfile * authfile, int type, int minindex, const char * address) { struct roar_authfile_key * ret = NULL; ssize_t len; if ( authfile == NULL ) return NULL; switch (authfile->type) { case ROAR_AUTHFILE_TYPE_ESD: case ROAR_AUTHFILE_TYPE_PULSE: if ( (type != ROAR_AUTH_T_COOKIE && type != ROAR_AUTH_T_AUTO) || minindex > 0 ) return NULL; if ( (ret = roar_authfile_key_new(ROAR_AUTH_T_COOKIE, 256, NULL)) == NULL ) return NULL; len = roar_vio_read(&(authfile->vio), ret->data, ret->len); if ( len == -1 ) { roar_authfile_key_unref(ret); return NULL; } ret->len = len; ret->index = 0; break; default: return NULL; break; } return ret; } struct roar_authfile_key * roar_authfile_key_new_random(int type, size_t len, const char * addr) { struct roar_authfile_key * ret = roar_authfile_key_new(type, len, addr); if ( ret == NULL ) return NULL; roar_random_gen_nonce(ret->data, ret->len); return ret; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/base64.c����������������������������������������������������������������0000644�0001750�0001750�00000017401�12264733533�015354� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//base64.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static char _base64_tab_fw[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; static char _base64_tab_bw[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; int roar_base64_init(struct roar_base64 * state, int flags) { if ( flags == -1 ) flags = 0; if ( state == NULL ) return -1; memset(state, 0, sizeof(struct roar_base64)); state->flags = flags; return 0; } static inline void _libroar_base64_encode_block(unsigned char out[4], const unsigned char in[3]) { // printf("in={'%c', '%c', '%c'}\n", in[0], in[1], in[2]); out[0] = _base64_tab_fw[(in[0] >> 2) & 0x3F]; out[1] = _base64_tab_fw[(((in[0] & 0x03) << 4) | (in[1] >> 4)) & 0x3F]; out[2] = _base64_tab_fw[(((in[1] & 0x0F) << 2) | ((in[2] >> 6) & 0x03)) & 0x3F]; out[3] = _base64_tab_fw[in[2] & 0x3F]; } #define _setoff(x) do { if ( off != NULL ) { *off = (x); } } while (0) ssize_t roar_base64_encode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off, int eof) { struct roar_base64 state_store; size_t offset = 0; size_t tlen; ssize_t ret = 0; unsigned char * outp; const unsigned char * inp; if ( inlen && in == NULL ) return -1; if ( outlen && out == NULL ) return -1; // this test should be removed as soon as those modes are supported. if ( in == NULL || out == NULL ) return -1; // we can not write anything anyway... if ( outlen < 4 ) return 0; if ( state == NULL ) { state = &state_store; roar_base64_init_encode(state, ROAR_BASE64_FLAG_NONE); eof = 1; } if ( state->buflen ) { tlen = 3 - state->buflen; ROAR_DBG("roar_base64_encode(state=%p,...): Still %llu bytes in state", state, (long long unsigned int)state->buflen); ROAR_DBG("roar_base64_encode(state=%p,...): Need %llu bytes", state, (long long unsigned int)tlen); if ( inlen >= tlen ) { memcpy(state->iobuf + state->buflen, in, tlen); offset += tlen; in += tlen; inlen -= tlen; _libroar_base64_encode_block(out, state->iobuf); out += 4; outlen -= 4; ret += 4; state->buflen = 0; } else { memcpy(state->iobuf + state->buflen, in, inlen); state->buflen += inlen; _setoff(inlen); return 0; } } for (; inlen >= 3 && outlen >= 4;) { _libroar_base64_encode_block(out, in); ret += 4; out += 4; in += 3; offset += 3; inlen -= 3; outlen -= 4; } // something left? if ( inlen ) { if ( eof ) { if ( outlen >= 4 ) { outp = out; inp = in; switch (inlen) { case 1: outp[0] = _base64_tab_fw[inp[0] >> 2]; outp[1] = _base64_tab_fw[(inp[0] & 0x03) << 4]; outp[2] = '='; outp[3] = '='; ret += 4; out += 4; in += 1; offset += 1; inlen -= 1; outlen -= 4; break; case 2: outp[0] = _base64_tab_fw[inp[0] >> 2]; outp[1] = _base64_tab_fw[(((inp[0] & 0x03) << 4) | (inp[1] >> 4)) & 0x3F]; outp[2] = _base64_tab_fw[(((inp[1] & 0x0F) << 2)) & 0x3F]; outp[3] = '='; ret += 4; out += 4; in += 2; offset += 2; inlen -= 2; outlen -= 4; break; } } } else { memcpy(state->iobuf, in, inlen); state->buflen = inlen; offset += inlen; in += inlen; inlen -= inlen; } } if ( outlen ) { *(char*)out = 0; } _setoff(offset); return 0; } ssize_t roar_base64_decode(struct roar_base64 * state, void * out, size_t outlen, const void * in, size_t inlen, size_t * off) { struct roar_base64 state_store; ssize_t ret = 0; unsigned char c; int bits; const unsigned char * inp = in; unsigned char * outp = out; size_t offset = 0; if ( inlen && in == NULL ) return -1; if ( outlen && out == NULL ) return -1; // this test should be removed as soon as those modes are supported. if ( in == NULL || out == NULL ) return -1; if ( state == NULL ) { state = &state_store; roar_base64_init_encode(state, ROAR_BASE64_FLAG_NONE); } if ( state->reglen >= 8 ) { *outp = (state->reg >> (state->reglen - 8)) & 0xFF; state->reglen -= 8; outp++; outlen--; ret++; } if ( state->flags & ROAR_BASE64_FLAG_EOF ) { if ( outlen ) { *outp = 0; } return ret; } //printf("state->reglen=%i\n", (int)state->reglen); for (; inlen && outlen; ) { c = *inp; inp++; inlen--; offset++; if ( c == '=' ) { bits = 0; } else { // hi-bit set chars need to be ignored. if ( (size_t)c > sizeof(_base64_tab_bw) ) continue; bits = _base64_tab_bw[c]; // ignore unknown chars. if ( bits == (char)0xFF ) continue; } state->reg <<= 6; state->reg |= bits; state->reglen += 6; if ( state->reglen >= 8 ) { *outp = (state->reg >> (state->reglen - 8)) & 0xFF; state->reglen -= 8; outp++; outlen--; ret++; } if ( c == '=' ) { state->flags |= ROAR_BASE64_FLAG_EOF; if ( state->reglen <= 6 ) { state->reglen = 0; } if ( inlen ) { if ( *inp == '=' ) { offset++; } } break; } } if ( off != NULL ) { *off = offset; } if ( outlen ) { *outp = 0; } return ret; } int roar_base64_is_eof(struct roar_base64 * state) { if ( state == NULL ) return -1; if ( state->reglen >= 8 ) return 0; return !!(state->flags & ROAR_BASE64_FLAG_EOF); } int roar_base64_uninit(struct roar_base64 * state) { if ( state == NULL ) return -1; if ( state->buflen ) { ROAR_WARN("roar_base64_uninit(state=%p): State has %i bytes left in IO buffer. This is a application error.", state, state->buflen); } if ( state->reglen ) { ROAR_WARN("roar_base64_uninit(state=%p): State has %i bits left in decode register. This is a application error.", state, state->reglen); } return 0; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/basic.c�����������������������������������������������������������������0000644�0001750�0001750�00000055104�12264733534�015354� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//basic.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) #include <pwd.h> #endif enum mode { NORMAL = 0, SYSTEM = 1 }; static int _connect_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout); int __get_daemonimage(char ** daemonimage, enum mode * mode, const char * server) { const char * tmp = NULL; *daemonimage = NULL; *mode = NORMAL; if ( !!strncmp(server, "+fork", 5) ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } server += 5; if ( server[0] == '=' ) { server++; if ( server[0] == 0 ) { // no special case, we just ignore it. } else if ( server[0] == 'd' && server[1] == ':' ) { server += 2; tmp = server; *mode = NORMAL; } else if ( server[0] == '!' ) { server += 1; tmp = server; *mode = SYSTEM; } else { roar_err_set(ROAR_ERROR_ILLSEQ); return -1; } } if ( tmp == NULL || *tmp == 0 ) tmp = roar_libroar_get_config()->daemonimage; // we keep this step to be compatible with older versions. if ( tmp == NULL || *tmp == 0 ) { tmp = roar_env_get("ROAR_DAEMONIMAGE"); if ( tmp != NULL ) { ROAR_WARN("__get_daemonimage(*): Usage of $ROAR_DAEMONIMAGE is obsolete. Use ROAR_OPTIONS=daemonimage:..."); } } if ( tmp != NULL && *tmp != 0 ) { *daemonimage = roar_mm_strdup(tmp); return 0; } *daemonimage = roar_libroar_get_path("bin-default-daemonimage", 0, NULL, NULL); if ( *daemonimage == NULL ) return -1; return 0; } #if defined(ROAR_TARGET_WIN32) #define NUM_TRIES 16 static int _start_server_win32(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { enum mode mode = NORMAL; char * daemonimage = NULL; char buf[64]; int port; size_t i; int fh; int ret; int err; if ( __get_daemonimage(&daemonimage, &mode, server) == -1 ) return -1; if ( mode != NORMAL ) { roar_mm_free(daemonimage); roar_err_set(ROAR_ERROR_NOSYS); return -1; } for (i = 0; i < NUM_TRIES; i++) { port = roar_random_uint16(); if ( port < 1025 ) /* it seems on some strange systems the magic border is at 1025 not 1024. */ continue; fh = roar_socket_connect(ROAR_SOCKET_TYPE_TCP, "localhost", port); if ( fh == -1 ) break; closesocket(fh); } if ( i == NUM_TRIES ) { roar_mm_free(daemonimage); roar_err_set(ROAR_ERROR_LOOP); return -1; } // port is the port to use. It seems to be 'free'. #if defined(_P_DETACH) #define MODE _P_DETACH #elif defined(_P_NOWAIT) #define MODE _P_NOWAIT #else #define MODE _P_NOWAITO #endif snprintf(buf, sizeof(buf), "%i", port); roar_err_clear_all(); if ( _spawnlp(MODE, daemonimage, daemonimage, "--tcp", "--bind", "localhost", "--port", buf, (const char*)NULL) < 0 ) { roar_err_update(); ROAR_ERR("_start_server_win32(server='%s', ...): Can not start server: %s: %s", server, daemonimage, roar_errorstring); roar_mm_free_noerror(daemonimage); return -1; } roar_mm_free(daemonimage); snprintf(buf, sizeof(buf), "localhost:%i", port); // give the daemon some time to come up: roar_usleep(25000); ret = -1; for (i = 0; ret == -1 && i < NUM_TRIES; i++) { ret = _connect_server(con, buf, type, flags, timeout); if ( ret == -1 && i < NUM_TRIES ) roar_sleep(1); } if ( ret == -1 ) return -1; con->flags |= ROAR_CON_FLAGS_TERMINATE; return 0; } #elif !defined(ROAR_TARGET_MICROCONTROLLER) static int _start_server_posix(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { enum mode mode = NORMAL; char * daemonimage = NULL; int socks[2]; int r; char fhstr[12]; size_t len; char * bin_sh; int err; if ( __get_daemonimage(&daemonimage, &mode, server) == -1 ) return -1; len = roar_mm_strlen(daemonimage) + 9; // 9 = '+fork=' + 'X:' + '\0' con->server_name = roar_mm_malloc(len); if ( con->server_name != NULL ) { snprintf(con->server_name, len, "+fork=%s%s", mode == NORMAL ? "d:" : "!", daemonimage); } if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) { roar_err_from_errno(); roar_mm_free_noerror(daemonimage); return -1; } r = roar_fork(NULL); if ( r == -1 ) { // error! ROAR_ERR("_start_server(*): Can not fork: %s", roar_error2str(roar_error)); err = roar_error; close(socks[0]); close(socks[1]); roar_mm_free(daemonimage); roar_error = err; return -1; } else if ( r == 0 ) { // we are the child roar_watchdog_stop(); close(socks[0]); close(ROAR_STDIN ); // we do not want roard to have any standard input close(ROAR_STDOUT); // STDOUT is also not needed, so we close it, // but STDERR we keep open for error messages. snprintf(fhstr, sizeof(fhstr), "%i", socks[1]); switch (mode) { case NORMAL: execlp(daemonimage, daemonimage, "--no-listen", "--client-fh", fhstr, (_LIBROAR_GOOD_CAST char*)NULL); break; case SYSTEM: dup2(socks[1], ROAR_STDIN ); dup2(socks[1], ROAR_STDOUT); bin_sh = roar_libroar_get_path("bin-sh", 0, NULL, NULL); if ( bin_sh != NULL ) { execl(bin_sh, bin_sh, "-c", daemonimage, (_LIBROAR_GOOD_CAST char*)NULL); roar_mm_free(bin_sh); } execlp("sh", "sh", "-c", daemonimage, (_LIBROAR_GOOD_CAST char*)NULL); break; } roar_mm_free(daemonimage); // we are still alive? ROAR_ERR("_start_server(*): alive after exec(), that's bad!"); ROAR_U_EXIT(1); } else { // we are the parent close(socks[1]); roar_mm_free(daemonimage); if ( roar_vio_open_fh_socket(con->viocon, socks[0]) == -1 ) { close(socks[0]); return -1; } else { con->flags |= ROAR_CON_FLAGS_VIO; } return 0; } return -1; } #endif static int _start_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { #if defined(ROAR_TARGET_WIN32) return _start_server_win32(con, server, type, flags, timeout); #elif !defined(ROAR_TARGET_MICROCONTROLLER) return _start_server_posix(con, server, type, flags, timeout); #else ROAR_ERR("_start_server(*): There is no UNIX Domain Socket, download a real OS."); roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } static int _connect_internal(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { struct roar_libroar_config * config = roar_libroar_get_config(); struct roar_vio_calls * vio; if ( config->connect_internal != NULL ) { vio = config->connect_internal(con, server, type, flags, timeout); if ( vio == NULL ) return -1; con->viocon = vio; con->flags |= ROAR_CON_FLAGS_VIO; return 0; } roar_err_set(ROAR_ERROR_BADHOST); return -1; } static int _connect_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { #if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT) struct stat sockstat; #endif const char * obj = NULL; char user_sock[128]; int is_decnet = 0; int port = 0; int i = 0; int fh = -1; int err; int ret; if ( con == NULL || server == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( !strcmp(server, "+invalid") ) { roar_err_set(ROAR_ERROR_CANCELED); return -1; } else if ( !strncmp(server, "+dstr=", 6) ) { if ( roar_vio_open_dstr_simple(con->viocon, server+6, ROAR_VIOF_READWRITE) == -1 ) return -1; con->flags |= ROAR_CON_FLAGS_VIO; con->server_name = roar_mm_strdup(server); return 0; } else if ( !strcmp(server, "+fork") || !strncmp(server, "+fork=", 6) ) { return _start_server(con, server, type, flags, timeout); } else if ( !strcmp(server, "+internal") || !strncmp(server, "+internal=", 10) ) { ret = _connect_internal(con, server, type, flags, timeout); if ( ret == 0 ) con->server_name = roar_mm_strdup(server); return ret; } strncpy(user_sock, server, sizeof(user_sock)-1); user_sock[sizeof(user_sock)-1] = 0; if ( *user_sock != '/' ) { // don't test AF_UNIX sockets for ports for (i = 0; user_sock[i] != 0; i++) { if ( user_sock[i] == ':' ) { if ( user_sock[i+1] == ':' ) { // DECnet, leave unchanged is_decnet = 1; obj = &user_sock[i+2]; break; } port = atoi(&(user_sock[i+1])); user_sock[i] = 0; break; } } } if ( is_decnet ) { if ( *user_sock == ':' ) { if ( roar_socket_get_local_nodename() != NULL ) { strncpy(user_sock, roar_socket_get_local_nodename(), sizeof(user_sock)-1); user_sock[sizeof(user_sock)-1] = 0; roar_mm_strlcat(user_sock, server, sizeof(user_sock)-1); user_sock[sizeof(user_sock)-1] = 0; obj = strstr(user_sock, "::"); obj += 2; } } if ( *obj == 0 ) { roar_mm_strlcat(user_sock, ROAR_DEFAULT_OBJECT, sizeof(user_sock)-1); user_sock[sizeof(user_sock)-1] = 0; } ROAR_DBG("roar_connect_raw(*): user_sock='%s'", user_sock); } if ( port || is_decnet ) { fh = roar_socket_connect(type, user_sock, port); // restore the original string user_sock[i] = ':'; } else { #if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT) if ( user_sock[0] == '/' ) { if ( stat(user_sock, &sockstat) == 0 ) { if ( S_ISCHR(sockstat.st_mode) ) { #ifdef O_NOCTTY fh = open(user_sock, O_RDWR|O_NOCTTY, 0666); #else fh = open(user_sock, O_RDWR, 0666); #endif } } } #endif if ( fh == -1 ) fh = roar_socket_connect(type, user_sock, ROAR_DEFAULT_PORT); } if ( fh == -1 ) return -1; if ( roar_vio_open_fh_socket(con->viocon, fh) == -1 ) { err = roar_error; #ifdef ROAR_TARGET_WIN32 closesocket(fh); #else close(fh); #endif roar_error = err; return -1; } else { con->flags |= ROAR_CON_FLAGS_VIO; } con->server_name = roar_mm_strdup(server); roar_err_set(ROAR_ERROR_NONE); return 0; } static int roar_connect_raw (struct roar_connection * con, const char * server, int flags, uint_least32_t timeout) { #ifdef ROAR_HAVE_LIBSLP struct roar_libroar_config * config = roar_libroar_get_config(); #endif #if defined(ROAR_HAVE_UNIX) char user_sock[128]; const char * roar_server; #endif #if defined(ROAR_HAVE_LIBSLP) || !defined(ROAR_TARGET_MICROCONTROLLER) int i = 0; #endif #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) struct passwd * pwd; char * sysconf_roarserver; #endif #ifdef ROAR_HAVE_LIBDNET struct stat decnet_stat; #endif #ifdef ROAR_HAVE_LIBX11 struct roar_x11_connection * x11con; #endif #ifdef ROAR_HAVE_LIBSLP struct roar_server * list; int workarounds_store; #endif roar_err_set(ROAR_ERROR_UNKNOWN); if ( timeout != 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( flags & ROAR_ENUM_FLAG_HARDNONBLOCK ) flags |= ROAR_ENUM_FLAG_NONBLOCK; if ( server == NULL || *server == 0 ) server = roar_libroar_get_server(); if ( server == NULL || *server == 0 ) server = roar_env_get("ROAR_SERVER"); #ifdef ROAR_HAVE_LIBX11 if ( server == NULL || *server == 0 ) { if ( (x11con = roar_x11_connect(NULL)) != NULL ) { server = roar_x11_get_prop(x11con, "ROAR_SERVER"); roar_x11_disconnect(x11con); } } #endif #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) sysconf_roarserver = roar_libroar_get_path("sysconf-roarserver", 0, NULL, NULL); if ( sysconf_roarserver != NULL ) { if ( (server == NULL || *server == 0) && (i = readlink(sysconf_roarserver, user_sock, sizeof(user_sock)-1)) != -1 ) { user_sock[i] = 0; server = user_sock; } roar_mm_free(sysconf_roarserver); } #endif if ( server != NULL && !strcasecmp(server, "+slp") ) { server = roar_slp_find_roard(0); if ( server == NULL ) { return -1; } } // "+default" is an alias for NULL. if ( server != NULL && !strcasecmp(server, "+default") ) { server = NULL; } if ( server == NULL || *server == 0 ) { /* connect via defaults */ #ifdef ROAR_HAVE_UNIX #ifndef ROAR_TARGET_MICROCONTROLLER roar_server = roar_env_get("HOME"); #else roar_server = NULL; #endif if ( roar_server == NULL ) { #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) if ( (pwd = getpwuid(getuid())) != NULL ) { roar_server = pwd->pw_dir; } #endif } if ( roar_server != NULL ) { snprintf(user_sock, sizeof(user_sock)-1, "%s/%s", roar_server, ROAR_DEFAULT_SOCK_USER); user_sock[sizeof(user_sock)-1] = 0; if ( _connect_server(con, user_sock, ROAR_SOCKET_TYPE_UNIX, flags, timeout) == 0 ) return 0; } if ( _connect_server(con, ROAR_DEFAULT_SOCK_GLOBAL, ROAR_SOCKET_TYPE_UNIX, flags, timeout) == 0 ) return 0; #endif if ( _connect_server(con, ROAR_DEFAULT_HOSTPORT, ROAR_SOCKET_TYPE_TCP, flags, timeout) == 0 ) return 0; #ifdef ROAR_HAVE_LIBDNET if ( stat(ROAR_PROC_NET_DECNET, &decnet_stat) == 0 ) { if ( roar_socket_get_local_nodename() ) { snprintf(user_sock, sizeof(user_sock)-1, "%s::%s", roar_socket_get_local_nodename(), ROAR_DEFAULT_OBJECT); if ( _connect_server(con, user_sock, ROAR_SOCKET_TYPE_DECNET, flags, timeout) == 0 ) return 0; } } #endif if ( _connect_server(con, "+abstract", ROAR_SOCKET_TYPE_UNKNOWN, flags, timeout) == 0 ) return 0; #ifdef ROAR_HAVE_LIBSLP if ( !(config->workaround.workarounds & ROAR_LIBROAR_CONFIG_WAS_NO_SLP) && !(flags & ROAR_ENUM_FLAG_NONBLOCK) && !(flags & ROAR_ENUM_FLAG_LOCALONLY) ) { if ( (server = roar_slp_find_roard(0)) != NULL ) { if ( _connect_server(con, server, ROAR_SOCKET_TYPE_UNKNOWN, 0, 0) == 0 ) return 0; /* in case we can not connect to the server given this may be a cache problem, we do a new lookup with the cache disabled in this case */ ROAR_WARN("roar_connect_raw(*): Can not connect to SLP located server, disabling cache"); if ( (server = roar_slp_find_roard(1)) != NULL ) if ( _connect_server(con, server, ROAR_SOCKET_TYPE_UNKNOWN, 0, 0) == 0 ) return 0; } } workarounds_store = config->workaround.workarounds; config->workaround.workarounds |= ROAR_LIBROAR_CONFIG_WAS_NO_SLP; list = roar_enum_servers(flags, -1, -1); config->workaround.workarounds = workarounds_store; if ( list != NULL ) { for (i = 0; list[i].server != NULL; i++) { if ( _connect_server(con, list[i].server, ROAR_SOCKET_TYPE_UNKNOWN, 0, 0) == 0 ) { roar_enum_servers_free(list); return 0; } } roar_enum_servers_free(list); } #endif return -1; } else { /* connect via (char*)server */ if ( _connect_server(con, server, ROAR_SOCKET_TYPE_UNKNOWN, flags, timeout) != 0 ) return -1; return 0; } roar_err_set(ROAR_ERROR_NODEV); ROAR_DBG("roar_connect_raw(*) = -1 // error=NODEV"); return -1; } int roar_connect (struct roar_connection * con, const char * server, int flags, uint_least32_t timeout) { struct roar_libroar_config * config = roar_libroar_get_config(); if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( roar_connect_none(con) == -1 ) return -1; if ( roar_connect_raw(con, server, flags | config->serverflags, timeout) == -1 ) return -1; return 0; } int roar_connect_none (struct roar_connection * con) { struct roar_libroar_config * config = roar_libroar_get_config(); if ( con == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } memset(con, 0, sizeof(struct roar_connection)); con->refc = 1; con->flags = ROAR_CON_FLAGS_ISCLIENT; con->version = _ROAR_MESSAGE_VERSION; con->cb_userdata = NULL; con->cb = NULL; con->server_stds = NULL; con->server_name = NULL; roar_err_init(&(con->errorframe)); con->viocon = &(con->viocon_store); // con->flags |= ROAR_CON_FLAGS_VIO; if ( config->protocolversion != -1 ) roar_set_connection_version(con, config->protocolversion); roar_err_set(ROAR_ERROR_NONE); return 0; } int roar_connect_vio (struct roar_connection * con, struct roar_vio_calls * vio) { if ( con == NULL || vio == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( roar_connect_none(con) == -1 ) return -1; con->viocon = vio; con->flags |= ROAR_CON_FLAGS_VIO; return -1; } int roar_connect_fh (struct roar_connection * con, int fh) { if ( con == NULL || fh == -1 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( roar_connect_none(con) == -1 ) return -1; // special hack to set an illegal value used internally in libroar: if ( fh == -2 ) fh = -1; if ( roar_vio_open_fh_socket(con->viocon, fh) != -1 ) { con->flags |= ROAR_CON_FLAGS_VIO; } else { return -1; } roar_err_set(ROAR_ERROR_NONE); return 0; } int roar_get_connection_fh (struct roar_connection * con) { int fh; ROAR_DBG("roar_get_connection_fh(con=%p) = ?", con); roar_debug_warn_sysio("roar_get_connection_fh", "roar_get_connection_vio2", NULL); if ( con == NULL ) return -1; ROAR_DBG("roar_get_connection_fh(con=%p) = ?", con); if ( roar_vio_ctl(con->viocon, ROAR_VIO_CTL_GET_FH, &fh) == -1 ) { #ifdef ROAR_TARGET_WIN32 if ( roar_vio_ctl(con->viocon, ROAR_VIO_CTL_GET_SELECT_FH, &fh) == -1 ) return -1; #else return -1; #endif } ROAR_DBG("roar_get_connection_fh(con=%p) = %i", con, fh); return fh; } struct roar_vio_calls * roar_get_connection_vio2 (struct roar_connection * con) { if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( con->flags & ROAR_CON_FLAGS_VIO ) return con->viocon; // TODO: try to open the VIO. roar_err_set(ROAR_ERROR_BADFH); return NULL; } const char * roar_get_connection_server(struct roar_connection * con) { if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } return con->server_name; } int roar_connectionref(struct roar_connection * con) { if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } con->refc++; return 0; } int roar_connectionunref(struct roar_connection * con) { struct roar_vio_calls * vio; struct roar_message m; if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } con->refc--; if ( con->refc ) return 0; if ( con->flags & ROAR_CON_FLAGS_TERMINATE ) { if ( roar_terminate(con, 1) == -1 ) { ROAR_WARN("roar_connectionunref(con=%p{.server_name='%s'}): Can not terminate server as requested.", con, con->server_name); if ( roar_terminate(con, 0) == -1 ) { ROAR_ERR("roar_connectionunref(con=%p{.server_name='%s'}): Can not exit server. BAD.", con, con->server_name); } } } memset(&m, 0, sizeof(m)); m.datalen = 0; m.stream = -1; m.pos = 0; m.cmd = ROAR_CMD_QUIT; roar_req(con, &m, NULL); if ( (vio = roar_get_connection_vio2(con)) != NULL ) { roar_vio_close(vio); } if ( con->server_stds != NULL ) { roar_stds_free(con->server_stds); con->server_stds = NULL; } if ( con->server_name != NULL ) { roar_mm_free(con->server_name); con->server_name = NULL; } if ( con->flags & ROAR_CON_FLAGS_FREESELF ) { roar_mm_free(con); } else { roar_connect_fh(con, -2); } return 0; } int roar_set_connection_callback(struct roar_connection * con, void (*cb)(struct roar_connection * con, struct roar_message * mes, void * data, void * userdata), void * userdata) { if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } con->cb = cb; con->cb_userdata = userdata; return 0; } int roar_set_connection_version(struct roar_connection * con, int version) { if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( version == -1 ) version = _ROAR_MESSAGE_VERSION; if ( version < 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } con->version = version; if ( version == 2 ) { con->flags |= ROAR_CON_FLAGS_SUPPORT_V2; } return 0; } int16_t roar_message_genseq(struct roar_connection * con, int is_client) { static int16_t store = 0; int16_t ret = 0; ret = store++; if ( ret == 0 ) ret = store++; if ( is_client == -1 ) { if ( con != NULL ) { is_client = con->flags & ROAR_CON_FLAGS_ISCLIENT ? 1 : 0; } } if ( is_client == -1 ) is_client = 1; ret |= 0x8000U; if ( !is_client ) ret -= 0x8000U; return ret; } int roar_sync (struct roar_connection * con) { // wait for any non-client reqs return roar_wait_msg(con, 0x0000, 0x8000); } int roar_wait_msg (struct roar_connection * con, int16_t seq, int16_t seqmask) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } int roar_noop (struct roar_connection * con) { struct roar_message mes; if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&mes, 0, sizeof(mes)); mes.cmd = ROAR_CMD_NOOP; mes.stream = -1; return roar_req3(con, &mes, NULL); } int roar_identify (struct roar_connection * con, const char * name) { struct roar_message mes; uint32_t pid; int max_len; roar_err_set(ROAR_ERROR_UNKNOWN); ROAR_DBG("roar_identify(*): try to identify myself..."); memset(&mes, 0, sizeof(mes)); mes.cmd = ROAR_CMD_IDENTIFY; mes.stream = -1; mes.pos = 0; ROAR_DBG("roar_identify(*): name=%p", name); if ( name == NULL ) name = "libroar client"; ROAR_DBG("roar_identify(*): name=%p", name); max_len = roar_mm_strlen(name); ROAR_DBG("roar_identify(*): strlen(name) = %i", max_len); if ( max_len > (LIBROAR_BUFFER_MSGDATA - 5) ) max_len = LIBROAR_BUFFER_MSGDATA - 5; mes.datalen = 5 + max_len; mes.data[0] = 1; pid = getpid(); mes.data[1] = (pid & 0xFF000000UL) >> 24; mes.data[2] = (pid & 0x00FF0000UL) >> 16; mes.data[3] = (pid & 0x0000FF00UL) >> 8; mes.data[4] = (pid & 0x000000FFUL) >> 0; ROAR_DBG("roar_identify(*): pid = %i", (int)pid); strncpy(mes.data+5, name, max_len); return roar_req3(con, &mes, NULL); } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/beep.c������������������������������������������������������������������0000644�0001750�0001750�00000004310�12264733534�015177� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//beep.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_beep(struct roar_connection * con, const struct roar_beep * beep) { struct roar_message m; int16_t * data = (int16_t*)m.data; if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_BEEP; if ( beep == NULL ) { m.datalen = 0; } else { m.datalen = 8*2; data[0] = ROAR_HOST2NET16(0); // version data[1] = ROAR_HOST2NET16(beep->vol); data[2] = ROAR_HOST2NET16(beep->time); data[3] = ROAR_HOST2NET16(beep->freq); data[4] = ROAR_HOST2NET16(beep->type); data[5] = ROAR_HOST2NET16(beep->x); data[6] = ROAR_HOST2NET16(beep->y); data[7] = ROAR_HOST2NET16(beep->z); } if ( roar_req3(con, &m, NULL) != 0 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return m.stream; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/buffer.c����������������������������������������������������������������0000644�0001750�0001750�00000052334�12264733535�015547� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//buffer.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" struct roar_buffer_ring { size_t read_pos; size_t write_pos; }; struct roar_buffer { size_t refc; size_t len; size_t user_len; int flags; void * data; void * user_data; union { void * vp; int32_t i32; struct roar_buffer_ring ring; } meta; int type; struct roar_buffer * next; }; #define _ckbuf_free(m) if ( buf == NULL || (m) ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } #define _ckbuf(m) if ( _ckmem_corruption(buf, (m)) == -1 ) return -1; // if we use the 'inline' keyword here the program segfaults. why? static int _ckmem_corruption(volatile struct roar_buffer * buf, int m) { int flags; ROAR_DBG("_ckmem_corruption(buf=%p) = ?", buf); // we need to recheck here, why? // gcc changes the order of the above macros. why? // this is a strange world. if ( buf == NULL || m ) { ROAR_DBG("_ckmem_corruption(buf=%p) = -1 // FAULT", buf); roar_err_set(ROAR_ERROR_FAULT); return -1; } ROAR_DBG("_ckmem_corruption(buf=%p) = ?", buf); flags = buf->flags & (ROAR_BUFFER_FLAG_USEABLE|ROAR_BUFFER_FLAG_FREED); ROAR_DBG("_ckmem_corruption(buf=%p{.flags=0x%.4x, ...}) = ?", buf, buf->flags); if ( flags == ROAR_BUFFER_FLAG_USEABLE ) { // seems ok, continue with next check. } else if ( flags == ROAR_BUFFER_FLAG_FREED ) { roar_panic(ROAR_FATAL_ERROR_MEMORY_USED_AFTER_FREE, NULL); roar_err_set(ROAR_ERROR_FAULT); return -1; } else { roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); roar_err_set(ROAR_ERROR_BADCKSUM); return -1; } if ( buf->refc == 0 ) { roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); roar_err_set(ROAR_ERROR_FAULT); return -1; } return 0; } int roar_buffer_new_data (struct roar_buffer ** buf, size_t len, void ** data) { void * bufdata; int err; if ((bufdata = roar_mm_malloc(len)) == NULL) { return -1; } if ( roar_buffer_new_no_ma(buf, len, bufdata) == -1 ) { roar_mm_free_noerror(bufdata); return -1; } if ( roar_buffer_set_flag(*buf, ROAR_BUFFER_FLAG_NOFREE, ROAR_BUFFER_RESET) == -1 ) { err = roar_error; roar_buffer_free(*buf); roar_mm_free(bufdata); roar_err_set(err); return -1; } if ( data != NULL ) *data = bufdata; return 0; } int roar_buffer_new_no_ma(struct roar_buffer ** buf, size_t len, void * data) { // no internal malloc struct roar_buffer * new; ROAR_DBG("buffer_new(buf=%p, len=%i) = ?", buf, len); _ckbuf_free(data == NULL) if ((new = roar_mm_malloc(sizeof(struct roar_buffer))) == NULL) { *buf = NULL; return -1; } new->refc = 1; new->data = data; new->flags = ROAR_BUFFER_FLAG_NONE|ROAR_BUFFER_FLAG_NOFREE|ROAR_BUFFER_FLAG_USEABLE; new->type = -1; new->user_data = new->data; new->next = NULL; new->len = len; new->user_len = len; *buf = new; ROAR_DBG("buffer_new(buf=%p, len=%i): New buffer at %p", buf, len, new); return 0; } int roar_buffer_new_str (struct roar_buffer ** buf, const char * str, int terminate) { size_t len; void * data; if ( buf == NULL || str == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } len = roar_mm_strlen(str); if ( terminate ) len++; if ( roar_buffer_new_data(buf, len, &data) == -1 ) return -1; if ( len ) memcpy(data, str, len); return 0; } int roar_buffer_ref (struct roar_buffer * buf) { _ckbuf(0) buf->refc++; return 0; } int roar_buffer_unref (struct roar_buffer * buf) { struct roar_buffer * next, * cur; int flags; ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); _ckbuf_free(0) ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); cur = buf; while (cur != NULL) { flags = cur->flags & (ROAR_BUFFER_FLAG_USEABLE|ROAR_BUFFER_FLAG_FREED); if ( flags == ROAR_BUFFER_FLAG_FREED ) { roar_panic(ROAR_FATAL_ERROR_MEMORY_DOUBLE_FREE, NULL); } _ckmem_corruption(cur, 0); if ( cur->refc == 0 ) { ROAR_WARN("roar_buffer_unref(buf=%p): Ref counter for buffer at %p is wrong. assuming one.", cur, cur); cur->refc = 1; roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); } else if ( cur->refc > 1 ) { cur->refc--; return 0; } ROAR_DBG("roar_buffer_unref(buf=%p) = ?", buf); if ( roar_buffer_get_flag(cur, ROAR_BUFFER_FLAG_NOFREE) != 1 ) roar_mm_free(cur->data); cur->flags = ROAR_BUFFER_FLAG_FREED; next = cur->next; roar_mm_free(cur); cur = next; } ROAR_DBG("roar_buffer_unref(buf=%p) = 0", buf); return 0; } int roar_buffer_delete (struct roar_buffer * buf, struct roar_buffer ** next) { if ( buf == NULL ) { if ( next != NULL ) *next = NULL; roar_err_set(ROAR_ERROR_FAULT); return -1; } ROAR_DBG("roar_buffer_delete(buf=%p, next=%p) = ?", buf, next); if ( next != NULL ) { *next = buf; return roar_buffer_next(next); } else { return roar_buffer_unref(buf); } } int roar_buffer_next (struct roar_buffer ** buf) { struct roar_buffer * ret; if ( buf == NULL || *buf == NULL ) { roar_err_set(ROAR_ERROR_FAULT); } ret = (*buf)->next; if ( ret != NULL ) roar_buffer_ref(ret); roar_buffer_unref(*buf); *buf = ret; return 0; } int roar_buffer_add (struct roar_buffer * buf, struct roar_buffer * next) { if ( roar_buffer_ref(next) == -1 ) return -1; return roar_buffer_moveinto(buf, &next); } int roar_buffer_moveinto (struct roar_buffer * buf, struct roar_buffer ** next) { unsigned int deep = 0; _ckbuf(next == NULL || _ckmem_corruption(*next, 0)) ROAR_DBG("buffer_add(buf=%p, next=%p) = ?", buf, next); ROAR_DBG("buffer_add(buf=%p, next=%p): *next=%p", buf, next, *next); if ( buf->flags & ROAR_BUFFER_FLAG_RING ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( buf == *next ) { ROAR_ERR("buffer_add(*): both pointer are of the same destination, This is a error in the application"); roar_err_set(ROAR_ERROR_INVAL); return -1; } while ( buf->next != NULL ) { ROAR_DBG("buffer_add(*): buf=%p, next=%p (len=%i)", buf, buf->next, buf->user_len); // ROAR_DBG("buffer_add(): buf=%p, buf->next=%p", buf, buf->next); buf = buf->next; deep++; if ( buf == *next ) { ROAR_ERR("buffer_add(*): Can not add buffer: loop detected at deep %u. This is a error in the application", deep); // why don't we return here? } } buf->next = *next; ROAR_DBG("buffer_add(*): adding buffer at deep %u", deep); *next = NULL; return 0; } int roar_buffer_moveintoqueue(struct roar_buffer ** buf, struct roar_buffer ** next) { if ( buf == NULL || next == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( *buf == NULL ) { *buf = *next; *next = NULL; return 0; } else { return roar_buffer_moveinto(*buf, next); } } int roar_buffer_get_next (struct roar_buffer * buf, struct roar_buffer ** next) { _ckbuf(0) *next = buf->next; return roar_buffer_ref(*next); } int roar_buffer_ring_new (struct roar_buffer ** buf, size_t len, int free_running) { struct roar_buffer * n; _ckbuf_free(0) if ( len == 0 ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } // just to be sure: *buf = NULL; if ( roar_buffer_new(&n, len) == -1 ) return -1; n->flags |= ROAR_BUFFER_FLAG_RING; if ( free_running ) n->flags |= ROAR_BUFFER_FLAG_FREE_RUNNING; n->meta.ring.read_pos = 0; n->meta.ring.write_pos = 0; memset(n->data, 0, n->len); *buf = n; return 0; } int roar_buffer_get_data (struct roar_buffer * buf, void ** data) { _ckbuf(data == NULL) *data = buf->user_data; return 0; } int roar_buffer_get_datalen(struct roar_buffer * buf, void ** data, size_t * len) { _ckbuf(0) if ( data != NULL ) *data = buf->user_data; if ( len != NULL ) *len = buf->user_len; return 0; } int roar_buffer_set_offset (struct roar_buffer * buf, size_t off) { _ckbuf(0) if ( off > buf->user_len ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } buf->user_len -= off; buf->user_data += off; return 0; } int roar_buffer_shift_out (struct roar_buffer ** buf, void * data, size_t * len) { size_t todo, cl; struct roar_buffer * cur; void * cd; _ckbuf_free(len == NULL || data == NULL); if ( *buf == NULL ) { ROAR_DBG("roar_buffer_shift_out(buf=%p, data=%p, len={%lu}) = -1 // Invalid pointer to buffer ring", buf, data, (unsigned long)len); roar_err_set(ROAR_ERROR_FAULT); return -1; } todo = *len; cur = *buf; *len = 0; while (todo && cur != NULL) { ROAR_DBG("roar_buffer_shift_out(*): todo=%u, cur=%p", (unsigned int) todo, cur); _ckmem_corruption(cur, 0); if ( roar_buffer_get_len(cur, &cl) == -1 ) return -1; if ( cl > todo ) { if ( roar_buffer_get_data(cur, &cd) == -1 ) return -1; cl = todo; memcpy(data, cd, cl); todo -= cl; data += cl; *len += cl; if ( roar_buffer_set_offset(cur, cl) == -1 ) return -1; } else { if ( roar_buffer_get_data(cur, &cd) == -1 ) return -1; memcpy(data, cd, cl); todo -= cl; data += cl; *len += cl; if ( roar_buffer_next(&cur) == -1 ) return -1; } /* if ( cur == NULL ) break; */ } *buf = cur; return 0; } int roar_buffer_set_meta (struct roar_buffer * buf, void * meta) { _ckbuf(0) buf->meta.vp = meta; return 0; } int roar_buffer_get_meta (struct roar_buffer * buf, void ** meta) { _ckbuf(meta == NULL) *meta = buf->meta.vp; return 0; } int roar_buffer_set_meta_i32(struct roar_buffer * buf, int32_t meta) { _ckbuf(0) buf->meta.i32 = meta; return 0; } int roar_buffer_get_meta_i32(struct roar_buffer * buf, int32_t * meta) { _ckbuf(meta == NULL) *meta = buf->meta.i32; return 0; } int roar_buffer_set_type (struct roar_buffer * buf, int type) { _ckbuf(0) switch (type) { case ROAR_VIO_DFT_RAW: case ROAR_VIO_DFT_PACKET: case ROAR_VIO_DFT_UNFRAMED: case ROAR_VIO_DFT_OGG_PACKET: case ROAR_VIO_DFT_OGG_PAGE: break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; } buf->type = type; return 0; } int roar_buffer_get_type (struct roar_buffer * buf, int * type) { _ckbuf(type == NULL) *type = buf->type; return 0; } int roar_buffer_set_len (struct roar_buffer * buf, size_t len) { size_t totlen; void * newbuf; size_t true_len; ROAR_DBG("roar_buffer_set_len(buf=%p, len=%lu) = ?", buf, (long unsigned int)len); _ckbuf(0) ROAR_DBG("roar_buffer_set_len(buf=%p, len=%lu) = ?", buf, (long unsigned int)len); // handle special case where user length is zero: if ( len && !buf->user_len ) { buf->user_data = buf->data; buf->user_len = buf->len; } ROAR_DBG("roar_buffer_set_len(buf=%p, len=%lu) = ?", buf, (long unsigned int)len); // calculate the true length of our buffer starting at buf->user_data. true_len = buf->len - (buf->user_data - buf->data); if ( len > true_len ) { ROAR_DBG("roar_buffer_set_len(buf=%p, len=%lu): We need to enlarge the buffer.", buf, (long unsigned int)len); // we can only enlage a buffer if it's one of our own memory segments if ( buf->flags & ROAR_BUFFER_FLAG_NOFREE ) { ROAR_DBG("roar_buffer_set_len(buf=%p, len=%lu) = -1 //error=NOTSUP", buf, (long unsigned int)len); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } totlen = (buf->len - buf->user_len) + len; newbuf = roar_mm_realloc(buf->data, totlen); if ( newbuf == NULL ) return -1; buf->user_data = newbuf + (buf->user_data - buf->data); buf->user_len = len; buf->data = newbuf; buf->len = totlen; } else { ROAR_DBG("roar_buffer_set_len(buf=%p, len=%lu): No need to enlarge the buffer.", buf, (long unsigned int)len); buf->user_len = len; } ROAR_DBG("roar_buffer_set_len(buf=%p, len=%lu) = 0", buf, (long unsigned int)len); return 0; } int roar_buffer_get_len (struct roar_buffer * buf, size_t * len) { _ckbuf(0) *len = buf->user_len; return 0; } int roar_buffer_set_flag (struct roar_buffer * buf, int flag, int reset) { _ckbuf(0) buf->flags |= flag; if ( reset ) buf->flags -= flag; return 0; } int roar_buffer_get_flag (struct roar_buffer * buf, int flag) { _ckbuf(0) return buf->flags & flag; } int roar_buffer_duplicate (struct roar_buffer * buf, struct roar_buffer ** copy) { struct roar_buffer * cur = buf; struct roar_buffer * new; void * od, * nd; int err; _ckbuf(copy == NULL) *copy = NULL; // TODO: This function does not handle ring buffers. // FIXME: This function does not error out in case of wrong buffer type in buf. // TODO: This function does not handle buffer meta data. while (cur != NULL) { if ( roar_buffer_new(&new, cur->user_len) == -1 ) { err = roar_error; roar_buffer_free(*copy); roar_err_set(err); return -1; } if ( *copy == NULL ) *copy = new; _LIBROAR_IGNORE_RET(roar_buffer_get_data(cur, &od)); _LIBROAR_IGNORE_RET(roar_buffer_get_data(new, &nd)); memcpy(nd, od, cur->user_len); if ( *copy != new ) { _LIBROAR_IGNORE_RET(roar_buffer_moveinto(*copy, &new)); } cur = cur->next; } return 0; } int roar_buffer_ring_stats (struct roar_buffer * buf, struct roar_buffer_stats * stats) { ROAR_DBG("roar_buffer_ring_stats(buf=%p, stats=%p) = ?", buf, stats); _ckbuf(0) ROAR_DBG("roar_buffer_ring_stats(buf=%p, stats=%p) = ?", buf, stats); stats->parts = 0; stats->bytes = 0; stats->memory_usage = 0; while (buf != NULL ) { stats->parts++; stats->bytes += buf->user_len; stats->memory_usage += buf->len + sizeof(struct roar_buffer); buf = buf->next; } return 0; } int roar_buffer_ring_read (struct roar_buffer * buf, void * data, size_t * len) { struct roar_buffer_ring * ring; size_t havelen; size_t done; size_t tmp; _ckbuf(len == NULL) if ( buf == NULL || len == NULL ) return -1; if ( data == NULL && *len != 0 ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } if ( *len == 0 ) return 0; // we may handle this later: if ( *len > buf->user_len ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) { if ( buf->meta.ring.read_pos >= buf->user_len ) buf->meta.ring.read_pos -= buf->user_len; if ( (*len + buf->meta.ring.read_pos) > buf->user_len ) { // wraped mode: memcpy(data, buf->user_data+buf->meta.ring.read_pos, buf->user_len - buf->meta.ring.read_pos); memcpy(data, buf->user_data, *len + buf->meta.ring.read_pos - buf->user_len); buf->meta.ring.read_pos += *len; buf->meta.ring.read_pos -= buf->user_len; return 0; } else { // unwarped mode: memcpy(data, buf->user_data+buf->meta.ring.read_pos, *len); buf->meta.ring.read_pos += *len; return 0; } } else { ring = &(buf->meta.ring); if ( ring->read_pos == ring->write_pos ) { *len = 0; return 0; } else if ( ring->read_pos < ring->write_pos ) { havelen = ring->write_pos - ring->read_pos; if ( havelen > *len ) havelen = *len; memcpy(data, buf->user_data+ring->read_pos, havelen); ring->read_pos += havelen; *len = havelen; return 0; } else { // write_pos < read_pos done = 0; // first pass: use data up to end of buffer havelen = buf->user_len - ring->read_pos; if ( havelen > *len ) havelen = *len; memcpy(data, buf->user_data+ring->read_pos, havelen); ring->read_pos += havelen; done += havelen; if ( ring->read_pos == buf->user_len ) { ring->read_pos = 0; } // second pass: use data from strat of buffer to write pointer if ( *len > done ) { tmp = *len - done; if ( roar_buffer_ring_read(buf, data+done, &tmp) == 0 ) { done += tmp; } } *len = done; return 0; } } roar_err_set(ROAR_ERROR_UNKNOWN); return -1; } int roar_buffer_ring_write (struct roar_buffer * buf, void * data, size_t * len) { struct roar_buffer_ring * ring; size_t havelen; size_t done; size_t tmp; ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len); _ckbuf(len == NULL) if ( data == NULL && *len != 0 ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } if ( *len == 0 ) return 0; // we may handle this later: if ( *len > buf->user_len ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) { if ( buf->meta.ring.write_pos >= buf->user_len ) buf->meta.ring.write_pos -= buf->user_len; if ( (*len + buf->meta.ring.write_pos) > buf->user_len ) { // wraped mode: memcpy(buf->user_data+buf->meta.ring.write_pos, data, buf->user_len - buf->meta.ring.write_pos); memcpy(buf->user_data, data, *len + buf->meta.ring.write_pos - buf->user_len); buf->meta.ring.write_pos += *len; buf->meta.ring.write_pos -= buf->user_len; return 0; } else { // unwarped mode: memcpy(buf->user_data+buf->meta.ring.write_pos, data, *len); buf->meta.ring.write_pos += *len; return 0; } } else { ring = &(buf->meta.ring); done = 0; ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p): write_pos=%u, read_pos=%u, user_len=%u", buf, data, len, (unsigned int)ring->write_pos, (unsigned int)ring->read_pos, (unsigned int)buf->user_len); if ( ring->write_pos >= ring->read_pos ) { ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len); havelen = buf->user_len - ring->write_pos; if ( ring->read_pos == 0 ) havelen--; if ( havelen > *len ) havelen = *len; memcpy(buf->user_data+ring->write_pos, data, havelen); done += havelen; ring->write_pos += havelen; if ( ring->write_pos == buf->user_len ) ring->write_pos = 0; if ( *len > done && ring->read_pos != 0 ) { tmp = *len - done; if ( roar_buffer_ring_write(buf, data+done, &tmp) == 0 ) { done += tmp; } } *len = done; ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len); return 0; } else { ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len); // test for buffer-is-full: if ( (ring->write_pos + 1) == ring->read_pos ) { *len = 0; ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len); return 0; } ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = ?", buf, data, len); havelen = ring->read_pos - ring->write_pos - 1; if ( havelen > *len ) havelen = *len; memcpy(buf->user_data+ring->write_pos, data, havelen); ring->write_pos += havelen; *len = havelen; ROAR_DBG("roar_buffer_ring_write(buf=%p, data=%p, len=%p) = 0", buf, data, len); return 0; } } roar_err_set(ROAR_ERROR_UNKNOWN); return -1; } int roar_buffer_ring_avail(struct roar_buffer * buf, size_t * readlen, size_t * writelen) { struct roar_buffer_ring * ring; size_t have; _ckbuf(0) if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } ring = &(buf->meta.ring); ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p) = ?", buf, readlen, writelen); if ( readlen != NULL ) { have = 0; if ( ring->write_pos >= ring->read_pos ) { have = ring->write_pos - ring->read_pos; } else { have = buf->user_len - ring->read_pos; have += ring->write_pos; have -= 1; } *readlen = have; ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p): readlen=%llu", buf, readlen, writelen, (unsigned long long int)have); } if ( writelen != NULL ) { have = 0; if ( ring->read_pos > ring->write_pos ) { have = ring->read_pos - ring->write_pos - 1; } else { have = buf->user_len - ring->write_pos; have += ring->read_pos; have -= 1; } *writelen = have; ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p): readlen=%llu", buf, readlen, writelen, (unsigned long long int)have); } ROAR_DBG("roar_buffer_ring_avail(buf=%p, readlen=%p, writelen=%p) = 0", buf, readlen, writelen); return 0; } int roar_buffer_ring_reset(struct roar_buffer * buf) { _ckbuf(0) if ( !(buf->flags & ROAR_BUFFER_FLAG_RING) ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } buf->meta.ring.read_pos = buf->meta.ring.write_pos = 0; return 0; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/caps.c������������������������������������������������������������������0000644�0001750�0001750�00000015452�12264733535�015224� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//caps.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" const struct roar_stds * libroar_libstds(void) { static const uint32_t std[] = { ROAR_STD_MAKE(ROAR_STDV_ROARAUDIO, 0, 0) // ra-msg-v0 }; static const struct roar_stds stds = {.stds_len = sizeof(std)/sizeof(*std), .stds = (uint32_t*)std}; return &stds; } int roar_caps_to_msg(struct roar_message * mes, struct roar_caps * caps, void ** data) { char * datap; size_t needlen = 4; if ( mes == NULL || caps == NULL ) return -1; needlen += caps->len; if ( needlen > sizeof(mes->data) ) { if ( data == NULL ) return -1; if ( (*data = roar_mm_malloc(needlen)) == NULL ) return -1; datap = *data; } else { datap = mes->data; } datap[0] = caps->version; datap[1] = caps->type; datap[2] = (caps->flags & 0xFF00) >> 8; datap[3] = caps->flags & 0xFF; if ( caps->len != 0 ) { memcpy(&(datap[4]), caps->data, caps->len); } mes->datalen = needlen; return 0; } int roar_caps_from_msg(struct roar_caps * caps, struct roar_message * mes, void * data) { char * datap; if ( mes == NULL || caps == NULL ) return -1; if ( data != NULL ) { datap = data; } else { datap = mes->data; } // versin check. if ( datap[0] != 0 || mes->datalen < 4 ) return -1; memset(caps, 0, sizeof(struct roar_caps)); caps->version = datap[0]; caps->type = datap[1]; caps->flags = (datap[2] << 8) | datap[3]; if ( mes->datalen == 4 ) { caps->data = NULL; caps->len = 0; } else { caps->data = &(datap[4]); caps->len = mes->datalen - 4; } return 0; } int roar_caps_stds(struct roar_connection * con, struct roar_stds ** out, struct roar_stds * in, int flags) { struct roar_message mes; struct roar_caps caps; void * data = NULL; char * data_char; size_t i; ROAR_DBG("roar_caps_stds(con=%p, out=%p, in=%p, flags=0x%.4x) = ?", con, out, in, flags); if ( flags == -1 ) flags = 0; if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( out != NULL ) flags |= ROAR_CF_REQUEST; if ( (flags & ROAR_CF_REQUEST) && out == NULL ) return -1; if ( in != NULL ) if ( in->stds_len == 0 ) in = NULL; memset(&caps, 0, sizeof(caps)); caps.version = 0; caps.type = ROAR_CT_STANDARDS; caps.flags = flags; memset(&mes, 0, sizeof(mes)); if ( in != NULL ) { // we use a hack here to avoid double alloc: // first pass the data in native byte order. // after we got a buffer swap in-buffer. caps.data = in->stds; caps.len = in->stds_len * 4; } if ( roar_caps_to_msg(&mes, &caps, &data) == -1 ) return -1; if ( in != NULL ) { if ( data == NULL ) { for (i = 0; i < in->stds_len; i++) { ((uint32_t*)mes.data)[i] = ROAR_HOST2NET32(((uint32_t*)mes.data)[i]); } } else { for (i = 0; i < in->stds_len; i++) { ((uint32_t*)data)[i] = ROAR_HOST2NET32(((uint32_t*)data)[i]); } } } mes.cmd = ROAR_CMD_CAPS; data_char = data; if ( roar_req(con, &mes, &data_char) == -1 ) return -1; data = data_char; if ( mes.cmd != ROAR_CMD_OK ) { if ( data != NULL ) roar_mm_free(data); return -1; } if ( roar_caps_from_msg(&caps, &mes, data) == -1 ) { if ( data != NULL ) roar_mm_free(data); return -1; } // check if response matches the request: if ( caps.version != 0 || caps.type != ROAR_CT_STANDARDS || (caps.len & 0x3) != 0 ) { if ( data != NULL ) roar_mm_free(data); return -1; } if ( out != NULL ) { *out = roar_stds_new(caps.len/4); if ( *out == NULL ) { if ( data != NULL ) roar_mm_free(data); return -1; } ROAR_DBG("roar_caps_stds(con=%p, out=%p, in=%p, flags=0x%.4x): (*out)->stds_len=%llu", con, out, in, flags, (long long unsigned int)(*out)->stds_len); for (i = 0; i < (*out)->stds_len; i++) { (*out)->stds[i] = ROAR_NET2HOST32(((uint32_t*)caps.data)[i]); ROAR_DBG("roar_caps_stds(con=%p, out=%p, in=%p, flags=0x%.4x): (*out)->stds[%llu] = 0x%.8x", con, out, in, flags, (long long unsigned int)i, (*out)->stds[i]); } } if ( data != NULL ) roar_mm_free(data); return 0; } struct roar_stds * roar_stds_new(size_t len) { struct roar_stds * ret; if ( len == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return NULL; } ret = roar_mm_malloc(sizeof(struct roar_stds)); if ( ret == NULL ) return NULL; memset(ret, 0, sizeof(struct roar_stds)); ret->stds_len = len; ret->stds = roar_mm_malloc(len*sizeof(uint32_t)); if ( ret->stds == NULL ) { roar_mm_free(ret); return NULL; } memset(ret->stds, 0, len*sizeof(uint32_t)); return ret; } int roar_stds_free(struct roar_stds * stds) { if ( stds == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( stds->stds != NULL ) roar_mm_free(stds->stds); roar_mm_free(stds); return 0; } static struct { const int vendor; const char * name; } _libroar_std_vendors[] = { {ROAR_STDV_ROARAUDIO, "RoarAudio"}, {ROAR_STDV_PROTO, "Protocols"}, {ROAR_STDV_RFC, "RFC"}, {-1, NULL} }; int roar_stds_str2vendor(const char * vendor) { int i; if ( vendor == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; _libroar_std_vendors[i].name != NULL; i++) if ( !strcasecmp(_libroar_std_vendors[i].name, vendor) ) return _libroar_std_vendors[i].vendor; roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_stds_vendor2str(const int vendor) { int i; for (i = 0; _libroar_std_vendors[i].name != NULL; i++) if ( _libroar_std_vendors[i].vendor == vendor ) return _libroar_std_vendors[i].name; roar_err_set(ROAR_ERROR_NOENT); return NULL; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/cdrom.c�����������������������������������������������������������������0000644�0001750�0001750�00000015215�12264733535�015377� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//cdrom.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define ROAR_CDROM_ERROR_NORETURN(format, args...) ROAR_ERR(format, ## args); ROAR_U_EXIT(3) #if BYTE_ORDER == BIG_ENDIAN #define ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT "--output-raw-big-endian" #elif BYTE_ORDER == LITTLE_ENDIAN #define ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT "--output-raw-little-endian" #endif #ifdef ROAR_TARGET_WIN32 #undef ROAR_HAVE_BIN_CDPARANOIA #endif pid_t roar_cdrom_run_cdparanoia (int cdrom, int data, int track, char * pos) { #if defined(ROAR_HAVE_BIN_CDPARANOIA) && defined(ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT) && defined(ROAR_HAVE_CDROM) char my_pos[32] = {0}; pid_t pid; int fh[2]; char * bin_cdparanoia = NULL, * dev_stdin = NULL; ROAR_DBG("roar_cdrom_run_cdparanoia(cdrom=%i, data=%i, track=%i, pos='%s') = ?", cdrom, data, track, pos); if ( cdrom == -1 || data == -1 || (track == -1 && pos == NULL) || (track != -1 && pos != NULL) ) return -1; if ( track != -1 ) { pos = my_pos; snprintf(pos, sizeof(my_pos), "%i", track); } if ( (pid = roar_fork(NULL)) == (pid_t)-1 ) { return -1; } if ( pid ) return pid; fh[0] = dup(cdrom); fh[1] = dup(data); if ( fh[0] == -1 || fh[1] == -1 ) { ROAR_CDROM_ERROR_NORETURN("Can not dup(): %s", strerror(errno)); } close(ROAR_STDIN); close(ROAR_STDOUT); // TODO: should I close some other handles? if ( dup2(fh[0], ROAR_STDIN) == -1 || dup2(fh[1], ROAR_STDOUT) == -1 ) { ROAR_CDROM_ERROR_NORETURN("Can not dup2(): %s", strerror(errno)); } // now close our backups: close(fh[0]); close(fh[1]); bin_cdparanoia = roar_libroar_get_path("bin-cdparanoia", 0, NULL, NULL); if ( bin_cdparanoia == NULL ) return -1; dev_stdin = roar_libroar_get_path("dev-stdin", 0, NULL, NULL); if ( dev_stdin == NULL ) { roar_mm_free_noerror(bin_cdparanoia); return -1; } execl(bin_cdparanoia, bin_cdparanoia, "--force-cdrom-device", dev_stdin, "-q", ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT, pos, "-", NULL); roar_mm_free(bin_cdparanoia); roar_mm_free(dev_stdin); ROAR_CDROM_ERROR_NORETURN("We are still alive after exec()!, very bad!, error was: %s", strerror(errno)); return -1; #else #ifndef ROAR_HAVE_BIN_CDPARANOIA ROAR_ERR("roar_cdrom_run_cdparanoia(*): ROAR_HAVE_BIN_CDPARANOIA not defined!"); #endif #ifndef ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT ROAR_ERR("roar_cdrom_run_cdparanoia(*): ROAR_CDROM_CDPARANOIA_OUTPUTFORMAT not defined!"); #endif ROAR_ERR("roar_cdrom_run_cdparanoia(cdrom=%i, data=%i, track=%i, pos='%s') = -1 // no cdparanoia support compiled in", cdrom, data, track, pos); return -1; #endif } int roar_cdrom_open (struct roar_connection * con, struct roar_cdrom * cdrom, const char * device, int mixer) { #ifdef ROAR_HAVE_CDROM int flags; if ( cdrom == NULL ) return -1; memset((void*)cdrom, 0, sizeof(struct roar_cdrom)); if ( device == NULL ) device = roar_cdromdevice(); if ( device == NULL ) return -1; strncpy(cdrom->device, device, ROAR_CDROM_MAX_DEVLEN); cdrom->con = con; // we do not care here if it is set or not as we can operate in local only mode cdrom->mixer = mixer; cdrom->stream = -1; cdrom->play_local = 1; cdrom->player = -1; if ( (cdrom->fh = open(cdrom->device, O_RDONLY, 0644)) == -1 ) return -1; #ifndef ROAR_TARGET_WIN32 if ( (flags = fcntl(cdrom->fh, F_GETFL, 0)) == -1 ) { close(cdrom->fh); cdrom->fh = -1; return -1; } flags |= FD_CLOEXEC; if ( fcntl(cdrom->fh, F_SETFL, flags) == -1 ) { close(cdrom->fh); cdrom->fh = -1; return -1; } #endif return 0; #else return -1; #endif } int roar_cdrom_close(struct roar_cdrom * cdrom) { #ifdef ROAR_HAVE_CDROM if ( cdrom == NULL ) return -1; roar_cdrom_stop(cdrom); // stop on close if ( cdrom->fh != -1 ) close(cdrom->fh); memset((void*)cdrom, 0, sizeof(struct roar_cdrom)); return 0; #else return -1; #endif } int roar_cdrom_stop (struct roar_cdrom * cdrom) { #ifdef ROAR_HAVE_CDROM int ret; if ( cdrom == NULL ) return -1; if ( cdrom->con == NULL ) return -1; if ( cdrom->stream == -1 ) return -1; if ( (ret = roar_kick(cdrom->con, ROAR_OT_STREAM, cdrom->stream)) == -1 ) { return -1; } #ifndef ROAR_TARGET_WIN32 if ( cdrom->player != -1 ) kill(cdrom->player, SIGINT); #else if ( cdrom->player != -1 ) { ROAR_ERR("roar_cdrom_stop(*): Can not kill player with pid %i, not supported on win32", cdrom->player); } #endif cdrom->player = -1; cdrom->stream = -1; return ret; #else return -1; #endif } int roar_cdrom_play (struct roar_cdrom * cdrom, int track) { #ifdef ROAR_HAVE_CDROM struct roar_vio_calls vio; struct roar_stream stream[1]; int stream_fh; if ( cdrom == NULL ) return -1; if ( cdrom->con == NULL ) return -1; if ( cdrom->stream != -1 ) { if ( roar_cdrom_stop(cdrom) == -1 ) return -1; } if ( cdrom->play_local ) { if ( roar_vio_simple_new_stream_obj(&vio, cdrom->con, stream, ROAR_CDROM_STREAMINFO, ROAR_DIR_PLAY, cdrom->mixer) == -1 ) { return -1; } if ( roar_vio_ctl(&vio, ROAR_VIO_CTL_GET_WRITE_FH, &stream_fh) == -1 ) { roar_vio_close(&vio); return -1; } if ( (cdrom->player = roar_cdrom_run_cdparanoia(cdrom->fh, stream_fh, track, NULL)) != -1 ) { cdrom->stream = stream->id; return 0; } roar_vio_close(&vio); return -1; } else { // no support for remote playback yet return -1; } #else return -1; #endif } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/client.c����������������������������������������������������������������0000644�0001750�0001750�00000010130�12264733535�015540� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//client.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_client_new (struct roar_client * client) { int i; if ( client == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(client, 0, sizeof(struct roar_client)); client->fh = -1; client->pid = -1; client->uid = -1; client->gid = -1; client->proto = ROAR_PROTO_ROARAUDIO; client->byteorder = ROAR_BYTEORDER_NETWORK; for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) client->streams[i] = -1; return 0; } int roar_client_set_fh (struct roar_client * client, int fh) { if ( client == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } client->fh = fh; return 0; } int roar_client_set_proto(struct roar_client * client, int proto, int byteorder) { if ( client == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } client->proto = proto; if ( byteorder != -1 ) { client->byteorder = byteorder; } else { switch (proto) { case ROAR_PROTO_ROARAUDIO: client->byteorder = ROAR_BYTEORDER_NETWORK; break; default: roar_err_set(ROAR_ERROR_INVAL); return -1; break; } } return 0; } int roar_client_pass (struct roar_connection * con, struct roar_client * client, uint16_t flags) { struct roar_message m; int16_t * d = (int16_t *)m.data; int confh; int i; if ( con == NULL || client == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_PASSFH; m.stream = -1; // client (non-stream) passs m.pos = 0; m.datalen = 4*2; d[0] = 0; // version d[1] = flags; d[2] = client->proto; d[3] = client->byteorder; for (i = 0; i < 4; i++) d[i] = ROAR_HOST2NET16(d[i]); if ( (confh = roar_get_connection_fh(con)) == -1 ) return -1; if ( roar_send_message(con, &m, NULL) == -1 ) { return -1; } if ( roar_socket_send_fh(confh, client->fh, NULL, 0) == -1 ) return -1; if ( roar_recv_message(con, &m, NULL) == -1 ) return -1; if ( m.cmd == ROAR_CMD_OK ) return 0; return -1; } int roar_client_exec (struct roar_connection * con, struct roar_client * client, uint16_t flags) { struct roar_message m; int16_t * d = (int16_t *)m.data; int i; if ( con == NULL || client == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_EXEC_STREAM; m.stream = -1; // client (non-stream) passs m.pos = 0; m.datalen = 4*2; d[0] = 0; // version d[1] = flags; d[2] = client->proto; d[3] = client->byteorder; for (i = 0; i < 4; i++) d[i] = ROAR_HOST2NET16(d[i]); if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; client->fh = roar_get_connection_fh(con); return 0; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/config.c����������������������������������������������������������������0000644�0001750�0001750�00000055233�12264733535�015544� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//config.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define LEN_AUTHFILE 1024 static struct roar_libroar_config_codec * roar_libroar_config_codec_get_conf(int32_t codec, int create, struct roar_libroar_config * config); struct roar_libroar_config * roar_libroar_get_config_ptr(void) { static struct roar_libroar_config config; static int inited = 0; static char authfile[LEN_AUTHFILE]; const char * home; if ( !inited ) { memset(&config, 0, sizeof(config)); #ifdef ROAR_SUPPORT_TRAP config.trap_policy = ROAR_TRAP_IGNORE; #endif config.opmode = ROAR_LIBROAR_CONFIG_OPMODE_NORMAL; config.server = NULL; config.authfile = NULL; config.forkapi = NULL; config.connect_internal = NULL; config.daemonimage = NULL; config.protocolversion = -1; // use default. home = roar_env_get_home(0); if ( home != NULL ) { snprintf(authfile, sizeof(authfile)-1, "%s/.roarauth", home); authfile[sizeof(authfile)-1] = 0; config.authfile = authfile; config.serversfile = NULL; } roar_random_salt_nonce(&config, sizeof(config)); inited++; } return &config; } struct roar_libroar_config * roar_libroar_get_config(void) { struct roar_libroar_config * config = roar_libroar_get_config_ptr(); static int inited = 0; const char * next; char * buf; if ( !inited ) { inited++; // we do this early so we can use ROAR_{DBG,INFO,WARN,ERR}() in roar_libroar_config_parse(). next = roar_env_get("ROAR_OPTIONS"); if ( next != NULL ) { if ( (buf = roar_mm_strdup(next)) != NULL ) { roar_libroar_config_parse(buf, " "); roar_mm_free(buf); } } } return config; } int roar_libroar_reset_config(void) { struct roar_libroar_config * config = roar_libroar_get_config_ptr(); if ( config->codecs.codec != NULL ) { roar_mm_free(config->codecs.codec); config->codecs.num = 0; } if ( config->x11.display != NULL ) roar_mm_free(config->x11.display); config->x11.display = NULL; if ( config->daemonimage != NULL ) roar_mm_free(config->daemonimage); config->daemonimage = NULL; return 0; } #define _P_FP(v) ((int)(atof((v))*256.0)) #define _P_INT(v) (atoi((v))) #define _P_BOOL(v) (*(v) == 'y' || *(v) == 'j' || *(v) == 't' || *(v) == '1' ? 1 : 0) static int roar_libroar_config_parse_codec(struct roar_libroar_config * config, char * txt) { struct roar_libroar_config_codec * codec_cfg; int32_t codec; char * codec_str, * option_str, * value_str; char * toksave = NULL; ROAR_DBG("roar_libroar_config_parse_codec(config=%p, txt='%s') = ?", config, txt); if ( config == NULL || txt == NULL ) return -1; ROAR_DBG("roar_libroar_config_parse_codec(config=%p, txt='%s') = ?", config, txt); codec_str = roar_mm_strtok_r(txt, ":", &toksave); if ( codec_str == NULL ) return -1; option_str = roar_mm_strtok_r(NULL, ":", &toksave); if ( option_str == NULL ) return -1; value_str = roar_mm_strtok_r(NULL, ":", &toksave); if ( value_str == NULL ) return -1; ROAR_DBG("roar_libroar_config_parse_codec(config=%p, txt='%s') = ?", config, txt); if ( (codec = roar_str2codec(codec_str)) == -1 ) { ROAR_WARN("roar_libroar_config_parse_codec(*): Unknown codec: %s", codec_str); return -1; } ROAR_DBG("roar_libroar_config_parse_codec(config=%p, txt='%s'): codec=%i", config, txt, codec); if ( (codec_cfg = roar_libroar_config_codec_get_conf(codec, 1, config)) == NULL ) return -1; ROAR_DBG("roar_libroar_config_parse_codec(config=%p, txt='%s'): codec=%i, codec_cfg=%p", config, txt, codec, codec_cfg); if ( !strcmp(option_str, "q") || !strcmp(option_str, "quality") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_Q; codec_cfg->q = _P_FP(value_str); } else if ( !strcmp(option_str, "complexity") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_COMPLEXITY; codec_cfg->complexity = _P_FP(value_str); } else if ( !strcmp(option_str, "dtx") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_DTX; codec_cfg->dtx = _P_BOOL(value_str); } else if ( !strcmp(option_str, "cc-max") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_MAX_CC; codec_cfg->max_cc = _P_INT(value_str); } else if ( !strcmp(option_str, "vbr") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_VBR; codec_cfg->vbr = _P_BOOL(value_str); } else if ( !strcmp(option_str, "mode") ) { if ( !strcmp(value_str, "nb") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_MODE; codec_cfg->mode = ROAR_LIBROAR_CONFIG_MODE_NB; } else if ( !strcmp(value_str, "wb") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_MODE; codec_cfg->mode = ROAR_LIBROAR_CONFIG_MODE_WB; } else if ( !strcmp(value_str, "uwb") ) { codec_cfg->para_set |= ROAR_LIBROAR_CONFIG_PSET_MODE; codec_cfg->mode = ROAR_LIBROAR_CONFIG_MODE_UWB; } else { ROAR_WARN("roar_libroar_config_parse_codec(*): Unknown codec mode: %s", value_str); return -1; } } else { ROAR_WARN("roar_libroar_config_parse_codec(*): Unknown codec option: %s", option_str); return -1; } return 0; } int roar_libroar_config_parse(char * txt, char * delm) { struct roar_libroar_config * config = roar_libroar_get_config_ptr(); ssize_t len; char * k, * v, * next = txt; while (next != NULL) { k = next; if ( delm == NULL ) { // no delm -> we have only one option next = NULL; } else { next = strstr(next, delm); } if ( next != NULL ) { *next = 0; next++; } ROAR_DBG("roar_libroar_config_parse(*): k='%s'", k); // strip leading spaces: while ( *k == ' ' ) k++; ROAR_DBG("roar_libroar_config_parse(*): k='%s'", k); // strip tailing new lions: len = roar_mm_strlen(k); if ( len != -1 ) for (len--; len && (k[len] == '\r' || k[len] == '\n'); len--) k[len] = 0; ROAR_DBG("roar_libroar_config_parse(*): k='%s'", k); // comments if ( *k == '#' ) continue; ROAR_DBG("roar_libroar_config_parse(*): k='%s'", k); // empty options: if ( *k == 0 ) continue; if ( (v = strstr(k, ":")) != NULL ) { *v = 0; v++; } ROAR_DBG("roar_libroar_config_parse(*): k='%s', v='%s'", k, v); if ( !strcmp(k, "workaround") ) { if ( !strcmp(v, "use-execed") ) { config->workaround.workarounds |= ROAR_LIBROAR_CONFIG_WAS_USE_EXECED; } else if ( !strcmp(v, "no-slp") ) { config->workaround.workarounds |= ROAR_LIBROAR_CONFIG_WAS_NO_SLP; } else { ROAR_WARN("roar_libroar_config_parse(*): Unknown workaround option: %s", v); } } else if ( !strcmp(k, "warning") || !strcmp(k, "warn") ) { if ( !strcmp(v, "sysio") ) { config->warnings.sysio = ROAR_WARNING_ALWAYS; } else if ( !strcmp(v, "obsolete") ) { config->warnings.obsolete = ROAR_WARNING_ALWAYS; } else if ( !strcmp(v, "all") ) { config->warnings.sysio = ROAR_WARNING_ALWAYS; config->warnings.obsolete = ROAR_WARNING_ALWAYS; } else { ROAR_WARN("roar_libroar_config_parse(*): Unknown warning option: %s", v); } } else if ( !strcmp(k, "opmode") ) { if ( !strcmp(v, "normal") ) { config->opmode = ROAR_LIBROAR_CONFIG_OPMODE_NORMAL; } else if ( !strcmp(v, "funny") ) { config->opmode = ROAR_LIBROAR_CONFIG_OPMODE_FUNNY; } else if ( !strcmp(v, "ms") ) { config->opmode = ROAR_LIBROAR_CONFIG_OPMODE_MS; } else { ROAR_WARN("roar_libroar_config_parse(*): Unknown opmode: %s", v); } #ifdef ROAR_SUPPORT_TRAP } else if ( !strcmp(k, "trap-policy") ) { if ( !strcmp(v, "ignore") ) { config->trap_policy = ROAR_TRAP_IGNORE; } else if ( !strcmp(v, "warn") ) { config->trap_policy = ROAR_TRAP_WARN; } else if ( !strcmp(v, "abort") ) { config->trap_policy = ROAR_TRAP_ABORT; #ifdef SIGKILL } else if ( !strcmp(v, "kill") ) { config->trap_policy = ROAR_TRAP_KILL; #endif #ifdef SIGSTOP } else if ( !strcmp(v, "stop") ) { config->trap_policy = ROAR_TRAP_STOP; #endif } else if ( !strcmp(v, "die") ) { config->trap_policy = ROAR_TRAP_DIE; } else { ROAR_WARN("roar_libroar_config_parse(*): Unknown trap policy: %s", v); } #endif } else if ( !strcmp(k, "force-rate") ) { config->info.rate = roar_str2rate(v); } else if ( !strcmp(k, "force-bits") ) { config->info.bits = roar_str2bits(v); } else if ( !strcmp(k, "force-channels") ) { config->info.channels = roar_str2channels(v); } else if ( !strcmp(k, "force-codec") ) { config->info.codec = roar_str2codec(v); } else if ( !strcmp(k, "codec") ) { if ( roar_libroar_config_parse_codec(config, v) == -1 ) { ROAR_WARN("roar_libroar_config_parse(*): Error parsing codec config option"); } } else if ( !strcmp(k, "set-server") ) { if ( roar_libroar_get_server() == NULL ) roar_libroar_set_server(v); } else if ( !strcmp(k, "set-authfile") ) { strncpy(config->authfile, v, LEN_AUTHFILE-1); config->authfile[LEN_AUTHFILE-1] = 0; } else if ( !strcmp(k, "x11-display") ) { if ( config->x11.display != NULL ) roar_mm_free(config->x11.display); config->x11.display = roar_mm_strdup(v); } else if ( !strcmp(k, "daemonimage") ) { if ( config->daemonimage != NULL ) roar_mm_free(config->daemonimage); config->daemonimage = roar_mm_strdup(v); } else if ( !strcmp(k, "serverflags") ) { if ( !strcmp(v, "nonblock") ) { config->serverflags |= ROAR_ENUM_FLAG_NONBLOCK; } else if ( !strcmp(v, "hardnonblock") ) { config->serverflags |= ROAR_ENUM_FLAG_HARDNONBLOCK; } else if ( !strcmp(v, "localonly") ) { config->serverflags |= ROAR_ENUM_FLAG_LOCALONLY; } else { ROAR_WARN("roar_libroar_config_parse(*): Unknown serverflag: %s", v); } } else if ( !strcmp(k, "protocolversion") ) { config->protocolversion = atoi(v); } else { ROAR_WARN("roar_libroar_config_parse(*): Unknown option: %s", k); } } roar_random_salt_nonce(&config, sizeof(config)); return 0; } struct roar_libroar_config_codec * roar_libroar_config_codec_get(int32_t codec, int create) { struct roar_libroar_config * config = roar_libroar_get_config(); return roar_libroar_config_codec_get_conf(codec, create, config); } static struct roar_libroar_config_codec * roar_libroar_config_codec_get_conf(int32_t codec, int create, struct roar_libroar_config * config) { size_t i; int need_new = 1; ROAR_DBG("roar_libroar_config_codec_get_conf(codec=%i, create=%i, config=%p) = ?", codec, create, config); if ( codec < 0 || create < 0 ) return NULL; ROAR_DBG("roar_libroar_config_codec_get_conf(codec=%i, create=%i, config=%p) = ?", codec, create, config); if ( config->codecs.num == 0 ) { // no match case: if ( !create ) return NULL; } else { for (i = 0; i < config->codecs.num; i++) { if ( config->codecs.codec[i].codec == (uint32_t)codec ) return &(config->codecs.codec[i]); if ( config->codecs.codec[i].codec == (uint32_t)-1 ) need_new = 0; } } ROAR_DBG("roar_libroar_config_codec_get_conf(codec=%i, create=%i, config=%p) = ?", codec, create, config); if ( !create ) return NULL; if ( !need_new ) { for (i = 0; i < config->codecs.num; i++) { if ( config->codecs.codec[i].codec == (uint32_t)-1 ) { memset(&(config->codecs.codec[i]), 0, sizeof(struct roar_libroar_config_codec)); config->codecs.codec[i].codec = codec; return &(config->codecs.codec[i]); } } } if ( config->codecs.num == 0 ) { config->codecs.codec = roar_mm_malloc(16*sizeof(struct roar_libroar_config_codec)); } else { config->codecs.codec = roar_mm_realloc(config->codecs.codec, (config->codecs.num+16)*sizeof(struct roar_libroar_config_codec)); } if ( config->codecs.codec == NULL ) return NULL; memset(&(config->codecs.codec[config->codecs.num]), 0, 16); for (i = config->codecs.num; i < (config->codecs.num+16); i++) { config->codecs.codec[i].codec = (uint32_t)-1; } i = config->codecs.num; config->codecs.num += 16; memset(&(config->codecs.codec[i]), 0, sizeof(struct roar_libroar_config_codec)); config->codecs.codec[i].codec = codec; return &(config->codecs.codec[i]); } int roar_libroar_set_server(const char * server) { roar_libroar_get_config_ptr()->server = server; return 0; } const char * roar_libroar_get_server(void) { return roar_libroar_get_config_ptr()->server; } int roar_libroar_set_forkapi(const struct roar_libroar_forkapi * api) { roar_libroar_get_config_ptr()->forkapi = api; return 0; } int roar_libroar_set_connect_internal(struct roar_vio_calls * (*func)(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout)) { roar_libroar_get_config_ptr()->connect_internal = func; return 0; } void roar_libroar_nowarn(void) { roar_libroar_get_config_ptr()->nowarncounter++; } void roar_libroar_warn(void) { struct roar_libroar_config * cfg = roar_libroar_get_config_ptr(); if ( cfg->nowarncounter == 0 ) { ROAR_WARN("roar_libroar_warn(): Re-Enabling already enabled warnings! (Application error?)"); return; } cfg->nowarncounter--; } static const struct pathinfo { const char * name; const char * path; const int with_product; // 0 = no, 1 = yes, 2 = just product. const int with_provider; } __paths[] = { // prefixes: {"prefix", ROAR_PREFIX, 0, 0}, {"prefix-bin", ROAR_PREFIX_BIN, 0, 0}, {"prefix-sbin", ROAR_PREFIX_SBIN, 0, 0}, {"prefix-lib", ROAR_PREFIX_LIB, 0, 0}, {"prefix-inc", ROAR_PREFIX_INC, 0, 0}, {"prefix-man", ROAR_PREFIX_MAN, 0, 0}, {"prefix-man1", ROAR_PREFIX_MAN "/man1", 0, 0}, {"prefix-man2", ROAR_PREFIX_MAN "/man2", 0, 0}, {"prefix-man3", ROAR_PREFIX_MAN "/man3", 0, 0}, {"prefix-man4", ROAR_PREFIX_MAN "/man4", 0, 0}, {"prefix-man5", ROAR_PREFIX_MAN "/man5", 0, 0}, {"prefix-man6", ROAR_PREFIX_MAN "/man6", 0, 0}, {"prefix-man7", ROAR_PREFIX_MAN "/man7", 0, 0}, {"prefix-man8", ROAR_PREFIX_MAN "/man8", 0, 0}, {"prefix-man9", ROAR_PREFIX_MAN "/man9", 0, 0}, {"prefix-pc", ROAR_PREFIX_PC, 0, 0}, {"prefix-ckport", ROAR_PREFIX_CKPORT, 0, 0}, {"prefix-sysconf", ROAR_PREFIX_SYSCONF, 2, 0}, {"prefix-dev", ROAR_PREFIX_DEV, 0, 0}, {"prefix-doc", ROAR_PREFIX_DOC, 2, 0}, {"prefix-tmp", ROAR_PREFIX_TMP, 0, 0}, {"prefix-var", ROAR_PREFIX_VAR, 0, 0}, {"prefix-cache", ROAR_PREFIX_CACHE, 2, 0}, {"prefix-data", ROAR_PREFIX_DATA, 2, 0}, {"prefix-lock", ROAR_PREFIX_LOCK, 0, 0}, {"prefix-log", ROAR_PREFIX_LOG, 0, 0}, {"prefix-mail", ROAR_PREFIX_MAIL, 0, 0}, {"prefix-run", ROAR_PREFIX_RUN, 0, 0}, {"prefix-spool", ROAR_PREFIX_SPOOL, 2, 0}, {"prefix-comp-libs", ROAR_PREFIX_COMP_LIBS, 0, 0}, {"prefix-comp-bins", ROAR_PREFIX_COMP_BINS, 0, 0}, {"prefix-plugins", ROAR_PREFIX_PLUGINS, 1, 1}, {"prefix-buildsystem", ROAR_PREFIX_BUILDSYSTEM, 0, 0}, // bins: {"bin-default-daemonimage", "roard", 0, 0}, #ifdef ROAR_HAVE_BIN_SH {"bin-sh", ROAR_HAVE_BIN_SH, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_OGG123 {"bin-ogg123", ROAR_HAVE_BIN_OGG123, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_FLAC {"bin-flac", ROAR_HAVE_BIN_FLAC, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_TIMIDITY {"bin-timidity", ROAR_HAVE_BIN_TIMIDITY, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_CDPARANOIA {"bin-cdparanoia", ROAR_HAVE_BIN_CDPARANOIA, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_GNUPLOT {"bin-gnuplot", ROAR_HAVE_BIN_GNUPLOT, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_SSH {"bin-ssh", ROAR_HAVE_BIN_SSH, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_PINENTRY {"bin-pinentry", ROAR_HAVE_BIN_PINENTRY, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_SSH_ASKPASS {"bin-ssh-askpass", ROAR_HAVE_BIN_SSH_ASKPASS, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_GTK_LED_ASKPASS {"bin-gtk-led-askpass", ROAR_HAVE_BIN_GTK_LED_ASKPASS, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_X11_SSH_ASKPASS {"bin-x11-ssh-askpass", ROAR_HAVE_BIN_X11_SSH_ASKPASS, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_GNOME_SSH_ASKPASS {"bin-gnome-ssh-askpass", ROAR_HAVE_BIN_GNOME_SSH_ASKPASS, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_GPG {"bin-gpg", ROAR_HAVE_BIN_GPG, 0, 0}, #endif #ifdef ROAR_HAVE_BIN_EJECT {"bin-eject", ROAR_HAVE_BIN_EJECT, 0, 0}, #endif // devices: {"dev-stdin", ROAR_PREFIX_DEV "/stdin", 0, 0}, {"dev-default-pwmled", ROAR_PREFIX_DEV "/ttyS0", 0, 0}, {"dev-default-dmx4linux", ROAR_PREFIX_DEV "/dmx", 0, 0}, #ifdef ROAR_DEFAULT_CDROM {"dev-default-cdrom", ROAR_DEFAULT_CDROM, 0, 0}, #endif #ifdef ROAR_DEFAULT_TTY {"dev-default-tty", ROAR_DEFAULT_TTY, 0, 0}, #endif #ifdef ROAR_DEFAULT_OSS_DEV {"dev-default-oss-dev", ROAR_DEFAULT_OSS_DEV, 0, 0}, #endif #ifdef ROAR_DEFAULT_OSS_MIX_DEV {"dev-default-oss-mix-dev", ROAR_DEFAULT_OSS_MIX_DEV, 0, 0}, #endif // proc: #ifdef ROAR_PROC_NET_DECNET {"proc-net-decnet", ROAR_PROC_NET_DECNET, 0, 0}, #endif #ifdef ROAR_PROC_NET_DECNET_NEIGH {"proc-net-decnet-neigh", ROAR_PROC_NET_DECNET_NEIGH, 0, 0}, #endif #ifdef ROAR_PROC_NET_ARP {"proc-net-arp", ROAR_PROC_NET_ARP, 0, 0}, #endif // sysconf: {"sysconf-hosts", ROAR_PREFIX_SYSCONF "/hosts", 0, 0}, {"sysconf-roarserver", ROAR_PREFIX_SYSCONF "/roarserver", 0, 0}, // special dirs: {"dir-nx-home", "/NX-HOME-DIR", 0, 0}, #ifdef ROAR_TARGET_WIN32 {"dir-win32-sucks", "/WIN32-SUCKS", 0, 0} #endif }; static int __product2path(char * path, size_t pathlen, int null_as_universal, const char * product, int type) { const char * c; const char * e; const char * s; const char * b; if ( product != NULL && !strcmp(product, "universal") ) { null_as_universal = 1; product = NULL; } if ( product == NULL ) { if ( null_as_universal ) { if ( type == 2 ) { snprintf(path, pathlen, "/universal"); } else { snprintf(path, pathlen, "/universal/universal"); } } else { path[0] = 0; } return 0; } b = strstr(product, " "); c = strstr(product, "<"); e = strstr(product, ">"); if ( b == NULL || c == NULL || e == NULL || c < b || e < c ) { roar_err_set(ROAR_ERROR_ILLSEQ); return -1; } c++; s = strstr(c, "/"); if ( type == 2 ) { snprintf(path, pathlen, "/%.*s", (int)(size_t)(b-product), product); } else if ( s == NULL ) { snprintf(path, pathlen, "/unreg-%.*s/%.*s", (int)(size_t)(e-c), c, (int)(size_t)(b-product), product); } else { snprintf(path, pathlen, "/%.*s-%.*s/%.*s", (int)(size_t)(s-c), c, (int)(size_t)(e-s-1), s+1, (int)(size_t)(b-product), product); } return 0; } static int __provider2path(char * path, size_t pathlen, const char * provider) { const char * c; const char * e; const char * s; if ( provider == NULL ) { path[0] = 0; return 0; } c = strstr(provider, "<"); e = strstr(provider, ">"); if ( c == NULL || e == NULL || e < c ) { roar_err_set(ROAR_ERROR_ILLSEQ); return -1; } c++; s = strstr(c, "/"); if ( s == NULL ) { snprintf(path, pathlen, "/unreg-%.*s", (int)(size_t)(e-c), c); } else { snprintf(path, pathlen, "/%.*s-%.*s", (int)(size_t)(s-c), c, (int)(size_t)(e-s-1), s+1); } return 0; roar_err_set(ROAR_ERROR_NOTSUP); return -1; } static const struct pathinfo * __lookup_path(const char * name) { size_t i; if ( name == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } for (i = 0; i < (sizeof(__paths)/sizeof(*__paths)); i++) if ( !strcmp(__paths[i].name, name) ) return &(__paths[i]); roar_err_set(ROAR_ERROR_NOENT); return NULL; } void __strip_double_slashes(char * p) { const char * in = p; for (; *in; in++, p++) { *p = *in; if ( *in == '/' ) for (; in[1] == '/'; in++); } *p = 0; } char * roar_libroar_get_path(const char * name, int null_as_universal, const char * product, const char * provider) { const struct pathinfo * path; char buf_product[384]; char buf_provider[384]; ssize_t len_prefix, len_product, len_provider; char * ret, * p; ROAR_DBG("roar_libroar_get_path(name='%s', null_as_universal=%i, product='%s', provider='%s') = ?", name, null_as_universal, product, provider); path = __lookup_path(name); if ( path == NULL ) return NULL; if ( ((null_as_universal || product != NULL) && !path->with_product) || (provider != NULL && !path->with_provider) || (!null_as_universal && product == NULL && provider != NULL) ) { roar_err_set(ROAR_ERROR_INVAL); return NULL; } if ( __product2path(buf_product, sizeof(buf_product), null_as_universal, product, path->with_product) == -1 ) return NULL; if ( __provider2path(buf_provider, sizeof(buf_provider), provider) == -1 ) return NULL; len_prefix = roar_mm_strlen(path->path); len_product = roar_mm_strlen(buf_product); len_provider = roar_mm_strlen(buf_provider); p = ret = roar_mm_malloc(len_prefix+len_product+len_provider+1); if ( ret == NULL ) return NULL; memcpy(p, path->path, len_prefix); p += len_prefix; if ( p[-1] == '/' ) p--; memcpy(p, buf_product, len_product); p += len_product; memcpy(p, buf_provider, len_provider); p += len_provider; *p = 0; __strip_double_slashes(ret); return ret; } const char * roar_libroar_get_path_static(const char * name) { const struct pathinfo * path; path = __lookup_path(name); if ( path == NULL ) return NULL; return path->path; } ssize_t roar_libroar_list_path(const char ** list, size_t len, size_t offset) { size_t i; ssize_t idx = 0; ROAR_DBG("roar_libroar_list_path(list=%p, len=%lu, offset=%lu) = ?", list, (long unsigned int)len, (long unsigned int)offset); if ( list == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( len == 0 ) return 0; if ( offset >= (sizeof(__paths)/sizeof(*__paths)) ) return 0; for (i = offset; idx < len && i < (sizeof(__paths)/sizeof(*__paths)); i++) { list[idx++] = __paths[i].name; } return idx; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/crc.c�������������������������������������������������������������������0000644�0001750�0001750�00000007050�12264733536�015041� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//crc.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define CRC24_POLY 0x01864CFBL #define CRC24_INIT 0x00B704CEL #define ADLER32_BASE 65521L #define ADLER32_INIT 1L uint32_t roar_crc24_add(uint32_t state, const void * data, size_t len) { const unsigned char * p = data; int i; if ( data == NULL ) return CRC24_INIT; for (; len; len--) { state ^= ((uint32_t)(*p++)) << 16; for (i = 0; i < 8; i++) { state <<= 1; if ( state & 0x01000000 ) state ^= CRC24_POLY; } } return state & 0x00FFFFFFL; } uint32_t roar_adler32_add(uint32_t state, const void * data, size_t len) { const unsigned char * p = data; uint32_t s1 = state & 0xFFFFL; uint32_t s2 = (state >> 16) & 0xFFFFL; size_t n; if ( data == NULL ) return ADLER32_INIT; for (n = 0; n < len; n++) { s1 = (s1 + p[n]) % ADLER32_BASE; s2 = (s2 + s1 ) % ADLER32_BASE; } return (s2 << 16) + s1; } int roar_hash_crc24_init(void * state) { uint32_t * self = state; *self = roar_crc24_init(); return 0; } int roar_hash_crc24_digest(void * state, void * digest, size_t * len) { uint32_t * self = state; unsigned char * out = digest; register uint32_t crc; if ( *len < 3 ) return -1; *len = 3; crc = *self; out[0] = ((crc & 0x00FF0000) >> 16) & 0xFF; out[1] = ((crc & 0x0000FF00) >> 8) & 0xFF; out[2] = ((crc & 0x000000FF) >> 0) & 0xFF; return 0; } int roar_hash_crc24_proc(void * state, const void * data, size_t len) { uint32_t * self = state; *self = roar_crc24_add(*self, data, len); return 0; } int roar_hash_adler32_init(void * state) { uint32_t * self = state; *self = roar_adler32_init(); return 0; } int roar_hash_adler32_digest(void * state, void * digest, size_t * len) { uint32_t * self = state; unsigned char * out = digest; register uint32_t crc; if ( *len < 4 ) return -1; *len = 4; crc = *self; out[0] = ((crc & 0xFF000000) >> 24) & 0xFF; out[1] = ((crc & 0x00FF0000) >> 16) & 0xFF; out[2] = ((crc & 0x0000FF00) >> 8) & 0xFF; out[3] = ((crc & 0x000000FF) >> 0) & 0xFF; return 0; } int roar_hash_adler32_proc(void * state, const void * data, size_t len) { uint32_t * self = state; *self = roar_adler32_add(*self, data, len); return 0; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/crypto.c����������������������������������������������������������������0000644�0001750�0001750�00000003764�12264733536�015622� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//crypto.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_LIBGCRYPT #include <gcrypt.h> #endif int roar_crypto_init (void) { static int inited = 0; if ( inited ) return 0; #ifdef ROAR_HAVE_LIBGCRYPT if ( !gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P) ) { ROAR_INFO("roar_crypto_init(void): libgcrypt not yet inited, initing it now.", ROAR_DBG_INFO_INFO); if ( !gcry_check_version(GCRYPT_VERSION) ) { ROAR_ERR("roar_crypto_init(void): libgcrypt version missmatch"); return -1; } // what about SECMEM? gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); } #endif inited = 1; return 0; } //ll ������������roaraudio-1.0beta11/libroar/ctl.c�������������������������������������������������������������������0000644�0001750�0001750�00000055170�12264733536�015062� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ctl.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_get_clientid (struct roar_connection * con) { struct roar_message mes; memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy! mes.cmd = ROAR_CMD_WHOAMI; mes.stream = -1; mes.datalen = 0; if ( roar_req(con, &mes, NULL) == -1 ) return -1; if ( mes.cmd != ROAR_CMD_OK ) return -1; if ( mes.datalen != 1 ) return -1; return mes.data[0]; } int roar_server_oinfo (struct roar_connection * con, struct roar_stream * s, int dir) { struct roar_message mes; memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy! mes.cmd = ROAR_CMD_SERVER_OINFO; if ( dir == -1 ) { mes.datalen = 0; } else { mes.datalen = 2; mes.data[0] = 0; mes.data[1] = dir; } if ( roar_req(con, &mes, NULL) == -1 ) return -1; if ( mes.cmd != ROAR_CMD_OK ) return -1; if ( roar_stream_m2s(s, &mes) == -1 ) return -1; return 0; } int roar_get_standby (struct roar_connection * con) { struct roar_message mes; memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy! mes.cmd = ROAR_CMD_GET_STANDBY; mes.stream = -1; mes.datalen = 0; if ( roar_req(con, &mes, NULL) == -1 ) return -1; if ( mes.cmd != ROAR_CMD_OK ) return -1; return ROAR_NET2HOST16(*((uint16_t*)mes.data)); } int roar_set_standby (struct roar_connection * con, int state) { struct roar_message mes; memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy! mes.cmd = ROAR_CMD_SET_STANDBY; mes.stream = -1; mes.datalen = 2; *((uint16_t*)mes.data) = ROAR_HOST2NET16((unsigned) state); if ( roar_req(con, &mes, NULL) == -1 ) return -1; if ( mes.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_terminate (struct roar_connection * con, int terminate) { struct roar_message mes; memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy! mes.cmd = ROAR_CMD_EXIT; mes.stream = -1; mes.datalen = 1; mes.data[0] = terminate; if ( roar_req(con, &mes, NULL) == -1 ) return -1; if ( mes.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_list_filtered(struct roar_connection * con, int * items, int max, int cmd, unsigned char filter, unsigned char cmp, uint32_t id) { struct roar_message m; memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy! roar_ctl_f2m(&m, filter, cmp, id); m.cmd = cmd; if ( roar_req(con, &m, NULL) == -1 ) return -1; return roar_ctl_m2ia(&m, items, max); } int roar_list (struct roar_connection * con, int * items, int max, int cmd) { return roar_list_filtered(con, items, max, cmd, ROAR_CTL_FILTER_ANY, ROAR_CTL_CMP_ANY, ROAR_CTL_FILTER_ANY); } int roar_get_client (struct roar_connection * con, struct roar_client * client, int id) { struct roar_message m; char * data = NULL; int ret; memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy! m.cmd = ROAR_CMD_GET_CLIENT; m.stream = -1; m.datalen = 1; m.data[0] = id; ROAR_DBG("roar_get_client(*): id = %i", id); if ( roar_req(con, &m, &data) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; ROAR_DBG("roar_get_client(*): got ok"); ret = roar_ctl_m2c2(&m, client, data); if ( data != NULL ) roar_mm_free(data); return ret; } int roar_get_stream (struct roar_connection * con, struct roar_stream * stream, int id) { struct roar_message m; memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy! m.cmd = ROAR_CMD_GET_STREAM; m.datalen = 1; m.data[0] = id; roar_err_set(ROAR_ERROR_UNKNOWN); if ( roar_req(con, &m, NULL) == -1 ) { roar_err_set(ROAR_ERROR_PROTO); return -1; } if ( m.cmd != ROAR_CMD_OK ) return -1; return roar_stream_m2s(stream, &m); } int roar_kick (struct roar_connection * con, int type, int id) { struct roar_message m; uint16_t * info = (uint16_t *) m.data; memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy! m.cmd = ROAR_CMD_KICK; m.datalen = 4; info[0] = ROAR_HOST2NET16(type); info[1] = ROAR_HOST2NET16(id); if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_set_vol (struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int channels, int mode) { struct roar_message m; uint16_t * info = (uint16_t *) m.data; int i; memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy! m.cmd = ROAR_CMD_SET_VOL; m.datalen = (3 + channels) * 2; m.stream = id; info[0] = ROAR_HOST2NET16(1); info[1] = ROAR_HOST2NET16(mixer->scale); info[2] = ROAR_HOST2NET16(mode); for (i = 0; i < channels; i++) info[i+3] = ROAR_HOST2NET16(mixer->mixer[i]); if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_get_vol (struct roar_connection * con, int id, struct roar_mixer_settings * mixer, int * channels) { struct roar_message m; uint16_t * info = (uint16_t *) m.data; int i; memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy! m.cmd = ROAR_CMD_GET_VOL; m.datalen = 2*2; m.stream = id; info[0] = ROAR_HOST2NET16(1); if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; if ( ROAR_NET2HOST16(info[0]) != 1 ) return -1; info[1] = ROAR_NET2HOST16(info[1]); if ( channels != NULL ) *channels = info[1]; if ( info[1] > ROAR_MAX_CHANNELS ) return -1; mixer->scale = ROAR_NET2HOST16(info[2]); mixer->rpg_mul = ROAR_NET2HOST16(info[3]); mixer->rpg_div = ROAR_NET2HOST16(info[4]); for (i = 0; i < info[1]; i++) mixer->mixer[i] = ROAR_NET2HOST16(info[i+5]); return 0; } // converts: *_m2*, *_*2m int roar_ctl_f2m (struct roar_message * m, unsigned char filter, unsigned char cmp, uint32_t id) { m->datalen = 7; m->data[0] = 0; m->data[1] = filter; m->data[2] = cmp; m->data[3] = (id & 0xFF000000LU) >> 24; m->data[4] = (id & 0x00FF0000LU) >> 16; m->data[5] = (id & 0x0000FF00LU) >> 8; m->data[6] = (id & 0x000000FFLU) >> 0; return 0; } int roar_ctl_m2f (struct roar_message * m, unsigned char * filter, unsigned char * cmp, uint32_t * id) { register uint32_t idreg; if ( m->datalen != 7 ) return -1; if ( m->data[0] != 0 ) { ROAR_DBG("roar_ctl_m2f(*): version %i not supported!", (int)m->data[0]); roar_err_set(ROAR_ERROR_NSVERSION); return -1; } *filter = m->data[1]; *cmp = m->data[2]; idreg = ((uint32_t)(unsigned char)m->data[3]) << 24; idreg |= ((uint32_t)(unsigned char)m->data[4]) << 16; idreg |= ((uint32_t)(unsigned char)m->data[5]) << 8; idreg |= ((uint32_t)(unsigned char)m->data[6]) << 0; *id = idreg; return 0; } int roar_filter_match (const unsigned cmp, const uint32_t a, const uint32_t b) { switch (cmp) { case ROAR_CTL_CMP_ANY: return 1; break; case ROAR_CTL_CMP_EQ: return a == b; break; case ROAR_CTL_CMP_NE: return a != b; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; } } int roar_ctl_ia2m (struct roar_message * m, int * data, size_t len) { size_t i; if ( len > LIBROAR_BUFFER_MSGDATA ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } m->datalen = len; for (i = 0; i < len; i++) m->data[i] = data[i]; return 0; } int roar_ctl_m2ia (struct roar_message * m, int * data, size_t len) { size_t i; if ( m->datalen > len ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } for (i = 0; i < m->datalen; i++) data[i] = m->data[i]; return m->datalen; } int roar_ctl_c2m2 (struct roar_message * m, struct roar_client * c, void ** data) { char * d; size_t cur = 0; int h; int i; int max_len; uint32_t pid; size_t nnode_len; size_t needed_len = 3 + 5*4 + 18 /* 18 = current max size for blob */; if ( c == NULL ) return -1; if ( data != NULL ) *data = NULL; max_len = strlen(c->name); needed_len += max_len; for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) if ( c->streams[i] != -1 ) needed_len++; if ( needed_len > sizeof(m->data) ) { if ( data == NULL ) { needed_len -= max_len; if ( needed_len > sizeof(m->data) ) { roar_panic(ROAR_FATAL_ERROR_CPU_FAILURE, "needed_len > sizeof(m->data) happend."); roar_err_set(ROAR_ERROR_BADCKSUM); return -1; } max_len = sizeof(m->data) - needed_len; needed_len = sizeof(m->data); d = m->data; } else { d = roar_mm_malloc(needed_len); if ( d == NULL ) return -1; *data = d; } } else { d = m->data; } d[cur++] = 0; // 0: Version d[cur++] = c->execed; // 1: execed h = 0; for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) if ( c->streams[i] != -1 ) d[cur+1+h++] = c->streams[i]; d[cur++] = h; // 2: num of streams cur += h; // TODO: add some code to check if this fits in the pkg // NOTE: add this code after we are sure how long this pkg will be // and fully decieded about this function. d[cur++] = max_len; strncpy(d+cur, c->name, max_len); cur += max_len; pid = ROAR_HOST2NET32(c->pid); memcpy(&(d[cur]), &pid, 4); cur += 4; pid = ROAR_HOST2NET32(c->uid); memcpy(&(d[cur]), &pid, 4); cur += 4; pid = ROAR_HOST2NET32(c->gid); memcpy(&(d[cur]), &pid, 4); cur += 4; pid = ROAR_HOST2NET32(c->proto); memcpy(&(d[cur]), &pid, 4); cur += 4; pid = ROAR_HOST2NET32(c->byteorder); memcpy(&(d[cur]), &pid, 4); cur += 4; if ( cur > needed_len ) { roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); } nnode_len = needed_len - cur; if ( roar_nnode_to_blob(&(c->nnode), &(d[cur]), &nnode_len) == 0 ) { cur += nnode_len; } if ( cur > needed_len ) { roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); } m->datalen = cur; return 0; } int roar_ctl_m2c2 (struct roar_message * m, struct roar_client * c, void * data) { char * d = data; uint32_t pid; size_t len; size_t cur; int i; if ( m == NULL || c == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( m->datalen == 0 ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } if ( d == NULL ) { if ( m->datalen > sizeof(m->data) ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } d = m->data; } ROAR_DBG("roar_ctl_m2c(*): got data!, len = %i", m->datalen); if ( d[0] != 0 ) { ROAR_DBG("roar_ctl_m2c(*): wrong version!"); roar_err_set(ROAR_ERROR_NSVERSION); return -1; } if ( m->datalen < 3 ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } ROAR_DBG("roar_ctl_m2c(*): have usable data!"); c->execed = d[1]; for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) c->streams[i] = -1; if ( d[2] < 0 || d[2] > ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT ) { roar_err_set(ROAR_ERROR_TOOMANYARGS); return -1; } for (i = 0; i < d[2]; i++) c->streams[i] = d[3+i]; cur = 3 + d[2]; // check length here! strncpy(c->name, d+cur+1, d[cur] > (sizeof(c->name)-1) ? sizeof(c->name)-1 : d[cur]); c->name[(size_t)d[cur] > (sizeof(c->name)-1) ? sizeof(c->name)-1 : (size_t)d[cur]] = 0; cur += d[cur] + 1; memcpy(&pid, &(d[cur]), 4); c->pid = ROAR_NET2HOST32(pid); cur += 4; memcpy(&pid, &(d[cur]), 4); c->uid = ROAR_NET2HOST32(pid); cur += 4; memcpy(&pid, &(d[cur]), 4); c->gid = ROAR_NET2HOST32(pid); cur += 4; if ( m->datalen >= cur+4 ) { memcpy(&pid, &(d[cur]), 4); c->proto = ROAR_NET2HOST32(pid); cur += 4; } else { c->proto = ROAR_PROTO_NONE; } if ( m->datalen >= cur+4 ) { memcpy(&pid, &(d[cur]), 4); c->byteorder = ROAR_NET2HOST32(pid); cur += 4; } else { c->byteorder = ROAR_BYTEORDER_UNKNOWN; } if ( m->datalen > cur ) { len = m->datalen - cur; if ( roar_nnode_from_blob(&(c->nnode), &(d[cur]), &len) == 0 ) { cur += len; } else { if ( roar_nnode_new(&(c->nnode), ROAR_SOCKET_TYPE_UNKNOWN) == -1 ) return -1; } } else { if ( roar_nnode_new(&(c->nnode), ROAR_SOCKET_TYPE_UNKNOWN) == -1 ) return -1; } return 0; } int roar_ctl_c2m (struct roar_message * m, struct roar_client * c) { return roar_ctl_c2m2(m, c, NULL); } int roar_ctl_m2c (struct roar_message * m, struct roar_client * c) { return roar_ctl_m2c2(m, c, NULL); } static struct { int id; const char * name; } _proto[] = { {ROAR_PROTO_NONE, "none"}, {ROAR_PROTO_ROARAUDIO, "RoarAudio"}, {ROAR_PROTO_ESOUND, "EsounD"}, {ROAR_PROTO_ESOUND, "ESD"}, // alias {ROAR_PROTO_AUTO, "(auto)"}, {ROAR_PROTO_HTTP, "http"}, {ROAR_PROTO_GOPHER, "gopher"}, {ROAR_PROTO_ICY, "ICY"}, {ROAR_PROTO_SIMPLE, "Simple"}, {ROAR_PROTO_RSOUND, "RSound"}, {ROAR_PROTO_RPLAY, "RPlay"}, {ROAR_PROTO_IRC, "IRC"}, {ROAR_PROTO_DCC, "DCC"}, {ROAR_PROTO_ECHO, "Echo"}, {ROAR_PROTO_DISCARD, "Discard"}, {ROAR_PROTO_WHOIS, "Whois"}, {ROAR_PROTO_FINGER, "Finger"}, {ROAR_PROTO_QUOTE, "quote"}, {ROAR_PROTO_DAYTIME, "daytime"}, {ROAR_PROTO_GAME, "game"}, {ROAR_PROTO_TELNET, "telnet"}, {ROAR_PROTO_DHCP, "dhcp"}, {ROAR_PROTO_SSH, "ssh"}, {ROAR_PROTO_TIME, "time"}, {ROAR_PROTO_RLOGIN, "rlogin"}, {ROAR_PROTO_RPLD, "rpld"}, {ROAR_PROTO_MPD, "mpd"}, {-1, NULL} }; int roar_str2proto (const char * proto) { size_t i; for (i = 0; _proto[i].id != -1; i++) if ( !strcasecmp(proto, _proto[i].name) ) return _proto[i].id; roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_proto2str (const int proto) { size_t i; roar_err_set(ROAR_ERROR_NONE); for (i = 0; _proto[i].id != -1; i++) if ( proto == _proto[i].id ) return _proto[i].name; roar_err_set(ROAR_ERROR_NOENT); return "(unknown)"; } int roar_str2byteorder (const char * byteorder) { if ( !strcasecmp(byteorder, "le") || !strcasecmp(byteorder, "little") || !strcasecmp(byteorder, "little endian") || !strcasecmp(byteorder, "1234") ) { return ROAR_BYTEORDER_LE; } else if ( !strcasecmp(byteorder, "be") || !strcasecmp(byteorder, "big") || !strcasecmp(byteorder, "big endian") || !strcasecmp(byteorder, "4321") ) { return ROAR_BYTEORDER_BE; } else if ( !strcasecmp(byteorder, "pdp") || !strcasecmp(byteorder, "pdp endian") ) { return ROAR_BYTEORDER_PDP; } else if ( !strcasecmp(byteorder, "network") || !strcasecmp(byteorder, "network byteorder") ) { return ROAR_BYTEORDER_NETWORK; } roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_byteorder2str (const int byteorder) { switch (byteorder) { case ROAR_BYTEORDER_LE: return "little endian"; break; case ROAR_BYTEORDER_BE: return "big endian"; break; case ROAR_BYTEORDER_PDP: return "pdp endian"; break; // case ROAR_BYTEORDER_NETWORK: return "network"; break; default: return "(unknown)"; } } // grep '^#define ROAR_OT_' roaraudio/proto.h | cut -d' ' -f2 | sed 's/^\(ROAR_OT_\)\(.*\)$/ {\1\2, "\2"},/' static struct { const int ot; const char * name; } _libroar_ot[] = { {ROAR_OT_CLIENT, "client"}, {ROAR_OT_STREAM, "stream"}, {ROAR_OT_SOURCE, "source"}, {ROAR_OT_SAMPLE, "sample"}, {ROAR_OT_OUTPUT, "output"}, {ROAR_OT_MIXER, "mixer"}, {ROAR_OT_BRIDGE, "bridge"}, {ROAR_OT_LISTEN, "listen"}, {ROAR_OT_ACTION, "action"}, {ROAR_OT_MSGQUEUE, "msgqueue"}, {ROAR_OT_MSGBUS, "msgbus"}, {-1, NULL} }; int roar_str2ot (const char * ot) { int i; for (i = 0; _libroar_ot[i].ot != -1; i++) if ( !strcasecmp(ot, _libroar_ot[i].name) ) return _libroar_ot[i].ot; roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_ot2str (const int ot) { int i; for (i = 0; _libroar_ot[i].ot != -1; i++) if ( _libroar_ot[i].ot == ot ) return _libroar_ot[i].name; roar_err_set(ROAR_ERROR_NOENT); return NULL; } int roar_conv_volume (struct roar_mixer_settings * dst, struct roar_mixer_settings * src, int dstchans, int srcchans) { struct roar_mixer_settings lsrc; int i; uint_least32_t s; if ( dst == NULL || src == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( dstchans < 0 || srcchans < 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( dstchans == srcchans ) { if ( dst == src ) return 0; memcpy(dst, src, sizeof(struct roar_mixer_settings)); return 0; } if ( dst == src ) { memcpy(&lsrc, src, sizeof(lsrc)); src = &lsrc; } // sepcal handling for N->1: if ( dstchans == 1 ) { s = 0; for (i = 0; i < srcchans; i++) s += src->mixer[i]; dst->mixer[0] = s / srcchans; } else { switch (srcchans) { case 1: for (i = 0; i < dstchans; i++) dst->mixer[i] = src->mixer[0]; break; case 2: switch (dstchans) { case 3: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = (src->mixer[0] + src->mixer[1]) / 2; break; case 4: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[0]; dst->mixer[3] = src->mixer[1]; break; case 5: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = (src->mixer[0] + src->mixer[1]) / 2; dst->mixer[3] = src->mixer[0]; dst->mixer[4] = src->mixer[1]; break; case 6: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = (src->mixer[0] + src->mixer[1]) / 2; dst->mixer[3] = dst->mixer[2]; dst->mixer[4] = src->mixer[0]; dst->mixer[5] = src->mixer[1]; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } break; case 3: switch (dstchans) { case 2: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; break; case 4: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[0]; dst->mixer[3] = src->mixer[1]; break; case 5: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[2]; dst->mixer[3] = src->mixer[0]; dst->mixer[4] = src->mixer[1]; break; case 6: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[2]; dst->mixer[3] = src->mixer[2]; dst->mixer[4] = src->mixer[0]; dst->mixer[5] = src->mixer[1]; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } break; case 4: switch (dstchans) { case 2: dst->mixer[0] = (src->mixer[0] + src->mixer[2]) / 2; dst->mixer[1] = (src->mixer[1] + src->mixer[3]) / 2; break; case 3: dst->mixer[0] = (src->mixer[0] + src->mixer[2]) / 2; dst->mixer[1] = (src->mixer[1] + src->mixer[3]) / 2; dst->mixer[2] = (dst->mixer[0] + dst->mixer[1]) / 2; break; case 5: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = (src->mixer[0] + src->mixer[2] + src->mixer[1] + src->mixer[3]) / 4; dst->mixer[3] = src->mixer[2]; dst->mixer[4] = src->mixer[3]; break; case 6: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = (src->mixer[0] + src->mixer[2] + src->mixer[1] + src->mixer[3]) / 4; dst->mixer[3] = dst->mixer[2]; dst->mixer[4] = src->mixer[2]; dst->mixer[5] = src->mixer[3]; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } break; case 5: switch (dstchans) { case 2: dst->mixer[0] = (src->mixer[0] + src->mixer[3]) / 2; dst->mixer[1] = (src->mixer[1] + src->mixer[4]) / 2; break; case 3: dst->mixer[0] = (src->mixer[0] + src->mixer[3]) / 2; dst->mixer[1] = (src->mixer[1] + src->mixer[4]) / 2; dst->mixer[2] = src->mixer[2]; break; case 4: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[3]; dst->mixer[3] = src->mixer[4]; break; case 6: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[2]; dst->mixer[3] = src->mixer[2]; dst->mixer[4] = src->mixer[3]; dst->mixer[5] = src->mixer[4]; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } break; case 6: switch (dstchans) { case 2: dst->mixer[0] = (src->mixer[0] + src->mixer[4]) / 2; dst->mixer[1] = (src->mixer[1] + src->mixer[5]) / 2; break; case 3: dst->mixer[0] = (src->mixer[0] + src->mixer[4]) / 2; dst->mixer[1] = (src->mixer[1] + src->mixer[5]) / 2; dst->mixer[2] = src->mixer[2]; break; case 4: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[4]; dst->mixer[3] = src->mixer[5]; break; case 5: dst->mixer[0] = src->mixer[0]; dst->mixer[1] = src->mixer[1]; dst->mixer[2] = src->mixer[2]; dst->mixer[3] = src->mixer[4]; dst->mixer[4] = src->mixer[5]; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } } dst->scale = src->scale; dst->rpg_mul = src->rpg_mul; dst->rpg_div = src->rpg_div; return 0; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/debug.c�����������������������������������������������������������������0000644�0001750�0001750�00000015637�12264733536�015372� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//debug.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static int roar_debug_stderr_mode = ROAR_DEBUG_MODE_SYSIO; static int roar_debug_stderr_fh = ROAR_STDERR; static struct roar_vio_calls * roar_debug_stderr_vio = NULL; void roar_debug_warn_sysio_real(char * func, char * newfunc, char * info) { struct roar_libroar_config * config = roar_libroar_get_config(); if ( !roar_libroar_iswarn(config) ) return; if ( config->warnings.sysio == ROAR_WARNING_ALWAYS ) { if ( newfunc == NULL ) { ROAR_WARN("%s(*): This function is obsolete. %s", func, info == NULL ? "" : info); } else { ROAR_WARN("%s(*): This function is obsolete. Please use %s(...). %s", func, newfunc, info == NULL ? "" : info); } } } void roar_debug_warn_obsolete_real(char * func, char * newfunc, char * info) { struct roar_libroar_config * config = roar_libroar_get_config(); if ( !roar_libroar_iswarn(config) ) return; if ( config->warnings.obsolete == ROAR_WARNING_ALWAYS ) { if ( newfunc == NULL ) { ROAR_WARN("%s(*): This function is obsolete. %s", func, info == NULL ? "" : info); } else { ROAR_WARN("%s(*): This function is obsolete. Please use %s(...). %s", func, newfunc, info == NULL ? "" : info); } } } void roar_debug_bin_obsolete(const char * progname, const char * newprog, const char * info) { if ( info == NULL ) info = ""; if ( newprog == NULL ) { roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, 0, progname, ROAR_DBG_PREFIX, "This program is obsolete and will be removed soon. %s", info); } else { roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, 0, progname, ROAR_DBG_PREFIX, "This program is obsolete and will be removed soon. Please use %s. %s", newprog, info); } } void roar_debug_option_obsolete(const char * progname, const char * option, const char * newopt, const char * info) { if ( info == NULL ) info = ""; if ( newopt == NULL ) { roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, 0, progname, ROAR_DBG_PREFIX, "The option \"%s\" is obsolete and will be removed soon. %s", option, info); } else { roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, 0, progname, ROAR_DBG_PREFIX, "The option \"%s\" is obsolete and will be removed soon. Please use \"%s\". %s", option, newopt, info); } } void roar_debug_set_stderr_fh(int fh) { roar_debug_stderr_fh = fh; } void roar_debug_set_stderr_vio(struct roar_vio_calls * vio) { roar_debug_stderr_vio = vio; } void roar_debug_set_stderr_mode(int mode) { roar_debug_stderr_mode = mode; } struct roar_vio_calls * roar_debug_get_stderr(void) { static struct roar_vio_calls STDERR; switch (roar_debug_stderr_mode) { case ROAR_DEBUG_MODE_SYSIO: if ( roar_debug_stderr_fh == -1 ) return NULL; roar_vio_open_fh(&STDERR, roar_debug_stderr_fh); return &STDERR; break; case ROAR_DEBUG_MODE_VIO: return roar_debug_stderr_vio; break; default: return NULL; break; } } // NOTE: This function MUST NOT alter RA's error values nor errno! void roar_debug_msg_simple(const char *format, ...) { struct roar_vio_calls * vio; va_list ap; int ret; char buf[8192]; #ifdef ROAR_HAVE_SYSLOG size_t len; #endif int _ra_error = roar_error; int _sys_error = errno; vio = roar_debug_get_stderr(); va_start(ap, format); ret = vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); buf[sizeof(buf)-1] = 0; if ( vio != NULL ) { _LIBROAR_IGNORE_RET(roar_vio_write(vio, buf, ret)); roar_vio_sync(vio); } else { switch (roar_debug_stderr_mode) { #ifdef ROAR_HAVE_SYSLOG case ROAR_DEBUG_MODE_SYSLOG: // strip \n if needed for syslog: len = strlen(buf); if ( buf[len-1] == '\n' ) buf[len-1] = 0; syslog(LOG_ERR, "%s", buf); // bad to use some defaults break; #endif default: // do nothing. break; } } roar_error = _ra_error; errno = _sys_error; } void roar_debug_msg(int type, unsigned long int line, const char * file, const char * prefix, const char * format, ...) { struct roar_vio_calls * vio; va_list ap; char buf[8192]; char * bufp = buf; char * typename; int ret; #ifdef ROAR_HAVE_SYSLOG int priority; #endif size_t len; struct roar_error_state error_state; roar_err_store(&error_state); switch (type) { case ROAR_DEBUG_TYPE_ERROR: typename = "Error"; break; case ROAR_DEBUG_TYPE_WARNING: typename = "Warning"; break; case ROAR_DEBUG_TYPE_INFO: typename = "Info"; break; case ROAR_DEBUG_TYPE_DEBUG: typename = "Debug"; break; default: typename = "Unknown Type"; break; } ret = snprintf(buf, sizeof(buf), "(%s: %s:%lu): %s: ", prefix, file, line, typename); if ( ret > 0 && ret < (int)sizeof(buf) ) { bufp += ret; } else { ret = 0; } len = ret; va_start(ap, format); ret = vsnprintf(bufp, sizeof(buf)-ret, format, ap); va_end(ap); buf[sizeof(buf)-1] = 0; len += ret; switch (roar_debug_stderr_mode) { case ROAR_DEBUG_MODE_SYSIO: case ROAR_DEBUG_MODE_VIO: if ( (vio = roar_debug_get_stderr()) == NULL ) { roar_err_restore(&error_state); return; } _LIBROAR_IGNORE_RET(roar_vio_write(vio, buf, len)); _LIBROAR_IGNORE_RET(roar_vio_write(vio, "\n", 1)); roar_vio_sync(vio); break; #ifdef ROAR_HAVE_SYSLOG case ROAR_DEBUG_MODE_SYSLOG: switch (type) { case ROAR_DEBUG_TYPE_ERROR: priority = LOG_ERR; break; case ROAR_DEBUG_TYPE_WARNING: priority = LOG_WARNING; break; case ROAR_DEBUG_TYPE_INFO: priority = LOG_INFO; break; case ROAR_DEBUG_TYPE_DEBUG: priority = LOG_DEBUG; break; default: priority = LOG_ERR; break; } syslog(priority, "%s", buf); break; #endif } roar_err_restore(&error_state); } //ll �������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/empty.c�����������������������������������������������������������������0000644�0001750�0001750�00000002660�12264733537�015433� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//*.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2013-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" //ll ��������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/enumdev.c���������������������������������������������������������������0000644�0001750�0001750�00000024356�12264733537�015746� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//enumdev.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" // TODO: we should put all the data in one big alloced block. static int _test_server(struct roar_server * c, int flags) { struct roar_connection con; struct roar_server_info * info; int checked = 0; if ( c->server == NULL ) return -1; if ( flags & ROAR_ENUM_FLAG_NONBLOCK ) return 0; ROAR_DBG("_test_server(c=%p{.server='%s', ...}, flags=0x%.4X) = ?", c, c->server, flags); roar_libroar_nowarn(); if ( roar_connect(&con, c->server, 0, 0) == -1 ) { roar_libroar_warn(); return -1; } roar_libroar_warn(); ROAR_DBG("_test_server(c=%p{.server='%s', ...}, flags=0x%.4X) = ?", c, c->server, flags); if ( (flags & ROAR_ENUM_FLAG_DESC) || (flags & ROAR_ENUM_FLAG_LOCATION) ) { info = roar_server_info(&con); if ( info != NULL ) { checked = 1; if ( info->location != NULL ) c->location = roar_mm_strdup(info->location); if ( info->description != NULL ) c->description = roar_mm_strdup(info->description); roar_server_info_free(info); } } ROAR_DBG("_test_server(c=%p{.server='%s', ...}, flags=0x%.4X) = ?", c, c->server, flags); // make sure we get at least a NOOP from the server to detect protocol mismatch. if ( !checked ) { if ( roar_noop(&con) != 0 ) { roar_disconnect(&con); return -1; } } roar_disconnect(&con); ROAR_DBG("_test_server(c=%p{.server='%s', ...}, flags=0x%.4X) = 0", c, c->server, flags); return 0; } #define _add(x) if ( (x) != NULL ) servers[ret++] = roar_mm_strdup((x)) static ssize_t _esl_defaults(int flags, int dir, int socktype, char ** servers, size_t maxlen) { #ifdef ROAR_HAVE_LIBX11 struct roar_x11_connection * x11con; #endif ssize_t ret = 0; const char * new; char buf[1024]; #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) int i; #endif char * ssh_buf, * tmp; (void)flags, (void)dir, (void)socktype; if ( maxlen < 12 ) return -1; // We can not yet test if those servers are local or reachable via network so // we skip them for now. // TODO: test those servers. if ( !(flags & ROAR_ENUM_FLAG_LOCALONLY) ) { new = roar_libroar_get_server(); _add(new); new = roar_env_get("ROAR_SERVER"); _add(new); #ifdef ROAR_HAVE_LIBX11 if ( (x11con = roar_x11_connect(NULL)) != NULL ) { new = roar_x11_get_prop(x11con, "ROAR_SERVER"); _add(new); roar_x11_disconnect(x11con); } #endif new = roar_env_get("SSH_CLIENT"); if ( new == NULL ) new = roar_env_get("SSH_CONNECTION"); if ( new != NULL ) { ssh_buf = roar_mm_strdup(new); if ( ssh_buf != NULL ) { tmp = strstr(ssh_buf, " "); if ( tmp == NULL ) { // invalid format. roar_mm_free(ssh_buf); } else { *tmp = 0; servers[ret++] = ssh_buf; } } } #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) tmp = roar_libroar_get_path("sysconf-roarserver", 0, NULL, NULL); if ( tmp != NULL ) { if ( (i = readlink(tmp, buf, sizeof(buf)-1)) != -1 ) { buf[i] = 0; _add(buf); } roar_mm_free(tmp); } #endif } if ( (new = roar_env_get_home(0)) != NULL ) { snprintf(buf, sizeof(buf)-1, "%s/%s", new, ROAR_DEFAULT_SOCK_USER); buf[sizeof(buf)-1] = 0; _add(buf); } servers[ret++] = roar_mm_strdup(ROAR_DEFAULT_SOCK_GLOBAL); servers[ret++] = roar_mm_strdup(ROAR_DEFAULT_HOST); servers[ret++] = roar_mm_strdup("::" ROAR_DEFAULT_OBJECT); servers[ret++] = roar_mm_strdup("+abstract"); servers[ret++] = roar_mm_strdup("/tmp/muroard"); servers[ret++] = roar_mm_strdup("/dev/roar"); return ret; } static ssize_t _esl_slp(int flags, int dir, int socktype, char ** servers, size_t maxlen) { struct roar_libroar_config * config = roar_libroar_get_config(); struct roar_slp_cookie cookie; int offset; char * url; size_t i; ssize_t ret = 0; if ( config->workaround.workarounds & ROAR_LIBROAR_CONFIG_WAS_NO_SLP ) return 0; if ( roar_slp_cookie_init(&cookie, NULL) == -1 ) return -1; if ( roar_slp_search(&cookie, ROAR_SLP_URL_TYPE) == -1 ) return -1; if ( cookie.matchcount == 0 ) return -1; ROAR_DBG("_esl_slp(*): cookie.matchcount=%i", (int)cookie.matchcount); for (i = 0; i < (size_t)cookie.matchcount && (ssize_t)maxlen > ret; i++) { url = cookie.match[i].url; ROAR_DBG("_esl_slp(*): cookie.match[%i].url='%s'", (int)i, url); offset = 0; if ( !strncmp(url, ROAR_SLP_URL_TYPE "://", ROAR_SLP_URL_TYPE_LEN + 3) ) offset = ROAR_SLP_URL_TYPE_LEN + 3; ROAR_DBG("_esl_slp(*): url=%p, offset=%i", url, offset); url = &(url[offset]); ROAR_DBG("_esl_slp(*): url='%s'", url); if ( *url == 0 ) continue; _add(url); } return ret; } #ifdef ROAR_HAVE_FOPEN static ssize_t _esl_neighbours(int flags, int dir, int socktype, char ** servers, size_t maxlen) { ssize_t ret = 0; char buf[1024]; FILE * inp; size_t i; char * delm; const struct { const char * file; const char * suffix; const size_t skip; } *f, files[] = { #ifdef ROAR_PROC_NET_DECNET_NEIGH {ROAR_PROC_NET_DECNET_NEIGH, "::", 1}, #endif #ifdef ROAR_PROC_NET_ARP {ROAR_PROC_NET_ARP, NULL, 1}, #endif // {roar_libroar_get_path_static("sysconf-hosts"), NULL, 0}, {NULL, NULL, 0} }; (void)flags, (void)dir, (void)socktype; for (f = &(files[0]); f->file != NULL; f++) { if ( (inp = fopen(f->file, "r")) == NULL ) continue; for (i = 0; i < f->skip; i++) { if ( fgets(buf, sizeof(buf), inp) == NULL ) { // bad error... fclose(inp); return ret; } } while (ret < (ssize_t)maxlen && fgets(buf, sizeof(buf), inp) != NULL) { // skip comments and empty lions if ( buf[0] == '#' || buf[0] == '\0' ) continue; // ensure we have a tailing \0. buf[sizeof(buf)-1] = 0; delm = strstr(buf, " "); if ( delm == NULL ) delm = strstr(buf, "\t"); // does it look like a correctly formated lion? // we may remove this check or relax it later. if ( delm == NULL ) continue; *delm = 0; if ( f->suffix != NULL ) { if ( (roar_mm_strlen(buf) + roar_mm_strlen(f->suffix) + 1) > sizeof(buf) ) continue; roar_mm_strscat(buf, f->suffix); } // work around a bug in Linux kernel which always reports node 0.2 to be up. if ( !strcmp(buf, "0.2::") ) continue; _add(buf); } fclose(inp); if ( ret == (ssize_t)maxlen ) break; } return ret; } #endif struct locmed { int supflags; ssize_t (*func)(int flags, int dir, int socktype, char ** servers, size_t maxlen); }; static struct locmed _libroar_locmod[] = { {ROAR_ENUM_FLAG_NONBLOCK|ROAR_ENUM_FLAG_HARDNONBLOCK|ROAR_ENUM_FLAG_LOCALONLY, _esl_defaults}, {ROAR_ENUM_FLAG_NONE, _esl_slp}, #ifdef ROAR_HAVE_FOPEN {ROAR_ENUM_FLAG_NONBLOCK, _esl_neighbours} #endif }; struct roar_server * roar_enum_servers(int flags, int dir, int socktype) { struct roar_libroar_config * config = roar_libroar_get_config(); struct roar_server * ret = NULL; struct roar_server * c; char * servers[64]; size_t have = 1; size_t i, cp, unic; ssize_t r; int testflags; int is_uniq; flags |= config->serverflags; testflags = flags; if ( flags & ROAR_ENUM_FLAG_HARDNONBLOCK ) flags |= ROAR_ENUM_FLAG_NONBLOCK; if ( testflags & ROAR_ENUM_FLAG_DESC ) testflags -= ROAR_ENUM_FLAG_DESC; if ( testflags & ROAR_ENUM_FLAG_LOCATION ) testflags -= ROAR_ENUM_FLAG_LOCATION; for (i = 0; i < sizeof(_libroar_locmod)/sizeof(*_libroar_locmod); i++) { if ( (_libroar_locmod[i].supflags & testflags) == testflags ) { r = _libroar_locmod[i].func(flags, dir, socktype, &(servers[have-1]), (sizeof(servers)/sizeof(*servers)) - have); if ( r > 0 ) have += r; } } ret = roar_mm_malloc(have*sizeof(struct roar_server)); if (ret == NULL) return NULL; have--; for (i = cp = 0; i < have; i++) { c = &(ret[cp]); c->server = servers[i]; c->description = NULL; c->location = NULL; // uniq test: is_uniq = 1; for (unic = 0; unic < cp; unic++) if ( !strcmp(ret[unic].server, servers[i]) ) is_uniq = 0; if ( is_uniq && _test_server(c, flags) == 0 ) { cp++; } else { roar_mm_free(servers[i]); } } ret[cp].server = NULL; ret[cp].description = roar_mm_strdup("Default server"); ret[cp].location = NULL; return ret; } int roar_enum_servers_free(struct roar_server * servs) { struct roar_server * c; int i; if ( servs == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; (c = &(servs[i]))->server != NULL; i++) { roar_mm_free((void*)c->server); if ( c->description != NULL ) roar_mm_free((void*)c->description); if ( c->location != NULL ) roar_mm_free((void*)c->location); } if ( c->description != NULL ) roar_mm_free((void*)c->description); if ( c->location != NULL ) roar_mm_free((void*)c->location); roar_mm_free(servs); return 0; } ssize_t roar_enum_servers_num(struct roar_server * servs) { size_t ret; if ( servs == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (ret = 0; servs[ret].server != NULL; ret++); return ret; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/env.c�������������������������������������������������������������������0000644�0001750�0001750�00000012013�12264733537�015056� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//env.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_env_set(struct roar_keyval * keyval) { #if defined(ROAR_HAVE_PUTENV) && !defined(ROAR_HAVE_SETENV) size_t len; char * str; #endif if ( keyval == NULL || keyval->key == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } #ifdef ROAR_HAVE_SETENV return setenv(keyval->key, keyval->value, 1); #elif defined(ROAR_HAVE_PUTENV) len = strlen(keyval->key) + strlen(keyval->value) + 2; // TODO: does this leak memory? if ( (str = malloc(len)) == NULL ) { return -1; } snprintf(str, len, "%s=%s", keyval->key, keyval->value); return putenv(str) == 0 ? 0 : -1; #else roar_strap(ROAR_TRAP_GROUP_LIBROAR, "env_set.not-implemented"); roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } const char * roar_env_get(const char * key) { const char * ret; if ( key == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } roar_err_clear_all(); ret = getenv(key); roar_err_update(); if ( ret == NULL && roar_error == ROAR_ERROR_NONE ) roar_err_set(ROAR_ERROR_NOENT); return ret; } const char * roar_env_get_home(int level) { const char * home = roar_env_get("HOME"); (void)level; return home; } int roar_env_get_home_r(int level, char * str, size_t len) { size_t homelen; const char * home; if ( len == 0 ) return 0; if ( str == NULL ) return -1; *str = 0; // write a single termination byte to be safe... home = roar_env_get_home(level); if ( home == NULL ) return -1; homelen = strlen(home); if ( (len - 1) < homelen ) return -1; strncpy(str, home, len); str[homelen] = 0; return 0; } static char * __get_path(const char ** inpath) { char buf_path[64]; size_t i; (*inpath)++; for (i = 0; i < sizeof(buf_path); i++) { if ( (*inpath)[i] == '/' || (*inpath)[i] == 0 ) { break; } else { buf_path[i] = (*inpath)[i]; } } if ( i == sizeof(buf_path) ) { roar_err_set(ROAR_ERROR_NOSPC); return NULL; } buf_path[i] = 0; (*inpath) += i; return roar_libroar_get_path(buf_path, 0, NULL, NULL); } int roar_env_render_path_r(char * out, size_t len, const char * inpath) { size_t inlen; size_t needlen = 0; size_t homelen = 0; const char * home; const char * prefix = NULL; char * prefix_path = NULL; enum { UNKNOWN, COPY, HOME, PREFIX } mode = UNKNOWN; if ( len == 0 && inpath == NULL ) return 0; if ( inpath == NULL ) return -1; inlen = strlen(inpath); if ( len == 0 && inlen == 0 ) return 0; if ( len == 0 ) return -1; if ( out == NULL ) return -1; home = roar_env_get_home(0); if ( home != NULL ) homelen = strlen(home); if ( inpath[0] == '/' ) { needlen = inlen; mode = COPY; } else if ( inpath[0] == '~' && inpath[1] == '/' ) { if ( homelen == 0 ) /* we don't know our $HOME */ return -1; needlen = inlen + homelen - 1; mode = HOME; prefix = home; inpath++; } else if ( inpath[0] == '$' ) { prefix_path = __get_path(&inpath); if ( prefix_path == NULL ) return -1; needlen = roar_mm_strlen(inpath) + roar_mm_strlen(prefix_path) + 1; mode = PREFIX; prefix = prefix_path; } if ( len < (needlen + 1) ) { if ( prefix_path != NULL ) roar_mm_free(prefix_path); roar_err_set(ROAR_ERROR_NOSPC); return -1; } switch (mode) { case COPY: strncpy(out, inpath, len); out[len-1] = 0; break; case HOME: case PREFIX: roar_mm_strlcpy(out, prefix, len); roar_mm_strlcat(out, inpath, len); // strip only ~, so we have the / if home is not /-terminated. break; default: if ( prefix_path != NULL ) roar_mm_free(prefix_path); roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } if ( prefix_path != NULL ) roar_mm_free(prefix_path); return 0; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/error.c�����������������������������������������������������������������0000644�0001750�0001750�00000132227�12264733540�015423� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//error.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" // 'no error' value for errno. // zero is true for GNU/Linux. // don't know about other systems. // IEEE Std 1003.1-2008 (POSIX 7) requires: // 'distinct positive values'. #define CLEAN_ERRNO 0 static int roar_errno = ROAR_ERROR_NONE; struct roar_error_frame * roar_err_errorframe(void) { static struct roar_error_frame frame = { .version = 0, .cmd = -1, .ra_errno = ROAR_ERROR_UNKNOWN, .ra_suberrno = -1, .p_errno = -1, .flags = 0, .datalen = 0, .data = NULL }; return &frame; } int roar_err_init(struct roar_error_frame * frame) { if ( frame == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(frame, 0, sizeof(struct roar_error_frame)); frame->cmd = -1; frame->ra_errno = ROAR_ERROR_UNKNOWN; frame->ra_suberrno = -1; frame->p_errno = -1; frame->datalen = 0; frame->data = NULL; return 0; } void * roar_err_buildmsg(struct roar_message * mes, void ** data, struct roar_error_frame * frame) { char * databuf = NULL; int16_t * d; size_t datalen; if ( mes == NULL || frame == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( data != NULL ) *data = NULL; datalen = 8 + frame->datalen; if ( datalen > LIBROAR_BUFFER_MSGDATA ) { if ( data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } roar_err_clear_errno(); *data = roar_mm_malloc(datalen); roar_err_from_errno(); if ( *data == NULL ) return NULL; databuf = *data; } else { databuf = mes->data; } memset(mes, 0, sizeof(struct roar_message)); memset(databuf, 0, mes->datalen); mes->datalen = datalen; d = (int16_t*)databuf; frame->data = &(databuf[8]); databuf[0] = 0; // version. databuf[1] = frame->cmd; databuf[2] = frame->ra_errno; databuf[3] = frame->ra_suberrno; d[2] = ROAR_HOST2NET16(frame->p_errno); d[3] = ROAR_HOST2NET16(frame->flags); return frame->data; } int roar_err_parsemsg(struct roar_message * mes, void * data, struct roar_error_frame * frame) { char * databuf = (char *)data; int16_t * d; ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( mes == NULL || frame == NULL ) { roar_err_set(ROAR_ERROR_FAULT); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=FAULT", mes, (int)mes->datalen, mes->data, data, frame); return -1; } ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( databuf == NULL ) databuf = mes->data; d = (int16_t*)databuf; ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( mes->datalen < 8 ) { roar_err_set(ROAR_ERROR_MSGSIZE); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=MSGSIZE", mes, (int)mes->datalen, mes->data, data, frame); return -1; } ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); if ( databuf[0] != 0 ) { roar_err_set(ROAR_ERROR_NSVERSION); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = -1 // error=NSVERSION", mes, (int)mes->datalen, mes->data, data, frame); return -1; } ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = ?", mes, (int)mes->datalen, mes->data, data, frame); frame->cmd = databuf[1]; frame->ra_errno = databuf[2]; frame->ra_suberrno = databuf[3]; frame->p_errno = ROAR_NET2HOST16(d[2]); frame->flags = ROAR_NET2HOST16(d[3]); frame->datalen = mes->datalen - 8; frame->data = &(databuf[8]); ROAR_DBG("roar_err_parsemsg2(mes=%p{.datalen=%i, .data=%p}, data=%p, frame=%p) = 0", mes, (int)mes->datalen, mes->data, data, frame); return 0; } #define roar_errno2_impl (&roar_errno) int * roar_errno2(void) { return roar_errno2_impl; } void roar_err_clear(void) { *roar_errno2_impl = ROAR_ERROR_NONE; } void roar_err_clear_errno(void) { errno = CLEAN_ERRNO; } void roar_err_clear_all(void) { roar_err_clear(); roar_err_clear_errno(); } void roar_err_update(void) { int * err = roar_errno2_impl; // NOTE: _NEVER_ call ROAR_{DBG,INFO,WARN,ERR}() in here! (will result in endless loop) //printf("*err=%i, errno=%i\n", *err, (int)errno); if ( *err != ROAR_ERROR_NONE ) { roar_err_to_errno(); } else if ( !roar_err_is_errno_clear() ) { roar_err_from_errno(); #ifdef ROAR_TARGET_WIN32 } else { roar_err_convert(err, ROAR_ERROR_TYPE_ROARAUDIO, WSAGetLastError(), ROAR_ERROR_TYPE_WINSOCK); roar_err_to_errno(); #endif } } int roar_err_is_errno_clear(void) { return errno == CLEAN_ERRNO ? 1 : 0; } void roar_err_set(const int error) { *roar_errno2_impl = error; } static int __errno_to_roar(int error) { int _roar_errno = ROAR_ERROR_NONE; switch (error) { #ifdef EACCES case EACCES: _roar_errno = ROAR_ERROR_PERM; break; #endif #ifdef EPERM case EPERM: _roar_errno = ROAR_ERROR_PERM; break; #endif #ifdef ENOENT case ENOENT: _roar_errno = ROAR_ERROR_NOENT; break; #endif #ifdef EBADMSG case EBADMSG: _roar_errno = ROAR_ERROR_BADMSG; break; #endif #ifdef EBUSY case EBUSY: _roar_errno = ROAR_ERROR_BUSY; break; #endif #ifdef ECONNREFUSED case ECONNREFUSED: _roar_errno = ROAR_ERROR_CONNREFUSED; break; #endif #ifdef ENOSYS case ENOSYS: _roar_errno = ROAR_ERROR_NOSYS; break; #endif #ifdef ENOTSUP case ENOTSUP: _roar_errno = ROAR_ERROR_NOTSUP; break; #endif #ifdef EPIPE case EPIPE: _roar_errno = ROAR_ERROR_PIPE; break; #endif #ifdef EPROTO case EPROTO: _roar_errno = ROAR_ERROR_PROTO; break; #endif #ifdef ERANGE case ERANGE: _roar_errno = ROAR_ERROR_RANGE; break; #endif #ifdef EMSGSIZE case EMSGSIZE: _roar_errno = ROAR_ERROR_MSGSIZE; break; #endif #ifdef ENOMEM case ENOMEM: _roar_errno = ROAR_ERROR_NOMEM; break; #endif #ifdef EINVAL case EINVAL: _roar_errno = ROAR_ERROR_INVAL; break; #endif #ifdef EALREADY case EALREADY: _roar_errno = ROAR_ERROR_ALREADY; break; #endif #ifdef EBADRQC case EBADRQC: _roar_errno = ROAR_ERROR_BADRQC; break; #endif #ifdef EDOM case EDOM: _roar_errno = ROAR_ERROR_DOM; break; #endif #ifdef EEXIST case EEXIST: _roar_errno = ROAR_ERROR_EXIST; break; #endif #ifdef EFAULT case EFAULT: _roar_errno = ROAR_ERROR_FAULT; break; #endif #ifdef EIO case EIO: _roar_errno = ROAR_ERROR_IO; break; #endif #ifdef EREMOTEIO case EREMOTEIO: _roar_errno = ROAR_ERROR_RIO; break; #endif #ifdef EKEYEXPIRED case EKEYEXPIRED: _roar_errno = ROAR_ERROR_KEYEXPIRED; break; #endif #ifdef EKEYREJECTED case EKEYREJECTED: _roar_errno = ROAR_ERROR_KEYREJECTED; break; #endif #ifdef ELOOP case ELOOP: _roar_errno = ROAR_ERROR_LOOP; break; #endif #ifdef EMFILE case EMFILE: _roar_errno = ROAR_ERROR_MFILE; break; #endif #ifdef ENAMETOOLONG case ENAMETOOLONG: _roar_errno = ROAR_ERROR_NAMETOOLONG; break; #endif #ifdef ENODATA case ENODATA: _roar_errno = ROAR_ERROR_NODATA; break; #endif #ifdef ENODEV case ENODEV: _roar_errno = ROAR_ERROR_NODEV; break; #endif #ifdef ENOSPC case ENOSPC: _roar_errno = ROAR_ERROR_NOSPC; break; #endif #ifdef ENOTCONN case ENOTCONN: _roar_errno = ROAR_ERROR_NOTCONN; break; #endif #ifdef EPROTONOSUPPORT case EPROTONOSUPPORT: _roar_errno = ROAR_ERROR_PROTONOSUP; break; #endif #ifdef EROFS case EROFS: _roar_errno = ROAR_ERROR_RO; break; #endif #ifdef ETIMEDOUT case ETIMEDOUT: _roar_errno = ROAR_ERROR_TIMEDOUT; break; #endif #ifdef EAGAIN case EAGAIN: _roar_errno = ROAR_ERROR_AGAIN; break; #endif #ifdef ENETDOWN case ENETDOWN: _roar_errno = ROAR_ERROR_LINKDOWN; break; #endif #ifdef EINTR case EINTR: _roar_errno = ROAR_ERROR_INTERRUPTED; break; #endif #ifdef EDQUOT case EDQUOT: _roar_errno = ROAR_ERROR_QUOTA; break; #endif #ifdef ELIBBAD case ELIBBAD: _roar_errno = ROAR_ERROR_BADLIB; break; #endif #ifdef ENOMEDIUM case ENOMEDIUM: _roar_errno = ROAR_ERROR_NOMEDIUM; break; #endif #ifdef ENOTUNIQ case ENOTUNIQ: _roar_errno = ROAR_ERROR_NOTUNIQ; break; #endif #ifdef EILSEQ case EILSEQ: _roar_errno = ROAR_ERROR_ILLSEQ; break; #endif #ifdef EADDRINUSE case EADDRINUSE: _roar_errno = ROAR_ERROR_ADDRINUSE; break; #endif #ifdef ESPIPE case ESPIPE: _roar_errno = ROAR_ERROR_BADSEEK; break; #endif #ifdef ECHERNOBYL case ECHERNOBYL: _roar_errno = ROAR_ERROR_CHERNOBYL; break; #endif #ifdef ECRAY case ECRAY: _roar_errno = ROAR_ERROR_CAUSALITY; break; #endif #ifdef ENOHORSE case ENOHORSE: _roar_errno = ROAR_ERROR_NOHORSE; break; #endif #ifdef ETXTBSY case ETXTBSY: _roar_errno = ROAR_ERROR_TEXTBUSY; break; #endif #ifdef ENOTEMPTY case ENOTEMPTY: _roar_errno = ROAR_ERROR_NOTEMPTY; break; #endif #ifdef EHOSTUNREACH case EHOSTUNREACH: _roar_errno = ROAR_ERROR_NODEUNREACH; break; #endif #ifdef EIDRM case EIDRM: _roar_errno = ROAR_ERROR_IDREMOVED; break; #endif #ifdef EINPROGRESS case EINPROGRESS: _roar_errno = ROAR_ERROR_INPROGRESS; break; #endif #ifdef ECHILD case ECHILD: _roar_errno = ROAR_ERROR_NOCHILD; break; #endif #ifdef ENETUNREACH case ENETUNREACH: _roar_errno = ROAR_ERROR_NETUNREACH; break; #endif #ifdef ECANCELED case ECANCELED: _roar_errno = ROAR_ERROR_CANCELED; break; #endif #ifdef EISDIR case EISDIR: _roar_errno = ROAR_ERROR_ISDIR; break; #endif #ifdef ENOTDIR case ENOTDIR: _roar_errno = ROAR_ERROR_NOTDIR; break; #endif #ifdef ENOEXEC case ENOEXEC: _roar_errno = ROAR_ERROR_BADEXEC; break; #endif #ifdef EISCONN case EISCONN: _roar_errno = ROAR_ERROR_ISCONN; break; #endif #ifdef EDEADLK case EDEADLK: _roar_errno = ROAR_ERROR_DEADLOCK; break; #endif #ifdef ECONNRESET case ECONNRESET: _roar_errno = ROAR_ERROR_CONNRST; break; #endif #ifdef EBADF case EBADF: _roar_errno = ROAR_ERROR_BADFH; break; #endif #ifdef ENOTSOCK case ENOTSOCK: _roar_errno = ROAR_ERROR_NOTSOCK; break; #endif #ifdef E2BIG case E2BIG: _roar_errno = ROAR_ERROR_TOOMANYARGS; break; #endif #ifdef EFBIG case EFBIG: _roar_errno = ROAR_ERROR_TOOLARGE; break; #endif #ifdef EDESTADDRREQ case EDESTADDRREQ: _roar_errno = ROAR_ERROR_DESTADDRREQ; break; #endif #ifdef EAFNOSUPPORT case EAFNOSUPPORT: _roar_errno = ROAR_ERROR_AFNOTSUP; break; #endif #ifdef ENFILE case ENFILE: _roar_errno = ROAR_ERROR_NFILE; break; #endif #ifdef ESTALE case ESTALE: _roar_errno = ROAR_ERROR_STALE; break; #endif #ifdef EXDEV case EXDEV: _roar_errno = ROAR_ERROR_XDEVLINK; break; #endif #ifdef EMLINK case EMLINK: _roar_errno = ROAR_ERROR_MLINK; break; #endif #ifdef ENONET case ENONET: _roar_errno = ROAR_ERROR_NONET; break; #endif #ifdef ENETRESET case ENETRESET: _roar_errno = ROAR_ERROR_CONNRSTNET; break; #endif #ifdef ECONNABORTED case ECONNABORTED: _roar_errno = ROAR_ERROR_CONNABORTED; break; #endif #ifdef EBADFD case EBADFD: _roar_errno = ROAR_ERROR_BADSTATE; break; #endif default: _roar_errno = ROAR_ERROR_UNKNOWN; break; } return _roar_errno; } void roar_err_from_errno(void) { roar_err_set(__errno_to_roar(errno)); } static int __roar_to_errno(int error) { switch (error) { case ROAR_ERROR_NONE: return CLEAN_ERRNO; break; #ifdef EPERM case ROAR_ERROR_PERM: return EPERM; break; #endif #ifdef ENOENT case ROAR_ERROR_NOENT: return ENOENT; break; #endif #ifdef EBADMSG case ROAR_ERROR_BADMSG: return EBADMSG; break; #endif #ifdef EBUSY case ROAR_ERROR_BUSY: return EBUSY; break; #endif #ifdef ECONNREFUSED case ROAR_ERROR_CONNREFUSED: return ECONNREFUSED; break; #endif #ifdef ENOSYS case ROAR_ERROR_NOSYS: return ENOSYS; break; #endif #ifdef ENOTSUP case ROAR_ERROR_NOTSUP: return ENOTSUP; break; #endif #ifdef EPIPE case ROAR_ERROR_PIPE: return EPIPE; break; #endif #ifdef EPROTO case ROAR_ERROR_PROTO: return EPROTO; break; #endif #ifdef ERANGE case ROAR_ERROR_RANGE: return ERANGE; break; #endif #ifdef EMSGSIZE case ROAR_ERROR_MSGSIZE: return EMSGSIZE; break; #endif #ifdef ENOMEM case ROAR_ERROR_NOMEM: return ENOMEM; break; #endif #ifdef EINVAL case ROAR_ERROR_INVAL: return EINVAL; break; #endif #ifdef EALREADY case ROAR_ERROR_ALREADY: return EALREADY; break; #endif #ifdef EBADRQC case ROAR_ERROR_BADRQC: return EBADRQC; break; #endif #ifdef EDOM case ROAR_ERROR_DOM: return EDOM; break; #endif #ifdef EEXIST case ROAR_ERROR_EXIST: return EEXIST; break; #endif #ifdef EFAULT case ROAR_ERROR_FAULT: return EFAULT; break; #endif #if defined(EREMOTEIO) || defined(EIO) case ROAR_ERROR_RIO: #ifdef EREMOTEIO return EREMOTEIO; #else return EIO; #endif break; #endif #ifdef EIO case ROAR_ERROR_IO: case ROAR_ERROR_HOLE: case ROAR_ERROR_BADCKSUM: case ROAR_ERROR_LOSTSYNC: case ROAR_ERROR_NOHORSE: return EIO; break; #endif #ifdef EKEYEXPIRED case ROAR_ERROR_KEYEXPIRED: return EKEYEXPIRED; break; #endif #ifdef EKEYREJECTED case ROAR_ERROR_KEYREJECTED: return EKEYREJECTED; break; #endif #ifdef ELOOP case ROAR_ERROR_LOOP: return ELOOP; break; #endif #ifdef EMFILE case ROAR_ERROR_MFILE: return EMFILE; break; #endif #ifdef ENAMETOOLONG case ROAR_ERROR_NAMETOOLONG: return ENAMETOOLONG; break; #endif #ifdef ENODATA case ROAR_ERROR_NODATA: return ENODATA; break; #endif #ifdef ENODEV case ROAR_ERROR_NODEV: case ROAR_ERROR_NODRV: return ENODEV; break; #endif #ifdef ENOSPC case ROAR_ERROR_NOSPC: return ENOSPC; break; #endif #ifdef EINVAL case ROAR_ERROR_TYPEMM: return EINVAL; break; #endif #ifdef ENOSYS case ROAR_ERROR_NORSYS: return ENOSYS; break; #endif #ifdef ENOTCONN case ROAR_ERROR_NOTCONN: return ENOTCONN; break; #endif #ifdef EPROTONOSUPPORT case ROAR_ERROR_PROTONOSUP: return EPROTONOSUPPORT; break; #endif #ifdef EROFS case ROAR_ERROR_RO: return EROFS; break; #endif #ifdef ETIMEDOUT case ROAR_ERROR_TIMEDOUT: return ETIMEDOUT; break; #endif #ifdef EAGAIN case ROAR_ERROR_AGAIN: return EAGAIN; break; #endif #ifdef ENETDOWN case ROAR_ERROR_LINKDOWN: return ENETDOWN; break; #endif #ifdef EINTR case ROAR_ERROR_INTERRUPTED: return EINTR; break; #endif #ifdef EDQUOT case ROAR_ERROR_QUOTA: return EDQUOT; break; #endif #ifdef ELIBBAD case ROAR_ERROR_BADLIB: return ELIBBAD; break; #endif #ifdef ENOMEDIUM case ROAR_ERROR_NOMEDIUM: return ENOMEDIUM; break; #endif #ifdef ENOTUNIQ case ROAR_ERROR_NOTUNIQ: return ENOTUNIQ; break; #endif #ifdef EILSEQ case ROAR_ERROR_ILLSEQ: return EILSEQ; break; #endif #ifdef EADDRINUSE case ROAR_ERROR_ADDRINUSE: return EADDRINUSE; break; #endif #ifdef ESPIPE case ROAR_ERROR_BADSEEK: case ROAR_ERROR_NOSEEK: return ESPIPE; break; #endif #ifdef ECHERNOBYL case ROAR_ERROR_CHERNOBYL: return ECHERNOBYL; break; #endif #ifdef ECRAY case ROAR_ERROR_CAUSALITY: return ECRAY; break; #endif #ifdef ENOHORSE case ROAR_ERROR_NOHORSE: return ENOHORSE; break; #endif #ifdef ETXTBSY case ROAR_ERROR_TEXTBUSY: return ETXTBSY; break; #endif #ifdef ENOTEMPTY case ROAR_ERROR_NOTEMPTY: return ENOTEMPTY; break; #endif #ifdef EHOSTUNREACH case ROAR_ERROR_NODEUNREACH: return EHOSTUNREACH; break; #endif #ifdef EIDRM case ROAR_ERROR_IDREMOVED: return EIDRM; break; #endif #ifdef EINPROGRESS case ROAR_ERROR_INPROGRESS: return EINPROGRESS; break; #endif #ifdef ECHILD case ROAR_ERROR_NOCHILD: return ECHILD; break; #endif #ifdef ENETUNREACH case ROAR_ERROR_NETUNREACH: return ENETUNREACH; break; #endif #ifdef ECANCELED case ROAR_ERROR_CANCELED: return ECANCELED; break; #endif #ifdef EISDIR case ROAR_ERROR_ISDIR: return EISDIR; break; #endif #ifdef ENOTDOR case ROAR_ERROR_NOTDIR: return ENOTDIR; break; #endif #ifdef ENOEXEC case ROAR_ERROR_BADEXEC: return ENOEXEC; break; #endif #ifdef EISCONN case ROAR_ERROR_ISCONN: return EISCONN; break; #endif #ifdef EDEADLK case ROAR_ERROR_DEADLOCK: return EDEADLK; break; #endif #ifdef ECONNRESET case ROAR_ERROR_CONNRST: return ECONNRESET; break; #endif #ifdef EBADF case ROAR_ERROR_BADFH: return EBADF; break; #endif #ifdef ENOTSOCK case ROAR_ERROR_NOTSOCK: return ENOTSOCK; break; #endif #ifdef E2BIG case ROAR_ERROR_TOOMANYARGS: return E2BIG; break; #endif #ifdef EFBIG case ROAR_ERROR_TOOLARGE: return EFBIG; break; #endif #ifdef EDESTADDRREQ case ROAR_ERROR_DESTADDRREQ: return EDESTADDRREQ; break; #endif #ifdef EAFNOSUPPORT case ROAR_ERROR_AFNOTSUP: return EAFNOSUPPORT; break; #endif // FIXME.... #ifdef ENOPOWER case ROAR_ERROR_NOPOWER: return ENOPOWER; break; #endif #ifdef EUSER case ROAR_ERROR_USER: return EUSER; break; #endif #ifdef ENFILE case ROAR_ERROR_NFILE: return ENFILE; break; #endif #ifdef ESTALE case ROAR_ERROR_STALE: return ESTALE; break; #endif #ifdef EXDEV case ROAR_ERROR_XDEVLINK: return EXDEV; break; #endif #ifdef EMLINK case ROAR_ERROR_MLINK: return EMLINK; break; #endif #ifdef ENONET case ROAR_ERROR_NONET: return ENONET; break; #endif #ifdef ENETRESET case ROAR_ERROR_CONNRSTNET: return ENETRESET; break; #endif #ifdef ECONNABORTED case ROAR_ERROR_CONNABORTED: return ECONNABORTED; break; #endif #ifdef EBADFD case ROAR_ERROR_BADSTATE: return EBADFD; break; #endif default: #ifdef EINVAL return EINVAL; #else return -1; // just guess #endif break; } } void roar_err_to_errno(void) { errno = __roar_to_errno(roar_error); } static const struct error_table_entry { const enum roar_error_type type; const int error; const int roarerror; } __libroar_error_table[] = { {ROAR_ERROR_TYPE_HTTP, 200, ROAR_ERROR_NONE}, {ROAR_ERROR_TYPE_HTTP, 301, ROAR_ERROR_MOVEDPERM}, {ROAR_ERROR_TYPE_HTTP, 303, ROAR_ERROR_SEEOTHER}, {ROAR_ERROR_TYPE_HTTP, 305, ROAR_ERROR_USEPROXY}, {ROAR_ERROR_TYPE_HTTP, 307, ROAR_ERROR_MOVEDTEMP}, {ROAR_ERROR_TYPE_HTTP, 400, ROAR_ERROR_INVAL}, {ROAR_ERROR_TYPE_HTTP, 402, ROAR_ERROR_NEEDPAYMENT}, {ROAR_ERROR_TYPE_HTTP, 403, ROAR_ERROR_PERM}, {ROAR_ERROR_TYPE_HTTP, 404, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_HTTP, 408, ROAR_ERROR_TIMEDOUT}, {ROAR_ERROR_TYPE_HTTP, 410, ROAR_ERROR_GONE}, {ROAR_ERROR_TYPE_HTTP, 415, ROAR_ERROR_NSTYPE}, {ROAR_ERROR_TYPE_HTTP, 423, ROAR_ERROR_BUSY}, {ROAR_ERROR_TYPE_HTTP, 426, ROAR_ERROR_SWITCHPROTO}, {ROAR_ERROR_TYPE_HTTP, 451, ROAR_ERROR_CENSORED}, {ROAR_ERROR_TYPE_HTTP, 450, ROAR_ERROR_CENSORED}, {ROAR_ERROR_TYPE_HTTP, 501, ROAR_ERROR_NOSYS}, {ROAR_ERROR_TYPE_HTTP, 504, ROAR_ERROR_TIMEDOUT}, {ROAR_ERROR_TYPE_HTTP, 505, ROAR_ERROR_NSVERSION}, {ROAR_ERROR_TYPE_HTTP, 507, ROAR_ERROR_NOSPC}, #ifdef NETDB_SUCCESS {ROAR_ERROR_TYPE_HERROR, NETDB_SUCCESS, ROAR_ERROR_NONE}, #endif #ifdef HOST_NOT_FOUND {ROAR_ERROR_TYPE_HERROR, HOST_NOT_FOUND, ROAR_ERROR_NOENT}, #endif #ifdef TRY_AGAIN {ROAR_ERROR_TYPE_HERROR, TRY_AGAIN, ROAR_ERROR_AGAIN}, #endif #ifdef NO_RECOVERY // {ROAR_ERROR_TYPE_HERROR, NO_RECOVERY, ROAR_ERROR_???}, #endif #ifdef NO_DATA {ROAR_ERROR_TYPE_HERROR, NO_DATA, ROAR_ERROR_NODATA}, #endif #ifdef NO_ADDRESS {ROAR_ERROR_TYPE_HERROR, NO_ADDRESS, ROAR_ERROR_NOENT}, #endif #ifdef ROAR_TARGET_WIN32 {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_HANDLE, ROAR_ERROR_BADFH}, {ROAR_ERROR_TYPE_WINSOCK, WSA_NOT_ENOUGH_MEMORY, ROAR_ERROR_NOMEM}, {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_PARAMETER, ROAR_ERROR_INVAL}, {ROAR_ERROR_TYPE_WINSOCK, WSA_OPERATION_ABORTED, ROAR_ERROR_INTERRUPTED}, // {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_INCOMPLETE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_PENDING, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEINTR, ROAR_ERROR_INTERRUPTED}, {ROAR_ERROR_TYPE_WINSOCK, WSAEBADF, ROAR_ERROR_BADFH}, {ROAR_ERROR_TYPE_WINSOCK, WSAEACCES, ROAR_ERROR_PERM}, {ROAR_ERROR_TYPE_WINSOCK, WSAEFAULT, ROAR_ERROR_FAULT}, {ROAR_ERROR_TYPE_WINSOCK, WSAEINVAL, ROAR_ERROR_INVAL}, {ROAR_ERROR_TYPE_WINSOCK, WSAEMFILE, ROAR_ERROR_MFILE}, {ROAR_ERROR_TYPE_WINSOCK, WSAEWOULDBLOCK, ROAR_ERROR_AGAIN}, {ROAR_ERROR_TYPE_WINSOCK, WSAEINPROGRESS, ROAR_ERROR_INPROGRESS}, {ROAR_ERROR_TYPE_WINSOCK, WSAEALREADY, ROAR_ERROR_ALREADY}, {ROAR_ERROR_TYPE_WINSOCK, WSAENOTSOCK, ROAR_ERROR_NOTSOCK}, {ROAR_ERROR_TYPE_WINSOCK, WSAEDESTADDRREQ, ROAR_ERROR_DESTADDRREQ}, {ROAR_ERROR_TYPE_WINSOCK, WSAEMSGSIZE, ROAR_ERROR_MSGSIZE}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTOTYPE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENOPROTOOPT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTONOSUPPORT, ROAR_ERROR_PROTONOSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAESOCKTNOSUPPORT, ROAR_ERROR_PROTONOSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEOPNOTSUPP, ROAR_ERROR_NOTSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEPFNOSUPPORT, ROAR_ERROR_AFNOTSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEAFNOSUPPORT, ROAR_ERROR_AFNOTSUP}, {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRINUSE, ROAR_ERROR_ADDRINUSE}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRNOTAVAIL, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENETDOWN, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAENETUNREACH, ROAR_ERROR_NETUNREACH}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENETRESET, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAECONNABORTED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAECONNRESET, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENOBUFS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEISCONN, ROAR_ERROR_ISCONN}, {ROAR_ERROR_TYPE_WINSOCK, WSAENOTCONN, ROAR_ERROR_NOTCONN}, // {ROAR_ERROR_TYPE_WINSOCK, WSAESHUTDOWN, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAETOOMANYREFS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAETIMEDOUT, ROAR_ERROR_TIMEDOUT}, {ROAR_ERROR_TYPE_WINSOCK, WSAECONNREFUSED, ROAR_ERROR_CONNREFUSED}, {ROAR_ERROR_TYPE_WINSOCK, WSAELOOP, ROAR_ERROR_LOOP}, {ROAR_ERROR_TYPE_WINSOCK, WSAENAMETOOLONG, ROAR_ERROR_NAMETOOLONG}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTDOWN, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTUNREACH, ROAR_ERROR_NODEUNREACH}, {ROAR_ERROR_TYPE_WINSOCK, WSAENOTEMPTY, ROAR_ERROR_NOTEMPTY}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEPROCLIM, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEUSERS, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEDQUOT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAESTALE, ROAR_ERROR_STALE}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEREMOTE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSASYSNOTREADY, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAVERNOTSUPPORTED, ROAR_ERROR_NSVERSION}, // {ROAR_ERROR_TYPE_WINSOCK, WSANOTINITIALISED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEDISCON, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAENOMORE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAECANCELLED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROCTABLE, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROVIDER, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEPROVIDERFAILEDINIT, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSASYSCALLFAILURE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSASERVICE_NOT_FOUND, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_WINSOCK, WSATYPE_NOT_FOUND, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_WINSOCK, WSA_E_NO_MORE, ROAR_ERROR_NOENT}, // {ROAR_ERROR_TYPE_WINSOCK, WSA_E_CANCELLED, ROAR_ERROR_???}, // {ROAR_ERROR_TYPE_WINSOCK, WSAEREFUSED, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSAHOST_NOT_FOUND, ROAR_ERROR_NOENT}, {ROAR_ERROR_TYPE_WINSOCK, WSATRY_AGAIN, ROAR_ERROR_AGAIN}, // {ROAR_ERROR_TYPE_WINSOCK, WSANO_RECOVERY, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSANO_DATA, ROAR_ERROR_NODATA}, #if 0 {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RECEIVERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_SENDERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_SENDERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_RECEIVERS, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_REQUEST_CONFIRMED, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ADMISSION_FAILURE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_POLICY_FAILURE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_STYLE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_OBJECT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_TRAFFIC_CTRL_ERROR, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_GENERIC_ERROR, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESERVICETYPE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWSPEC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPROVSPECBUF, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERSTYLE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERTYPE, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERCOUNT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EOBJLENGTH, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWCOUNT, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EUNKOWNPSOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPOLICYOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWDESC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFLOWSPEC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFILTERSPEC, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESDMODEOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESHAPERATEOBJ, ROAR_ERROR_???}, {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RESERVED_PETYPE, ROAR_ERROR_???}, #endif #endif {ROAR_ERROR_TYPE_EAI, 0 /* defined value, see manpage */, ROAR_ERROR_NONE}, #ifdef EAI_ADDRFAMILY {ROAR_ERROR_TYPE_EAI, EAI_ADDRFAMILY, ROAR_ERROR_NOENT}, #endif #ifdef EAI_AGAIN {ROAR_ERROR_TYPE_EAI, EAI_AGAIN, ROAR_ERROR_AGAIN}, #endif #ifdef EAI_BADFLAGS {ROAR_ERROR_TYPE_EAI, EAI_BADFLAGS, ROAR_ERROR_INVAL}, #endif #ifdef EAI_FAIL {ROAR_ERROR_TYPE_EAI, EAI_FAIL, ROAR_ERROR_RIO}, #endif #ifdef EAI_FAMILY {ROAR_ERROR_TYPE_EAI, EAI_FAMILY, ROAR_ERROR_AFNOTSUP}, #endif #ifdef EAI_MEMORY {ROAR_ERROR_TYPE_EAI, EAI_MEMORY, ROAR_ERROR_NOMEM}, #endif #ifdef EAI_NODATA {ROAR_ERROR_TYPE_EAI, EAI_NODATA, ROAR_ERROR_NODATA}, #endif #ifdef EAI_NONAME {ROAR_ERROR_TYPE_EAI, EAI_NONAME, ROAR_ERROR_NOENT}, #endif #ifdef EAI_SERVICE {ROAR_ERROR_TYPE_EAI, EAI_SERVICE, ROAR_ERROR_PROTONOSUP}, #endif #ifdef EAI_SOCKTYPE {ROAR_ERROR_TYPE_EAI, EAI_SOCKTYPE, ROAR_ERROR_INVAL}, #endif #ifdef EAI_SYSTEM // {ROAR_ERROR_TYPE_EAI, EAI_SYSTEM, ROAR_ERROR_???}, #endif }; static int roar_err_convert_table_lookup(const struct error_table_entry ** match, const int error, const enum roar_error_type type, const int to_roar) { size_t i; // we have the following loop to times as an inner if() would cost more cycles // than the outer if we currently have. if ( to_roar ) { for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) { if ( __libroar_error_table[i].type == type && __libroar_error_table[i].error == error) { *match = &(__libroar_error_table[i]); return ROAR_ERROR_NONE; } } } else { for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) { if ( __libroar_error_table[i].type == type && __libroar_error_table[i].roarerror == error) { *match = &(__libroar_error_table[i]); return ROAR_ERROR_NONE; } } } return ROAR_ERROR_NOENT; } // Convert error codes between diffrent representations. // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_convert(int * out, const enum roar_error_type outtype, const int in, const enum roar_error_type intype) { const struct error_table_entry * tablematch; int tmp; int ret; if ( out == NULL ) return ROAR_ERROR_FAULT; if ( outtype == intype ) { *out = in; return ROAR_ERROR_NONE; } // if not to/from roar, use roar as temp type so we do only need to code two kinds of translators (not any->any). if ( intype != ROAR_ERROR_TYPE_ROARAUDIO && outtype != ROAR_ERROR_TYPE_ROARAUDIO ) { ret = roar_err_convert(&tmp, ROAR_ERROR_TYPE_ROARAUDIO, in, intype); if ( ret != ROAR_ERROR_NONE ) return ret; return roar_err_convert(out, outtype, tmp, ROAR_ERROR_TYPE_ROARAUDIO); } // from here we can asume that if intype != ROAR_ERROR_TYPE_ROARAUDIO outtype is ROAR_ERROR_TYPE_ROARAUDIO // and the other way around. if ( intype == ROAR_ERROR_TYPE_ROARAUDIO ) { ret = roar_err_convert_table_lookup(&tablematch, in, outtype, 0); } else { ret = roar_err_convert_table_lookup(&tablematch, in, intype, 1); } if ( ret == ROAR_ERROR_NONE ) { *out = intype == ROAR_ERROR_TYPE_ROARAUDIO ? tablematch->error : tablematch->roarerror; return ROAR_ERROR_NONE; } if ( intype == ROAR_ERROR_TYPE_ROARAUDIO && outtype == ROAR_ERROR_TYPE_ERRNO ) { // the __roar_to_errno() function always succeeds. *out = __roar_to_errno(in); return ROAR_ERROR_NONE; } if ( outtype == ROAR_ERROR_TYPE_ROARAUDIO && intype == ROAR_ERROR_TYPE_ERRNO ) { // the __errno_to_roar() function always succeeds. *out = __errno_to_roar(in); return ROAR_ERROR_NONE; } roar_err_get_default_error(out, outtype); return ROAR_ERROR_NOENT; } // Outputs a default error for the given type. // returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state. int roar_err_get_default_error(int * out, const enum roar_error_type type) { int is_set = 0; if ( out == NULL ) return ROAR_ERROR_FAULT; switch (type) { case ROAR_ERROR_TYPE_ROARAUDIO: is_set = 1; *out = ROAR_ERROR_UNKNOWN; break; #ifdef EINVAL case ROAR_ERROR_TYPE_ERRNO: is_set = 1; *out = EINVAL; break; #endif #ifdef NO_RECOVERY case ROAR_ERROR_TYPE_HERROR: is_set = 1; *out = NO_RECOVERY; break; #endif #ifdef __YIFF__ case ROAR_ERROR_TYPE_YIFF: is_set = 1; *out = YIFF_ERRNO_UNKNOWN; break; #endif case ROAR_ERROR_TYPE_HTTP: is_set = 1; *out = 500; break; #ifndef DEBUG // enable compiler warnings in DEBUG mode. default: break; #endif } if ( is_set ) { return ROAR_ERROR_NONE; } *out = -1; // some default so we do not leave it uninited. return ROAR_ERROR_NOENT; } // Resets the stored state to 'no error' state. This can be used // to init the state. int roar_err_initstore(struct roar_error_state * state) { struct roar_error_state curstate; if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } roar_err_store(&curstate); roar_err_clear_all(); roar_err_store(state); roar_err_restore(&curstate); return -1; } // store a error state (both libroar and system) int roar_err_store(struct roar_error_state * state) { if ( state == NULL ) return ROAR_ERROR_FAULT; memset(state, 0, sizeof(struct roar_error_state)); state->refc = 0; state->libroar_error = roar_error; state->system_error = errno; #ifdef ROAR_TARGET_WIN32 state->winsock_error = WSAGetLastError(); #endif #ifdef ROAR_HAVE_VAR_H_ERRNO state->syssock_herror = h_errno; #endif #ifdef __YIFF__ state->yiffc_error = yiffc_error; #endif return ROAR_ERROR_NONE; } // restore error state to values at time of call to roar_err_store() int roar_err_restore(struct roar_error_state * state) { if ( state == NULL ) return ROAR_ERROR_FAULT; roar_err_set(state->libroar_error); errno = state->system_error; #ifdef ROAR_TARGET_WIN32 WSASetLastError(state->winsock_error); #endif #ifdef ROAR_HAVE_VAR_H_ERRNO h_errno = state->syssock_herror; #endif #ifdef __YIFF__ yiffc_error = state->yiffc_error; #endif return ROAR_ERROR_NONE; } // phi@ph7:roaraudio $ grep '^#define ROAR_ERROR_' error.h | tr -d /\* | while read d c d t; do printf " {%-23s \"%s\"},\n" $c, "$t"; done static const char * roar_error2str_ms(const int error, const char * msg) { static char buf[1024] = ""; int num[8]; size_t i; int _ra_err = roar_error; int _sys_err = errno; for (i = 0; i < (sizeof(num)/sizeof(*num)); i++) num[i] = roar_random_uint32(); snprintf(buf, sizeof(buf), "\e[44;39;1m\e[2J\e[H" " RoarAudio\n" "\n\n" "Fatal error %.4x: %s\n" "RA Error: %.4i, Sys Error: %.4i (%s)\n" "Random numbers:\n" " A: 0x%.8X B: 0x%.8X\n" " C: 0x%.8X D: 0x%.8X\n" " E: 0x%.8X F: 0x%.8X\n" " G: 0x%.8X H: 0x%.8X\n" "\n\n" "\e[0m", error, msg, _ra_err, _sys_err, strerror(_sys_err), num[0], num[1], num[2], num[3], num[4], num[5], num[6], num[7]); return buf; } const char * roar_error2str(const int error) { struct roar_libroar_config * config = roar_libroar_get_config(); const struct { const int err; const char * msg; } msgs[] = { {ROAR_ERROR_NONE, "No error"}, {ROAR_ERROR_PERM, "Operation not permitted"}, {ROAR_ERROR_NOENT, "No such object, file, directory or node"}, {ROAR_ERROR_BADMSG, "Bad message"}, {ROAR_ERROR_BUSY, "Device or resource busy"}, {ROAR_ERROR_CONNREFUSED, "Connection refused"}, {ROAR_ERROR_NOSYS, "Function not implemented"}, {ROAR_ERROR_NOTSUP, "Operation not supported"}, {ROAR_ERROR_PIPE, "Broken pipe"}, {ROAR_ERROR_PROTO, "Protocol error"}, {ROAR_ERROR_RANGE, "Result too large or parameter out of range"}, {ROAR_ERROR_MSGSIZE, "Message too long"}, {ROAR_ERROR_NOMEM, "Not enough space"}, {ROAR_ERROR_INVAL, "Invalid argument"}, {ROAR_ERROR_ALREADY, "Connection already in progress"}, {ROAR_ERROR_BADRQC, "Invalid request code"}, {ROAR_ERROR_DOM, "Mathematics argument out of domain of function"}, {ROAR_ERROR_EXIST, "File or object exists"}, {ROAR_ERROR_FAULT, "Bad address"}, {ROAR_ERROR_IO, "I/O-Error"}, {ROAR_ERROR_KEYEXPIRED, "Key has expired"}, {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"}, {ROAR_ERROR_LOOP, "Too many recursions"}, {ROAR_ERROR_MFILE, "Too many open files or objects"}, {ROAR_ERROR_NAMETOOLONG, "File or object name too long"}, {ROAR_ERROR_NODATA, "No message is available on the read queue"}, {ROAR_ERROR_NODEV, "No such device"}, {ROAR_ERROR_NODRV, "No such driver"}, {ROAR_ERROR_NOSPC, "No space left on device"}, {ROAR_ERROR_TYPEMM, "Type missmatch. Object of diffrent type required"}, {ROAR_ERROR_NORSYS, "Feature not implemented by remote end"}, {ROAR_ERROR_NOTCONN, "Socket or object not connected"}, {ROAR_ERROR_PROTONOSUP, "Protocol not supported"}, {ROAR_ERROR_RIO, "Remote I/O Error"}, {ROAR_ERROR_RO, "File or object is read only"}, {ROAR_ERROR_TIMEDOUT, "Connection timed out"}, {ROAR_ERROR_AGAIN, "Resource temporarily unavailable"}, {ROAR_ERROR_NOISE, "Line too noisy"}, {ROAR_ERROR_LINKDOWN, "Physical or logical link down"}, {ROAR_ERROR_INTERRUPTED, "Operation was interruped"}, {ROAR_ERROR_CAUSALITY, "Causality error"}, {ROAR_ERROR_QUOTA, "Quota exceeded"}, {ROAR_ERROR_BADLIB, "Accessing a corrupted shared library"}, {ROAR_ERROR_NOMEDIUM, "No medium found"}, {ROAR_ERROR_NOTUNIQ, "Name not unique"}, {ROAR_ERROR_ILLSEQ, "Illegal byte sequence"}, {ROAR_ERROR_ADDRINUSE, "Address in use"}, {ROAR_ERROR_HOLE, "Hole in data"}, {ROAR_ERROR_BADVERSION, "Bad version"}, {ROAR_ERROR_NSVERSION, "Not supported version"}, {ROAR_ERROR_BADMAGIC, "Bad magic number"}, {ROAR_ERROR_LOSTSYNC, "Lost synchronization"}, {ROAR_ERROR_BADSEEK, "Can not seek to destination position"}, {ROAR_ERROR_NOSEEK, "Seeking not supported on resource"}, {ROAR_ERROR_BADCKSUM, "Data integrity error"}, {ROAR_ERROR_NOHORSE, "Mount failed"}, {ROAR_ERROR_CHERNOBYL, "Fatal device error"}, {ROAR_ERROR_NOHUG, "Device needs love"}, {ROAR_ERROR_TEXTBUSY, "Text file busy"}, {ROAR_ERROR_NOTEMPTY, "Directory not empty"}, {ROAR_ERROR_NODEUNREACH, "Node is unreachable"}, {ROAR_ERROR_IDREMOVED, "Identifier removed"}, {ROAR_ERROR_INPROGRESS, "Operation in progress"}, {ROAR_ERROR_NOCHILD, "No child processes or object"}, {ROAR_ERROR_NETUNREACH, "Network unreachable"}, {ROAR_ERROR_CANCELED, "Operation canceled"}, {ROAR_ERROR_ISDIR, "Is a directory"}, {ROAR_ERROR_NOTDIR, "Not a directory"}, {ROAR_ERROR_BADEXEC, "Executable file format error"}, {ROAR_ERROR_ISCONN, "Socket or Object is connected"}, {ROAR_ERROR_DEADLOCK, "Resource deadlock would occur"}, {ROAR_ERROR_CONNRST, "Connection reset"}, {ROAR_ERROR_BADFH, "Bad file handle"}, {ROAR_ERROR_NOTSOCK, "Not a socket"}, {ROAR_ERROR_TOOMANYARGS, "Argument list too long"}, {ROAR_ERROR_TOOLARGE, "File or Object too large"}, {ROAR_ERROR_DESTADDRREQ, "Destination address required"}, {ROAR_ERROR_AFNOTSUP, "Address family not supported"}, {ROAR_ERROR_NOPOWER, "Operation can not be completed because we are low on power"}, {ROAR_ERROR_USER, "Error in front of screen"}, {ROAR_ERROR_NFILE, "Too many filesobjects open in system"}, {ROAR_ERROR_STALE, "Stale file handle or object"}, {ROAR_ERROR_XDEVLINK, "Cross-device link"}, {ROAR_ERROR_MLINK, "Too many links to file or object"}, {ROAR_ERROR_NONET, "Not connected to any network"}, {ROAR_ERROR_CONNRSTNET, "Connection reset by network"}, {ROAR_ERROR_CONNABORTED, "Connection aborted"}, {ROAR_ERROR_BADHOST, "Bad host software or hardware"}, {ROAR_ERROR_SWITCHPROTO, "Switch protocol"}, {ROAR_ERROR_MOVEDPERM, "Moved Permanently"}, {ROAR_ERROR_MOVEDTEMP, "Moved Temporary"}, {ROAR_ERROR_USEPROXY, "Use Proxy server"}, {ROAR_ERROR_SEEOTHER, "See other resource"}, {ROAR_ERROR_GONE, "Resource gone"}, {ROAR_ERROR_BADLICENSE, "Bad License"}, {ROAR_ERROR_NEEDPAYMENT, "Payment Required"}, {ROAR_ERROR_NSTYPE, "Type or Format not supported"}, {ROAR_ERROR_CENSORED, "Access denied because of censorship"}, {ROAR_ERROR_BADSTATE, "Object is in bad/wrong state"}, {ROAR_ERROR_DISABLED, "This has been disabled by the administrator"}, {-1, NULL} }, msgs_funny[] = { // {ROAR_ERROR_UNKNOWN, "Unknown (maybe no) error"}, {ROAR_ERROR_NONE, "No error, huh?"}, {ROAR_ERROR_PERM, "Little kitty is not allowed to do this"}, {ROAR_ERROR_NOENT, "Mouse not found"}, // {ROAR_ERROR_BADMSG, "Bad message"}, {ROAR_ERROR_BUSY, "Another kitty is playing with this mouse"}, // {ROAR_ERROR_CONNREFUSED, "Connection refused"}, // {ROAR_ERROR_NOSYS, "Function not implemented"}, // {ROAR_ERROR_NOTSUP, "Operation not supported"}, {ROAR_ERROR_PIPE, "Flood"}, // {ROAR_ERROR_PROTO, "Protocol error"}, // {ROAR_ERROR_RANGE, "Result too largegeneral out of range"}, // {ROAR_ERROR_MSGSIZE, "Message too long"}, // {ROAR_ERROR_NOMEM, "Not enough space"}, // {ROAR_ERROR_INVAL, "Invalid argument"}, // {ROAR_ERROR_ALREADY, "Connection already in progress"}, {ROAR_ERROR_BADRQC, "Stupid staff"}, // {ROAR_ERROR_DOM, "Mathematics argument out of domain of function"}, // {ROAR_ERROR_EXIST, "File or object exists"}, // {ROAR_ERROR_FAULT, "Bad address"}, // {ROAR_ERROR_IO, "IO-Error"}, // {ROAR_ERROR_KEYEXPIRED, "Key has expired"}, // {ROAR_ERROR_KEYREJECTED, "Key was rejected by service"}, // {ROAR_ERROR_LOOP, "Too many recursions"}, // {ROAR_ERROR_MFILE, "Too many open files or objects"}, {ROAR_ERROR_NAMETOOLONG, "Staff can not remember long names"}, // {ROAR_ERROR_NODATA, "No message is available on the read queue"}, {ROAR_ERROR_NODEV, "No such mouse"}, // {ROAR_ERROR_NODRV, "No such driver"}, {ROAR_ERROR_NOSPC, "Too many fish on desk"}, // {ROAR_ERROR_TYPEMM, "Type missmatch. Object of diffrent type required"}, // {ROAR_ERROR_NORSYS, "Feature not implemented by remote end"}, // {ROAR_ERROR_NOTCONN, "Socket or object not connected"}, // {ROAR_ERROR_PROTONOSUP, "Protocol not supported"}, // {ROAR_ERROR_RIO, "Remote IO Error"}, {ROAR_ERROR_RO, "Touching disallowed"}, // {ROAR_ERROR_TIMEDOUT, "Connection timed out"}, // {ROAR_ERROR_AGAIN, "Resource temporarily unavailable"}, // {ROAR_ERROR_NOISE, "Line too noisy"}, // {ROAR_ERROR_LINKDOWN, "Physical or logical link down"}, // {ROAR_ERROR_INTERRUPTED, "Operation was interruped"}, // {ROAR_ERROR_CAUSALITY, "Causality error"}, // {ROAR_ERROR_QUOTA, "Quota exceeded"}, // {ROAR_ERROR_BADLIB, "Accessing a corrupted shared library"}, // {ROAR_ERROR_NOMEDIUM, "No medium found"}, // {ROAR_ERROR_NOTUNIQ, "Name not unique"}, // {ROAR_ERROR_ILLSEQ, "Illegal byte sequence"}, // {ROAR_ERROR_ADDRINUSE, "Address in use"}, {ROAR_ERROR_HOLE, "Hole in wall"}, // {ROAR_ERROR_BADVERSION, "Bad version"}, // {ROAR_ERROR_NSVERSION, "Not supported version"}, {ROAR_ERROR_BADMAGIC, "Magician's fault"}, // {ROAR_ERROR_LOSTSYNC, "Lost synchronization"}, // {ROAR_ERROR_BADSEEK, "Can not seek to destination position"}, // {ROAR_ERROR_NOSEEK, "Seeking not supported on resource"}, // {ROAR_ERROR_BADCKSUM, "Data integrity error"}, {ROAR_ERROR_NOHORSE, "No horse"}, // {ROAR_ERROR_CHERNOBYL, "Fatal device error"}, {ROAR_ERROR_NOHUG, "No hug"}, // {ROAR_ERROR_TEXTBUSY, "Text file busy"}, // {ROAR_ERROR_NOTEMPTY, "Directory not empty"}, // {ROAR_ERROR_NODEUNREACH, "Node is unreachable"}, // {ROAR_ERROR_IDREMOVED, "Identifier removed"}, // {ROAR_ERROR_INPROGRESS, "Operation in progress"}, // {ROAR_ERROR_NOCHILD, "No child processesobject"}, // {ROAR_ERROR_NETUNREACH, "Network unreachable"}, // {ROAR_ERROR_CANCELED, "Operation canceled"}, // {ROAR_ERROR_ISDIR, "Is a directory"}, // {ROAR_ERROR_NOTDIR, "Not a directory"}, // {ROAR_ERROR_BADEXEC, "Executable file format error"}, // {ROAR_ERROR_ISCONN, "Socket/Object is connected"}, {ROAR_ERROR_DEADLOCK, "Mouse would die"}, // {ROAR_ERROR_CONNRST, "Connection reset"}, // {ROAR_ERROR_BADFH, "Bad file handle"}, // {ROAR_ERROR_NOTSOCK, "Not a socket"}, // {ROAR_ERROR_TOOMANYARGS, "Argument list too long"}, // {ROAR_ERROR_TOOLARGE, "File/Object too large"}, // {ROAR_ERROR_DESTADDRREQ, "Destination address required"}, // {ROAR_ERROR_AFNOTSUP, "Address family not supported"}, // {ROAR_ERROR_NOPOWER, "Operation can not be completed because we are low on power"}, // {ROAR_ERROR_USER, "Error in front of screen"}, // {ROAR_ERROR_NFILE, "Too many filesobjects open in system"}, // {ROAR_ERROR_STALE, "Stale file handle or object"}, {ROAR_ERROR_XDEVLINK, "Mice tails too short for kinking"}, // {ROAR_ERROR_MLINK, "Too many links to file or object"}, // {ROAR_ERROR_NONET, "Not connected to any network"}, // {ROAR_ERROR_CONNRSTNET, "Connection reset by network"}, // {ROAR_ERROR_CONNABORTED, "Connection aborted"}, // {ROAR_ERROR_BADHOST, "Bad host software or hardware"}, // {ROAR_ERROR_SWITCHPROTO, "Switch protocol"}, // {ROAR_ERROR_MOVEDPERM, "Moved Permanently"}, // {ROAR_ERROR_MOVEDTEMP, "Moved Temporary"}, // {ROAR_ERROR_USEPROXY, "Use Proxy server"}, // {ROAR_ERROR_SEEOTHER, "See other resource"}, // {ROAR_ERROR_GONE, "Resource gone"}, {-1, NULL} }; int i; if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_MS ) { for (i = 0; msgs[i].msg != NULL; i++) { if ( msgs[i].err == error ) { return roar_error2str_ms(error, msgs[i].msg); } } return roar_error2str_ms(error, "<<<unknown error>>>"); } if ( config->opmode == ROAR_LIBROAR_CONFIG_OPMODE_FUNNY ) for (i = 0; msgs_funny[i].msg != NULL; i++) if ( msgs_funny[i].err == error ) return msgs_funny[i].msg; for (i = 0; msgs[i].msg != NULL; i++) if ( msgs[i].err == error ) return msgs[i].msg; return NULL; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/file.c������������������������������������������������������������������0000644�0001750�0001750�00000006257�12264733540�015214� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//file.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_file_codecdetect(const char * buf, const int len) { int codec = -1; if ( len > 3 ) { if ( strncmp(buf, "OggS", 4) == 0 ) { codec = ROAR_CODEC_OGG_GENERAL; if ( len > 32 ) { // this is 5 bytes after the end of the header if ( strncmp(buf+28, "\177FLAC", 5) == 0 ) { codec = ROAR_CODEC_OGG_FLAC; } else if ( strncmp(buf+28, "Speex", 5) == 0 ) { codec = ROAR_CODEC_OGG_SPEEX; } else if ( len > 34 ) { // this is 7 bytes after the end of the header if ( strncmp(buf+28, "\001vorbis", 7) == 0 ) codec = ROAR_CODEC_OGG_VORBIS; } } } else if ( strncmp(buf, "MThd", 4) == 0 ) { codec = ROAR_CODEC_MIDI_FILE; } else if ( strncmp(buf, "RIFF", 4) == 0 ) { if ( len > 15 ) { if ( strncmp(buf+8, "WAVEfmt ", 8) == 0 ) codec = ROAR_CODEC_RIFF_WAVE; } } else if ( strncmp(buf, "Roar", 4) == 0 ) { if ( len > ROAR_SPEEX_MAGIC_LEN ) { if ( strncmp(buf, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) == 0 ) codec = ROAR_CODEC_ROAR_SPEEX; #if ROAR_SPEEX_MAGIC_LEN < ROAR_CELT_MAGIC_LEN } if ( len > ROAR_CELT_MAGIC_LEN ) { #endif if ( strncmp(buf, ROAR_CELT_MAGIC_0, ROAR_CELT_MAGIC_LEN) == 0 || strncmp(buf, ROAR_CELT_MAGIC_1, ROAR_CELT_MAGIC_LEN) == 0 ) codec = ROAR_CODEC_ROAR_CELT; } } else if ( strncmp(buf, "fLaC", 4) == 0 ) { codec = ROAR_CODEC_FLAC; } else if ( strncmp(buf, ".snd", 4) == 0 ) { codec = ROAR_CODEC_AU; } else if ( len > 7 && strncmp(buf, "RAUM-CF0", 8) == 0 ) { codec = ROAR_CODEC_RAUM; } } return codec; } const char * roar_cdromdevice (void) { const char * k; if ( (k = roar_env_get("CDDA_DEVICE")) != NULL ) return k; #ifdef ROAR_DEFAULT_CDROM return ROAR_DEFAULT_CDROM; #endif roar_err_set(ROAR_ERROR_NODEV); return NULL; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/hash.c������������������������������������������������������������������0000644�0001750�0001750�00000031502�12264733540�015207� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//hash.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_LIBGCRYPT #include <gcrypt.h> #endif struct roar_hash_state { struct roar_hash_cmds * cmds; void * state; }; static const struct hashes { const roar_hash_t id; const char * name; const ssize_t dlen; } _libroar_hashes[] = { /* grep '^ +HT_' doc/new-cmds | sed 's/ *#(.*)$//; s/^ +HT_//; s/ *=.*$//' | while read n; do printf " {ROAR_HT_%-12s \"%-12s -1 },\n" $n, $n\",; done */ {ROAR_HT_NONE, "NONE", -1 }, {ROAR_HT_MD5, "MD5", 16 }, {ROAR_HT_SHA1, "SHA1", 20 }, {ROAR_HT_RIPEMD160, "RIPEMD160", 20 }, {ROAR_HT_MD2, "MD2", -1 }, {ROAR_HT_TIGER, "TIGER", 24 }, {ROAR_HT_HAVAL, "HAVAL", -1 }, {ROAR_HT_SHA256, "SHA256", 32 }, {ROAR_HT_SHA384, "SHA384", 48 }, {ROAR_HT_SHA512, "SHA512", 64 }, {ROAR_HT_SHA224, "SHA224", 28 }, {ROAR_HT_MD4, "MD4", 16 }, {ROAR_HT_CRC32, "CRC32", 4 }, {ROAR_HT_RFC1510, "RFC1510", 4 }, {ROAR_HT_RFC2440, "RFC2440", 3 }, {ROAR_HT_WHIRLPOOL, "WHIRLPOOL", 64 }, {ROAR_HT_UUID, "UUID", 16 }, {ROAR_HT_GTN8, "GTN8", 1 }, {ROAR_HT_GTN16, "GTN16", 2 }, {ROAR_HT_GTN32, "GTN32", 4 }, {ROAR_HT_GTN64, "GTN64", 8 }, {ROAR_HT_CLIENTID, "CLIENTID", -1 }, {ROAR_HT_STREAMID, "STREAMID", -1 }, {ROAR_HT_SOURCEID, "SOURCEID", -1 }, {ROAR_HT_SAMPLEID, "SAMPLEID", -1 }, {ROAR_HT_MIXERID, "MIXERID", -1 }, {ROAR_HT_BRIDGEID, "BRIDGEID", -1 }, {ROAR_HT_LISTENID, "LISTENID", -1 }, {ROAR_HT_ACTIONID, "ACTIONID", -1 }, {ROAR_HT_MSGQUEUEID, "MSGQUEUEID", -1 }, {ROAR_HT_MSGBUSID, "MSGBUSID", -1 }, {ROAR_HT_GTIN8, "GTIN8", 4 }, {ROAR_HT_GTIN13, "GTIN13", 8 }, {ROAR_HT_ISBN10, "ISBN10", 8 }, {ROAR_HT_ISBN13, "ISBN13", 8 }, {ROAR_HT_ADLER32, "ADLER32", 4 }, {-1, NULL, -1} }; int roar_hash_sha1_init(void * state); int roar_hash_sha1_uninit(void * state); int roar_hash_sha1_digest(void * state, void * digest, size_t * len); int roar_hash_sha1_proc_block(void * state, const void * block); int roar_hash_sha1_proc(void * state, const void * data, size_t len); static struct roar_hash_cmds _libroar_hash_cmds[] = { {ROAR_HT_TIGER, sizeof(struct roar_hash_tiger), 512, (int (*)(void *))roar_hash_tiger_init, (int (*)(void *))roar_hash_tiger_uninit, (int (*)(void *, void *, size_t *))roar_hash_tiger_get_digest, (int (*)(void *, const void *))roar_hash_tiger_proc_block, (int (*)(void *, const void *, size_t))roar_hash_tiger_proc }, {ROAR_HT_RFC2440, sizeof(uint32_t), -1, roar_hash_crc24_init, NULL, roar_hash_crc24_digest, NULL, roar_hash_crc24_proc }, {ROAR_HT_ADLER32, sizeof(uint32_t), -1, roar_hash_adler32_init, NULL, roar_hash_adler32_digest, NULL, roar_hash_adler32_proc }, {ROAR_HT_SHA1, sizeof(struct roar_hash_sha1), 64, roar_hash_sha1_init, roar_hash_sha1_uninit, roar_hash_sha1_digest, roar_hash_sha1_proc_block, roar_hash_sha1_proc}, {-1, -1, -1, NULL, NULL, NULL, NULL, NULL} }; static struct roar_hash_cmds * roar_ht2cmds(const roar_hash_t ht) { size_t i; for(i = 0; _libroar_hash_cmds[i].algo != (roar_hash_t)-1; i++) if ( _libroar_hash_cmds[i].algo == ht ) return &(_libroar_hash_cmds[i]); roar_err_set(ROAR_ERROR_NOENT); return NULL; } static inline int roar_ht2gcrypt_tested (const roar_hash_t ht) { #ifdef ROAR_HAVE_LIBGCRYPT const char * name; if ( ht > 512 ) return -1; // test the algo: name = gcry_md_algo_name(ht); if ( name == NULL ) return -1; if ( *name == 0 ) return -1; return ht; #else return -1; #endif } const char * roar_ht2str (const roar_hash_t ht) { int i; for (i = 0; _libroar_hashes[i].id != (roar_hash_t)-1; i++) if ( _libroar_hashes[i].id == ht ) return _libroar_hashes[i].name; roar_err_set(ROAR_ERROR_NOENT); return NULL; } roar_hash_t roar_str2ht (const char * ht) { int i; for (i = 0; _libroar_hashes[i].id != (roar_hash_t)-1; i++) if ( !strcasecmp(_libroar_hashes[i].name, ht) ) return _libroar_hashes[i].id; roar_err_set(ROAR_ERROR_NOENT); return -1; } ssize_t roar_ht_digestlen (const roar_hash_t ht) { int i; for (i = 0; _libroar_hashes[i].id != (uint_least32_t)-1; i++) if ( _libroar_hashes[i].id == ht ) return _libroar_hashes[i].dlen; roar_err_set(ROAR_ERROR_NOENT); return -1; } static void _bin2hex(char * out, char * in, size_t inlen, int uppercase) { const char * tab = uppercase ? "0123456789ABCDEF" : "0123456789abcdef"; unsigned char c; int nib0, nib1; for (; inlen; inlen--) { c = *(in++); nib0 = (c & 0x0F) >> 0; nib1 = (c & 0xF0) >> 4; // printf("inlen=%zu, c=%u, nibs={%i, %i}\n", inlen, (unsigned)c, nib1, nib0); *(out++) = tab[nib1]; *(out++) = tab[nib0]; } *out = 0; } ssize_t roar_hash_digest2str(char * out, size_t outlen, void * digest, size_t digestlen, roar_hash_t ht) { ssize_t slen = roar_ht_digestlen(ht); union { long long int llsi; } tmp; enum { HEX, TIGER, // BASE64, UUID, INT, GTIN } type = HEX; if ( out == NULL || digest == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( !(slen == -1 || (ssize_t)digestlen == slen) ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } switch (ht) { case ROAR_HT_TIGER: type = TIGER; break; case ROAR_HT_UUID: type = UUID; break; case ROAR_HT_CLIENTID: case ROAR_HT_STREAMID: case ROAR_HT_SOURCEID: case ROAR_HT_SAMPLEID: case ROAR_HT_MIXERID: case ROAR_HT_BRIDGEID: case ROAR_HT_LISTENID: case ROAR_HT_ACTIONID: case ROAR_HT_MSGQUEUEID: case ROAR_HT_MSGBUSID: type = INT; break; case ROAR_HT_GTIN8: case ROAR_HT_GTIN13: case ROAR_HT_ISBN10: type = GTIN; break; } switch (type) { case HEX: if ( outlen < (digestlen*2 + 1) ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } _bin2hex(out, digest, digestlen, 0); break; case UUID: if ( outlen < 37 || digestlen != 16 ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } _bin2hex(out+ 0, digest+ 0, 4, 0); out[ 8] = '-'; _bin2hex(out+ 9, digest+ 4, 2, 0); out[13] = '-'; _bin2hex(out+14, digest+ 6, 2, 0); out[18] = '-'; _bin2hex(out+19, digest+ 8, 2, 0); out[23] = '-'; _bin2hex(out+24, digest+10, 6, 0); // printf("%s\n", out+24); break; case TIGER: if ( outlen < 51 || digestlen != 24 ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } _bin2hex(out+ 0, digest+ 0, 8, 1); out[16] = ' '; _bin2hex(out+17, digest+ 8, 8, 1); out[33] = ' '; _bin2hex(out+34, digest+16, 8, 1); break; case INT: switch (digestlen) { case 1: tmp.llsi = *(_LIBROAR_GOOD_CAST char*)digest; break; case 2: tmp.llsi = ROAR_NET2HOST16(*(int16_t*)digest); break; case 4: tmp.llsi = ROAR_NET2HOST32(*(int32_t*)digest); break; default: roar_err_set(ROAR_ERROR_NOSYS); return -1; break; } snprintf(out, outlen-1, "%" LIBROAR__ll "i", (LIBROAR__longlong int)tmp.llsi); break; default: roar_err_set(ROAR_ERROR_NOSYS); return -1; } out[outlen-1] = 0; return roar_mm_strlen(out); } int roar_ht_is_supported(const roar_hash_t ht) { roar_crypto_init(); if ( roar_ht2cmds(ht) != NULL ) return 1; #ifdef ROAR_HAVE_LIBGCRYPT if ( roar_ht2gcrypt_tested(ht) == -1 ) return 0; return 1; #else return 0; #endif } struct roar_hash_state * roar_hash_new(roar_hash_t algo) { struct roar_hash_cmds * cmds = roar_ht2cmds(algo); struct roar_hash_state * self; if ( cmds == NULL ) return NULL; self = roar_mm_malloc(sizeof(struct roar_hash_state)); if ( self == NULL ) return NULL; memset(self, 0, sizeof(struct roar_hash_state)); self->cmds = cmds; self->state = roar_mm_malloc(cmds->statelen); if ( self->state == NULL ) { roar_mm_free(self); return NULL; } memset(self->state, 0, cmds->statelen); if ( cmds->init != NULL ) { if ( cmds->init(self->state) == -1 ) { roar_mm_free(self->state); roar_mm_free(self); return NULL; } } return self; } int roar_hash_free(struct roar_hash_state * state) { int ret = 0; if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( state->cmds->uninit != NULL ) ret = state->cmds->uninit(state->state); // clear crypto data. memset(state->state, 0, state->cmds->statelen); roar_mm_free(state->state); memset(state, 0, sizeof(struct roar_hash_state)); roar_mm_free(state); return ret; } int roar_hash_digest(struct roar_hash_state * state, void * digest, size_t * len) { if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( state->cmds->digest == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } return state->cmds->digest(state->state, digest, len); } int roar_hash_proc(struct roar_hash_state * state, const void * data, size_t len) { if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( state->cmds->proc == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } return state->cmds->proc(state->state, data, len); } int roar_hash_buffer(void * digest, const void * data, size_t datalen, roar_hash_t algo) { roar_crypto_init(); return roar_hash_salted_buffer(digest, data, datalen, algo, NULL, 0); } #ifdef ROAR_HAVE_LIBGCRYPT static inline int roar_hash_salted_buffer_gcrypt(void * digest, const void * data, size_t datalen, roar_hash_t algo, const void * salt, size_t saltlen) { gcry_md_hd_t hdl; roar_crypto_init(); algo = roar_ht2gcrypt_tested(algo); if ( algo == (roar_hash_t)-1 ) return -1; if ( salt == NULL ) { // optimized for unsalted: gcry_md_hash_buffer(algo, digest, data, datalen); return 0; } else { if ( gcry_md_open(&hdl, algo, 0) != 0 ) return -1; gcry_md_write(hdl, data, datalen); gcry_md_write(hdl, salt, saltlen); memcpy(digest, gcry_md_read(hdl, algo), gcry_md_get_algo_dlen(algo)); gcry_md_close(hdl); } return 0; } #endif int roar_hash_salted_buffer(void * digest, const void * data, size_t datalen, roar_hash_t algo, const void * salt, size_t saltlen) { struct roar_hash_state * state; size_t len; int ret = 0; ROAR_DBG("roar_hash_salted_buffer(digest=%p, data=%p, datalen=%llu, algo=%i, salt=%p, saltlen=%llu) = ?", digest, data, (unsigned long long int)datalen, algo, salt, (unsigned long long int)saltlen); if ( digest == NULL || data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } len = roar_ht_digestlen(algo); if ( len == (size_t)-1 ) /* this is a hack to avoid len to be of type ssize_t which breaks following code */ return -1; if ( (state = roar_hash_new(algo)) != NULL ) { ROAR_DBG("roar_hash_salted_buffer(*): ret=%i", ret); if ( roar_hash_proc(state, data, datalen) == -1 ) ret = -1; ROAR_DBG("roar_hash_salted_buffer(*): ret=%i", ret); if ( saltlen != 0 ) if ( roar_hash_proc(state, salt, saltlen) == -1 ) ret = -1; ROAR_DBG("roar_hash_salted_buffer(*): ret=%i", ret); if ( roar_hash_digest(state, digest, &len) == -1 ) ret = -1; ROAR_DBG("roar_hash_salted_buffer(*): ret=%i", ret); if ( roar_hash_free(state) == -1 ) ret = -1; ROAR_DBG("roar_hash_salted_buffer(*): ret=%i", ret); return ret; } ROAR_DBG("roar_hash_salted_buffer(*): state=%p", state); #ifdef ROAR_HAVE_LIBGCRYPT return roar_hash_salted_buffer_gcrypt(digest, data, datalen, algo, salt, saltlen); #else roar_err_set(ROAR_ERROR_NOTSUP); return -1; #endif } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/hash_sha1.c�������������������������������������������������������������0000644�0001750�0001750�00000021270�12264733540�016124� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//hashh_sha1.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * Copyright (C) Steve Reid <steve@edmweb.com> * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define SHA1_BLOCK_LENGTH 64 #define SHA1_DIGEST_LENGTH 20 #define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) union uint864uint3216 { uint8_t c[64]; uint32_t l[16]; }; int roar_hash_sha1_proc(void * state, const void * data, size_t len); #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* * blk0() and blk() perform the initial expand. * I got the idea of expanding during the round function from SSLeay */ #if BYTE_ORDER == LITTLE_ENDIAN # define blk0(i) (compblock->l[i] = (rol(compblock->l[i],24)&0xFF00FF00) \ |(rol(compblock->l[i],8)&0x00FF00FF)) #else # define blk0(i) compblock->l[i] #endif #define blk(i) (compblock->l[i&15] = rol(compblock->l[(i+13)&15]^compblock->l[(i+8)&15] \ ^compblock->l[(i+2)&15]^compblock->l[i&15],1)) /* * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); int roar_hash_sha1_init(void * state) { struct roar_hash_sha1 * context = state; if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(context, 0, sizeof(struct roar_hash_sha1)); context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; return 0; } int roar_hash_sha1_uninit(void * state) { (void)state; return 0; } int roar_hash_sha1_digest(void * state, void * digest, size_t * len) { struct roar_hash_sha1 * context = state; uint64_t count; int i; if ( state == NULL || digest == NULL || len == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( context->is_final ) { roar_err_set(ROAR_ERROR_BUSY); return -1; } if ( *len < SHA1_DIGEST_LENGTH ) { roar_err_set(ROAR_ERROR_NOSPC); return -1; } *len = SHA1_DIGEST_LENGTH; context->count *= 8; count = ROAR_HOST2NET64(context->count); roar_hash_sha1_proc(state, "\200", 1); // TODO: make this calc the correct length directly. // this is inefficent. while (context->in_buffer != (SHA1_BLOCK_LENGTH - 8)) { ROAR_DBG("roar_hash_sha1_digest(state=%p, digest=%p, len=%p): context->in_buffer = %i", state, digest, len, (int)context->in_buffer); roar_hash_sha1_proc(state, "\0", 1); } roar_hash_sha1_proc(state, &count, 8); for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { ((uint8_t *)digest)[i] = (uint8_t)((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } memset(context, 0, sizeof(struct roar_hash_sha1)); context->is_final = 1; return 0; } int roar_hash_sha1_proc_block(void * state, const void * block) { struct roar_hash_sha1 * context = state; uint32_t a, b, c, d, e; uint8_t workspace[SHA1_BLOCK_LENGTH]; union uint864uint3216 * compblock = (union uint864uint3216 *)(void*)workspace; if ( state == NULL || block == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( context->is_final ) { roar_err_set(ROAR_ERROR_BUSY); return -1; } if ( context->in_buffer ) { return roar_hash_sha1_proc(state, block, SHA1_BLOCK_LENGTH); } memcpy(compblock, block, SHA1_BLOCK_LENGTH); /* Copy context->state[] to working vars */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; return 0; } int roar_hash_sha1_proc(void * state, const void * data, size_t len) { struct roar_hash_sha1 * context = state; size_t buflen; ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); if ( state == NULL || data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( context->is_final ) { roar_err_set(ROAR_ERROR_BUSY); return -1; } ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); context->count += len; if ( context->in_buffer ) { ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); buflen = len > (SHA1_BLOCK_LENGTH - context->in_buffer) ? SHA1_BLOCK_LENGTH - context->in_buffer : len; memcpy(context->buffer + context->in_buffer, data, buflen); context->in_buffer += buflen; if ( context->in_buffer == SHA1_BLOCK_LENGTH ) { ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); context->in_buffer = 0; roar_hash_sha1_proc_block(state, context->buffer); } else { ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = 0", state, data, (long long unsigned int)len); return 0; } len -= buflen; data += buflen; } ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); while (len >= SHA1_BLOCK_LENGTH) { ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); roar_hash_sha1_proc_block(state, data); len -= SHA1_BLOCK_LENGTH; data += SHA1_BLOCK_LENGTH; } ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); if ( len ) { memcpy(context->buffer, data, len); context->in_buffer = len; } ROAR_DBG("roar_hash_sha1_proc(state=%p, data=%p, len=%llu) = 0", state, data, (long long unsigned int)len); return 0; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/hash_tiger.c������������������������������������������������������������0000644�0001750�0001750�00000140201�12264733541�016377� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//hash_tiger.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define STATE_LEN (3*8) #define PSTATE_LEN (4*8) #define DIGEST_LEN STATE_LEN #define BLOCK_LEN (64) static uint64_t table[4*256] = { 0x02AAB17CF7E90C5ELLU /* 0 */, 0xAC424B03E243A8ECLLU /* 1 */, 0x72CD5BE30DD5FCD3LLU /* 2 */, 0x6D019B93F6F97F3ALLU /* 3 */, 0xCD9978FFD21F9193LLU /* 4 */, 0x7573A1C9708029E2LLU /* 5 */, 0xB164326B922A83C3LLU /* 6 */, 0x46883EEE04915870LLU /* 7 */, 0xEAACE3057103ECE6LLU /* 8 */, 0xC54169B808A3535CLLU /* 9 */, 0x4CE754918DDEC47CLLU /* 10 */, 0x0AA2F4DFDC0DF40CLLU /* 11 */, 0x10B76F18A74DBEFALLU /* 12 */, 0xC6CCB6235AD1AB6ALLU /* 13 */, 0x13726121572FE2FFLLU /* 14 */, 0x1A488C6F199D921ELLU /* 15 */, 0x4BC9F9F4DA0007CALLU /* 16 */, 0x26F5E6F6E85241C7LLU /* 17 */, 0x859079DBEA5947B6LLU /* 18 */, 0x4F1885C5C99E8C92LLU /* 19 */, 0xD78E761EA96F864BLLU /* 20 */, 0x8E36428C52B5C17DLLU /* 21 */, 0x69CF6827373063C1LLU /* 22 */, 0xB607C93D9BB4C56ELLU /* 23 */, 0x7D820E760E76B5EALLU /* 24 */, 0x645C9CC6F07FDC42LLU /* 25 */, 0xBF38A078243342E0LLU /* 26 */, 0x5F6B343C9D2E7D04LLU /* 27 */, 0xF2C28AEB600B0EC6LLU /* 28 */, 0x6C0ED85F7254BCACLLU /* 29 */, 0x71592281A4DB4FE5LLU /* 30 */, 0x1967FA69CE0FED9FLLU /* 31 */, 0xFD5293F8B96545DBLLU /* 32 */, 0xC879E9D7F2A7600BLLU /* 33 */, 0x860248920193194ELLU /* 34 */, 0xA4F9533B2D9CC0B3LLU /* 35 */, 0x9053836C15957613LLU /* 36 */, 0xDB6DCF8AFC357BF1LLU /* 37 */, 0x18BEEA7A7A370F57LLU /* 38 */, 0x037117CA50B99066LLU /* 39 */, 0x6AB30A9774424A35LLU /* 40 */, 0xF4E92F02E325249BLLU /* 41 */, 0x7739DB07061CCAE1LLU /* 42 */, 0xD8F3B49CECA42A05LLU /* 43 */, 0xBD56BE3F51382F73LLU /* 44 */, 0x45FAED5843B0BB28LLU /* 45 */, 0x1C813D5C11BF1F83LLU /* 46 */, 0x8AF0E4B6D75FA169LLU /* 47 */, 0x33EE18A487AD9999LLU /* 48 */, 0x3C26E8EAB1C94410LLU /* 49 */, 0xB510102BC0A822F9LLU /* 50 */, 0x141EEF310CE6123BLLU /* 51 */, 0xFC65B90059DDB154LLU /* 52 */, 0xE0158640C5E0E607LLU /* 53 */, 0x884E079826C3A3CFLLU /* 54 */, 0x930D0D9523C535FDLLU /* 55 */, 0x35638D754E9A2B00LLU /* 56 */, 0x4085FCCF40469DD5LLU /* 57 */, 0xC4B17AD28BE23A4CLLU /* 58 */, 0xCAB2F0FC6A3E6A2ELLU /* 59 */, 0x2860971A6B943FCDLLU /* 60 */, 0x3DDE6EE212E30446LLU /* 61 */, 0x6222F32AE01765AELLU /* 62 */, 0x5D550BB5478308FELLU /* 63 */, 0xA9EFA98DA0EDA22ALLU /* 64 */, 0xC351A71686C40DA7LLU /* 65 */, 0x1105586D9C867C84LLU /* 66 */, 0xDCFFEE85FDA22853LLU /* 67 */, 0xCCFBD0262C5EEF76LLU /* 68 */, 0xBAF294CB8990D201LLU /* 69 */, 0xE69464F52AFAD975LLU /* 70 */, 0x94B013AFDF133E14LLU /* 71 */, 0x06A7D1A32823C958LLU /* 72 */, 0x6F95FE5130F61119LLU /* 73 */, 0xD92AB34E462C06C0LLU /* 74 */, 0xED7BDE33887C71D2LLU /* 75 */, 0x79746D6E6518393ELLU /* 76 */, 0x5BA419385D713329LLU /* 77 */, 0x7C1BA6B948A97564LLU /* 78 */, 0x31987C197BFDAC67LLU /* 79 */, 0xDE6C23C44B053D02LLU /* 80 */, 0x581C49FED002D64DLLU /* 81 */, 0xDD474D6338261571LLU /* 82 */, 0xAA4546C3E473D062LLU /* 83 */, 0x928FCE349455F860LLU /* 84 */, 0x48161BBACAAB94D9LLU /* 85 */, 0x63912430770E6F68LLU /* 86 */, 0x6EC8A5E602C6641CLLU /* 87 */, 0x87282515337DDD2BLLU /* 88 */, 0x2CDA6B42034B701BLLU /* 89 */, 0xB03D37C181CB096DLLU /* 90 */, 0xE108438266C71C6FLLU /* 91 */, 0x2B3180C7EB51B255LLU /* 92 */, 0xDF92B82F96C08BBCLLU /* 93 */, 0x5C68C8C0A632F3BALLU /* 94 */, 0x5504CC861C3D0556LLU /* 95 */, 0xABBFA4E55FB26B8FLLU /* 96 */, 0x41848B0AB3BACEB4LLU /* 97 */, 0xB334A273AA445D32LLU /* 98 */, 0xBCA696F0A85AD881LLU /* 99 */, 0x24F6EC65B528D56CLLU /* 100 */, 0x0CE1512E90F4524ALLU /* 101 */, 0x4E9DD79D5506D35ALLU /* 102 */, 0x258905FAC6CE9779LLU /* 103 */, 0x2019295B3E109B33LLU /* 104 */, 0xF8A9478B73A054CCLLU /* 105 */, 0x2924F2F934417EB0LLU /* 106 */, 0x3993357D536D1BC4LLU /* 107 */, 0x38A81AC21DB6FF8BLLU /* 108 */, 0x47C4FBF17D6016BFLLU /* 109 */, 0x1E0FAADD7667E3F5LLU /* 110 */, 0x7ABCFF62938BEB96LLU /* 111 */, 0xA78DAD948FC179C9LLU /* 112 */, 0x8F1F98B72911E50DLLU /* 113 */, 0x61E48EAE27121A91LLU /* 114 */, 0x4D62F7AD31859808LLU /* 115 */, 0xECEBA345EF5CEAEBLLU /* 116 */, 0xF5CEB25EBC9684CELLU /* 117 */, 0xF633E20CB7F76221LLU /* 118 */, 0xA32CDF06AB8293E4LLU /* 119 */, 0x985A202CA5EE2CA4LLU /* 120 */, 0xCF0B8447CC8A8FB1LLU /* 121 */, 0x9F765244979859A3LLU /* 122 */, 0xA8D516B1A1240017LLU /* 123 */, 0x0BD7BA3EBB5DC726LLU /* 124 */, 0xE54BCA55B86ADB39LLU /* 125 */, 0x1D7A3AFD6C478063LLU /* 126 */, 0x519EC608E7669EDDLLU /* 127 */, 0x0E5715A2D149AA23LLU /* 128 */, 0x177D4571848FF194LLU /* 129 */, 0xEEB55F3241014C22LLU /* 130 */, 0x0F5E5CA13A6E2EC2LLU /* 131 */, 0x8029927B75F5C361LLU /* 132 */, 0xAD139FABC3D6E436LLU /* 133 */, 0x0D5DF1A94CCF402FLLU /* 134 */, 0x3E8BD948BEA5DFC8LLU /* 135 */, 0xA5A0D357BD3FF77ELLU /* 136 */, 0xA2D12E251F74F645LLU /* 137 */, 0x66FD9E525E81A082LLU /* 138 */, 0x2E0C90CE7F687A49LLU /* 139 */, 0xC2E8BCBEBA973BC5LLU /* 140 */, 0x000001BCE509745FLLU /* 141 */, 0x423777BBE6DAB3D6LLU /* 142 */, 0xD1661C7EAEF06EB5LLU /* 143 */, 0xA1781F354DAACFD8LLU /* 144 */, 0x2D11284A2B16AFFCLLU /* 145 */, 0xF1FC4F67FA891D1FLLU /* 146 */, 0x73ECC25DCB920ADALLU /* 147 */, 0xAE610C22C2A12651LLU /* 148 */, 0x96E0A810D356B78ALLU /* 149 */, 0x5A9A381F2FE7870FLLU /* 150 */, 0xD5AD62EDE94E5530LLU /* 151 */, 0xD225E5E8368D1427LLU /* 152 */, 0x65977B70C7AF4631LLU /* 153 */, 0x99F889B2DE39D74FLLU /* 154 */, 0x233F30BF54E1D143LLU /* 155 */, 0x9A9675D3D9A63C97LLU /* 156 */, 0x5470554FF334F9A8LLU /* 157 */, 0x166ACB744A4F5688LLU /* 158 */, 0x70C74CAAB2E4AEADLLU /* 159 */, 0xF0D091646F294D12LLU /* 160 */, 0x57B82A89684031D1LLU /* 161 */, 0xEFD95A5A61BE0B6BLLU /* 162 */, 0x2FBD12E969F2F29ALLU /* 163 */, 0x9BD37013FEFF9FE8LLU /* 164 */, 0x3F9B0404D6085A06LLU /* 165 */, 0x4940C1F3166CFE15LLU /* 166 */, 0x09542C4DCDF3DEFBLLU /* 167 */, 0xB4C5218385CD5CE3LLU /* 168 */, 0xC935B7DC4462A641LLU /* 169 */, 0x3417F8A68ED3B63FLLU /* 170 */, 0xB80959295B215B40LLU /* 171 */, 0xF99CDAEF3B8C8572LLU /* 172 */, 0x018C0614F8FCB95DLLU /* 173 */, 0x1B14ACCD1A3ACDF3LLU /* 174 */, 0x84D471F200BB732DLLU /* 175 */, 0xC1A3110E95E8DA16LLU /* 176 */, 0x430A7220BF1A82B8LLU /* 177 */, 0xB77E090D39DF210ELLU /* 178 */, 0x5EF4BD9F3CD05E9DLLU /* 179 */, 0x9D4FF6DA7E57A444LLU /* 180 */, 0xDA1D60E183D4A5F8LLU /* 181 */, 0xB287C38417998E47LLU /* 182 */, 0xFE3EDC121BB31886LLU /* 183 */, 0xC7FE3CCC980CCBEFLLU /* 184 */, 0xE46FB590189BFD03LLU /* 185 */, 0x3732FD469A4C57DCLLU /* 186 */, 0x7EF700A07CF1AD65LLU /* 187 */, 0x59C64468A31D8859LLU /* 188 */, 0x762FB0B4D45B61F6LLU /* 189 */, 0x155BAED099047718LLU /* 190 */, 0x68755E4C3D50BAA6LLU /* 191 */, 0xE9214E7F22D8B4DFLLU /* 192 */, 0x2ADDBF532EAC95F4LLU /* 193 */, 0x32AE3909B4BD0109LLU /* 194 */, 0x834DF537B08E3450LLU /* 195 */, 0xFA209DA84220728DLLU /* 196 */, 0x9E691D9B9EFE23F7LLU /* 197 */, 0x0446D288C4AE8D7FLLU /* 198 */, 0x7B4CC524E169785BLLU /* 199 */, 0x21D87F0135CA1385LLU /* 200 */, 0xCEBB400F137B8AA5LLU /* 201 */, 0x272E2B66580796BELLU /* 202 */, 0x3612264125C2B0DELLU /* 203 */, 0x057702BDAD1EFBB2LLU /* 204 */, 0xD4BABB8EACF84BE9LLU /* 205 */, 0x91583139641BC67BLLU /* 206 */, 0x8BDC2DE08036E024LLU /* 207 */, 0x603C8156F49F68EDLLU /* 208 */, 0xF7D236F7DBEF5111LLU /* 209 */, 0x9727C4598AD21E80LLU /* 210 */, 0xA08A0896670A5FD7LLU /* 211 */, 0xCB4A8F4309EBA9CBLLU /* 212 */, 0x81AF564B0F7036A1LLU /* 213 */, 0xC0B99AA778199ABDLLU /* 214 */, 0x959F1EC83FC8E952LLU /* 215 */, 0x8C505077794A81B9LLU /* 216 */, 0x3ACAAF8F056338F0LLU /* 217 */, 0x07B43F50627A6778LLU /* 218 */, 0x4A44AB49F5ECCC77LLU /* 219 */, 0x3BC3D6E4B679EE98LLU /* 220 */, 0x9CC0D4D1CF14108CLLU /* 221 */, 0x4406C00B206BC8A0LLU /* 222 */, 0x82A18854C8D72D89LLU /* 223 */, 0x67E366B35C3C432CLLU /* 224 */, 0xB923DD61102B37F2LLU /* 225 */, 0x56AB2779D884271DLLU /* 226 */, 0xBE83E1B0FF1525AFLLU /* 227 */, 0xFB7C65D4217E49A9LLU /* 228 */, 0x6BDBE0E76D48E7D4LLU /* 229 */, 0x08DF828745D9179ELLU /* 230 */, 0x22EA6A9ADD53BD34LLU /* 231 */, 0xE36E141C5622200ALLU /* 232 */, 0x7F805D1B8CB750EELLU /* 233 */, 0xAFE5C7A59F58E837LLU /* 234 */, 0xE27F996A4FB1C23CLLU /* 235 */, 0xD3867DFB0775F0D0LLU /* 236 */, 0xD0E673DE6E88891ALLU /* 237 */, 0x123AEB9EAFB86C25LLU /* 238 */, 0x30F1D5D5C145B895LLU /* 239 */, 0xBB434A2DEE7269E7LLU /* 240 */, 0x78CB67ECF931FA38LLU /* 241 */, 0xF33B0372323BBF9CLLU /* 242 */, 0x52D66336FB279C74LLU /* 243 */, 0x505F33AC0AFB4EAALLU /* 244 */, 0xE8A5CD99A2CCE187LLU /* 245 */, 0x534974801E2D30BBLLU /* 246 */, 0x8D2D5711D5876D90LLU /* 247 */, 0x1F1A412891BC038ELLU /* 248 */, 0xD6E2E71D82E56648LLU /* 249 */, 0x74036C3A497732B7LLU /* 250 */, 0x89B67ED96361F5ABLLU /* 251 */, 0xFFED95D8F1EA02A2LLU /* 252 */, 0xE72B3BD61464D43DLLU /* 253 */, 0xA6300F170BDC4820LLU /* 254 */, 0xEBC18760ED78A77ALLU /* 255 */, 0xE6A6BE5A05A12138LLU /* 256 */, 0xB5A122A5B4F87C98LLU /* 257 */, 0x563C6089140B6990LLU /* 258 */, 0x4C46CB2E391F5DD5LLU /* 259 */, 0xD932ADDBC9B79434LLU /* 260 */, 0x08EA70E42015AFF5LLU /* 261 */, 0xD765A6673E478CF1LLU /* 262 */, 0xC4FB757EAB278D99LLU /* 263 */, 0xDF11C6862D6E0692LLU /* 264 */, 0xDDEB84F10D7F3B16LLU /* 265 */, 0x6F2EF604A665EA04LLU /* 266 */, 0x4A8E0F0FF0E0DFB3LLU /* 267 */, 0xA5EDEEF83DBCBA51LLU /* 268 */, 0xFC4F0A2A0EA4371ELLU /* 269 */, 0xE83E1DA85CB38429LLU /* 270 */, 0xDC8FF882BA1B1CE2LLU /* 271 */, 0xCD45505E8353E80DLLU /* 272 */, 0x18D19A00D4DB0717LLU /* 273 */, 0x34A0CFEDA5F38101LLU /* 274 */, 0x0BE77E518887CAF2LLU /* 275 */, 0x1E341438B3C45136LLU /* 276 */, 0xE05797F49089CCF9LLU /* 277 */, 0xFFD23F9DF2591D14LLU /* 278 */, 0x543DDA228595C5CDLLU /* 279 */, 0x661F81FD99052A33LLU /* 280 */, 0x8736E641DB0F7B76LLU /* 281 */, 0x15227725418E5307LLU /* 282 */, 0xE25F7F46162EB2FALLU /* 283 */, 0x48A8B2126C13D9FELLU /* 284 */, 0xAFDC541792E76EEALLU /* 285 */, 0x03D912BFC6D1898FLLU /* 286 */, 0x31B1AAFA1B83F51BLLU /* 287 */, 0xF1AC2796E42AB7D9LLU /* 288 */, 0x40A3A7D7FCD2EBACLLU /* 289 */, 0x1056136D0AFBBCC5LLU /* 290 */, 0x7889E1DD9A6D0C85LLU /* 291 */, 0xD33525782A7974AALLU /* 292 */, 0xA7E25D09078AC09BLLU /* 293 */, 0xBD4138B3EAC6EDD0LLU /* 294 */, 0x920ABFBE71EB9E70LLU /* 295 */, 0xA2A5D0F54FC2625CLLU /* 296 */, 0xC054E36B0B1290A3LLU /* 297 */, 0xF6DD59FF62FE932BLLU /* 298 */, 0x3537354511A8AC7DLLU /* 299 */, 0xCA845E9172FADCD4LLU /* 300 */, 0x84F82B60329D20DCLLU /* 301 */, 0x79C62CE1CD672F18LLU /* 302 */, 0x8B09A2ADD124642CLLU /* 303 */, 0xD0C1E96A19D9E726LLU /* 304 */, 0x5A786A9B4BA9500CLLU /* 305 */, 0x0E020336634C43F3LLU /* 306 */, 0xC17B474AEB66D822LLU /* 307 */, 0x6A731AE3EC9BAAC2LLU /* 308 */, 0x8226667AE0840258LLU /* 309 */, 0x67D4567691CAECA5LLU /* 310 */, 0x1D94155C4875ADB5LLU /* 311 */, 0x6D00FD985B813FDFLLU /* 312 */, 0x51286EFCB774CD06LLU /* 313 */, 0x5E8834471FA744AFLLU /* 314 */, 0xF72CA0AEE761AE2ELLU /* 315 */, 0xBE40E4CDAEE8E09ALLU /* 316 */, 0xE9970BBB5118F665LLU /* 317 */, 0x726E4BEB33DF1964LLU /* 318 */, 0x703B000729199762LLU /* 319 */, 0x4631D816F5EF30A7LLU /* 320 */, 0xB880B5B51504A6BELLU /* 321 */, 0x641793C37ED84B6CLLU /* 322 */, 0x7B21ED77F6E97D96LLU /* 323 */, 0x776306312EF96B73LLU /* 324 */, 0xAE528948E86FF3F4LLU /* 325 */, 0x53DBD7F286A3F8F8LLU /* 326 */, 0x16CADCE74CFC1063LLU /* 327 */, 0x005C19BDFA52C6DDLLU /* 328 */, 0x68868F5D64D46AD3LLU /* 329 */, 0x3A9D512CCF1E186ALLU /* 330 */, 0x367E62C2385660AELLU /* 331 */, 0xE359E7EA77DCB1D7LLU /* 332 */, 0x526C0773749ABE6ELLU /* 333 */, 0x735AE5F9D09F734BLLU /* 334 */, 0x493FC7CC8A558BA8LLU /* 335 */, 0xB0B9C1533041AB45LLU /* 336 */, 0x321958BA470A59BDLLU /* 337 */, 0x852DB00B5F46C393LLU /* 338 */, 0x91209B2BD336B0E5LLU /* 339 */, 0x6E604F7D659EF19FLLU /* 340 */, 0xB99A8AE2782CCB24LLU /* 341 */, 0xCCF52AB6C814C4C7LLU /* 342 */, 0x4727D9AFBE11727BLLU /* 343 */, 0x7E950D0C0121B34DLLU /* 344 */, 0x756F435670AD471FLLU /* 345 */, 0xF5ADD442615A6849LLU /* 346 */, 0x4E87E09980B9957ALLU /* 347 */, 0x2ACFA1DF50AEE355LLU /* 348 */, 0xD898263AFD2FD556LLU /* 349 */, 0xC8F4924DD80C8FD6LLU /* 350 */, 0xCF99CA3D754A173ALLU /* 351 */, 0xFE477BACAF91BF3CLLU /* 352 */, 0xED5371F6D690C12DLLU /* 353 */, 0x831A5C285E687094LLU /* 354 */, 0xC5D3C90A3708A0A4LLU /* 355 */, 0x0F7F903717D06580LLU /* 356 */, 0x19F9BB13B8FDF27FLLU /* 357 */, 0xB1BD6F1B4D502843LLU /* 358 */, 0x1C761BA38FFF4012LLU /* 359 */, 0x0D1530C4E2E21F3BLLU /* 360 */, 0x8943CE69A7372C8ALLU /* 361 */, 0xE5184E11FEB5CE66LLU /* 362 */, 0x618BDB80BD736621LLU /* 363 */, 0x7D29BAD68B574D0BLLU /* 364 */, 0x81BB613E25E6FE5BLLU /* 365 */, 0x071C9C10BC07913FLLU /* 366 */, 0xC7BEEB7909AC2D97LLU /* 367 */, 0xC3E58D353BC5D757LLU /* 368 */, 0xEB017892F38F61E8LLU /* 369 */, 0xD4EFFB9C9B1CC21ALLU /* 370 */, 0x99727D26F494F7ABLLU /* 371 */, 0xA3E063A2956B3E03LLU /* 372 */, 0x9D4A8B9A4AA09C30LLU /* 373 */, 0x3F6AB7D500090FB4LLU /* 374 */, 0x9CC0F2A057268AC0LLU /* 375 */, 0x3DEE9D2DEDBF42D1LLU /* 376 */, 0x330F49C87960A972LLU /* 377 */, 0xC6B2720287421B41LLU /* 378 */, 0x0AC59EC07C00369CLLU /* 379 */, 0xEF4EAC49CB353425LLU /* 380 */, 0xF450244EEF0129D8LLU /* 381 */, 0x8ACC46E5CAF4DEB6LLU /* 382 */, 0x2FFEAB63989263F7LLU /* 383 */, 0x8F7CB9FE5D7A4578LLU /* 384 */, 0x5BD8F7644E634635LLU /* 385 */, 0x427A7315BF2DC900LLU /* 386 */, 0x17D0C4AA2125261CLLU /* 387 */, 0x3992486C93518E50LLU /* 388 */, 0xB4CBFEE0A2D7D4C3LLU /* 389 */, 0x7C75D6202C5DDD8DLLU /* 390 */, 0xDBC295D8E35B6C61LLU /* 391 */, 0x60B369D302032B19LLU /* 392 */, 0xCE42685FDCE44132LLU /* 393 */, 0x06F3DDB9DDF65610LLU /* 394 */, 0x8EA4D21DB5E148F0LLU /* 395 */, 0x20B0FCE62FCD496FLLU /* 396 */, 0x2C1B912358B0EE31LLU /* 397 */, 0xB28317B818F5A308LLU /* 398 */, 0xA89C1E189CA6D2CFLLU /* 399 */, 0x0C6B18576AAADBC8LLU /* 400 */, 0xB65DEAA91299FAE3LLU /* 401 */, 0xFB2B794B7F1027E7LLU /* 402 */, 0x04E4317F443B5BEBLLU /* 403 */, 0x4B852D325939D0A6LLU /* 404 */, 0xD5AE6BEEFB207FFCLLU /* 405 */, 0x309682B281C7D374LLU /* 406 */, 0xBAE309A194C3B475LLU /* 407 */, 0x8CC3F97B13B49F05LLU /* 408 */, 0x98A9422FF8293967LLU /* 409 */, 0x244B16B01076FF7CLLU /* 410 */, 0xF8BF571C663D67EELLU /* 411 */, 0x1F0D6758EEE30DA1LLU /* 412 */, 0xC9B611D97ADEB9B7LLU /* 413 */, 0xB7AFD5887B6C57A2LLU /* 414 */, 0x6290AE846B984FE1LLU /* 415 */, 0x94DF4CDEACC1A5FDLLU /* 416 */, 0x058A5BD1C5483AFFLLU /* 417 */, 0x63166CC142BA3C37LLU /* 418 */, 0x8DB8526EB2F76F40LLU /* 419 */, 0xE10880036F0D6D4ELLU /* 420 */, 0x9E0523C9971D311DLLU /* 421 */, 0x45EC2824CC7CD691LLU /* 422 */, 0x575B8359E62382C9LLU /* 423 */, 0xFA9E400DC4889995LLU /* 424 */, 0xD1823ECB45721568LLU /* 425 */, 0xDAFD983B8206082FLLU /* 426 */, 0xAA7D29082386A8CBLLU /* 427 */, 0x269FCD4403B87588LLU /* 428 */, 0x1B91F5F728BDD1E0LLU /* 429 */, 0xE4669F39040201F6LLU /* 430 */, 0x7A1D7C218CF04ADELLU /* 431 */, 0x65623C29D79CE5CELLU /* 432 */, 0x2368449096C00BB1LLU /* 433 */, 0xAB9BF1879DA503BALLU /* 434 */, 0xBC23ECB1A458058ELLU /* 435 */, 0x9A58DF01BB401ECCLLU /* 436 */, 0xA070E868A85F143DLLU /* 437 */, 0x4FF188307DF2239ELLU /* 438 */, 0x14D565B41A641183LLU /* 439 */, 0xEE13337452701602LLU /* 440 */, 0x950E3DCF3F285E09LLU /* 441 */, 0x59930254B9C80953LLU /* 442 */, 0x3BF299408930DA6DLLU /* 443 */, 0xA955943F53691387LLU /* 444 */, 0xA15EDECAA9CB8784LLU /* 445 */, 0x29142127352BE9A0LLU /* 446 */, 0x76F0371FFF4E7AFBLLU /* 447 */, 0x0239F450274F2228LLU /* 448 */, 0xBB073AF01D5E868BLLU /* 449 */, 0xBFC80571C10E96C1LLU /* 450 */, 0xD267088568222E23LLU /* 451 */, 0x9671A3D48E80B5B0LLU /* 452 */, 0x55B5D38AE193BB81LLU /* 453 */, 0x693AE2D0A18B04B8LLU /* 454 */, 0x5C48B4ECADD5335FLLU /* 455 */, 0xFD743B194916A1CALLU /* 456 */, 0x2577018134BE98C4LLU /* 457 */, 0xE77987E83C54A4ADLLU /* 458 */, 0x28E11014DA33E1B9LLU /* 459 */, 0x270CC59E226AA213LLU /* 460 */, 0x71495F756D1A5F60LLU /* 461 */, 0x9BE853FB60AFEF77LLU /* 462 */, 0xADC786A7F7443DBFLLU /* 463 */, 0x0904456173B29A82LLU /* 464 */, 0x58BC7A66C232BD5ELLU /* 465 */, 0xF306558C673AC8B2LLU /* 466 */, 0x41F639C6B6C9772ALLU /* 467 */, 0x216DEFE99FDA35DALLU /* 468 */, 0x11640CC71C7BE615LLU /* 469 */, 0x93C43694565C5527LLU /* 470 */, 0xEA038E6246777839LLU /* 471 */, 0xF9ABF3CE5A3E2469LLU /* 472 */, 0x741E768D0FD312D2LLU /* 473 */, 0x0144B883CED652C6LLU /* 474 */, 0xC20B5A5BA33F8552LLU /* 475 */, 0x1AE69633C3435A9DLLU /* 476 */, 0x97A28CA4088CFDECLLU /* 477 */, 0x8824A43C1E96F420LLU /* 478 */, 0x37612FA66EEEA746LLU /* 479 */, 0x6B4CB165F9CF0E5ALLU /* 480 */, 0x43AA1C06A0ABFB4ALLU /* 481 */, 0x7F4DC26FF162796BLLU /* 482 */, 0x6CBACC8E54ED9B0FLLU /* 483 */, 0xA6B7FFEFD2BB253ELLU /* 484 */, 0x2E25BC95B0A29D4FLLU /* 485 */, 0x86D6A58BDEF1388CLLU /* 486 */, 0xDED74AC576B6F054LLU /* 487 */, 0x8030BDBC2B45805DLLU /* 488 */, 0x3C81AF70E94D9289LLU /* 489 */, 0x3EFF6DDA9E3100DBLLU /* 490 */, 0xB38DC39FDFCC8847LLU /* 491 */, 0x123885528D17B87ELLU /* 492 */, 0xF2DA0ED240B1B642LLU /* 493 */, 0x44CEFADCD54BF9A9LLU /* 494 */, 0x1312200E433C7EE6LLU /* 495 */, 0x9FFCC84F3A78C748LLU /* 496 */, 0xF0CD1F72248576BBLLU /* 497 */, 0xEC6974053638CFE4LLU /* 498 */, 0x2BA7B67C0CEC4E4CLLU /* 499 */, 0xAC2F4DF3E5CE32EDLLU /* 500 */, 0xCB33D14326EA4C11LLU /* 501 */, 0xA4E9044CC77E58BCLLU /* 502 */, 0x5F513293D934FCEFLLU /* 503 */, 0x5DC9645506E55444LLU /* 504 */, 0x50DE418F317DE40ALLU /* 505 */, 0x388CB31A69DDE259LLU /* 506 */, 0x2DB4A83455820A86LLU /* 507 */, 0x9010A91E84711AE9LLU /* 508 */, 0x4DF7F0B7B1498371LLU /* 509 */, 0xD62A2EABC0977179LLU /* 510 */, 0x22FAC097AA8D5C0ELLU /* 511 */, 0xF49FCC2FF1DAF39BLLU /* 512 */, 0x487FD5C66FF29281LLU /* 513 */, 0xE8A30667FCDCA83FLLU /* 514 */, 0x2C9B4BE3D2FCCE63LLU /* 515 */, 0xDA3FF74B93FBBBC2LLU /* 516 */, 0x2FA165D2FE70BA66LLU /* 517 */, 0xA103E279970E93D4LLU /* 518 */, 0xBECDEC77B0E45E71LLU /* 519 */, 0xCFB41E723985E497LLU /* 520 */, 0xB70AAA025EF75017LLU /* 521 */, 0xD42309F03840B8E0LLU /* 522 */, 0x8EFC1AD035898579LLU /* 523 */, 0x96C6920BE2B2ABC5LLU /* 524 */, 0x66AF4163375A9172LLU /* 525 */, 0x2174ABDCCA7127FBLLU /* 526 */, 0xB33CCEA64A72FF41LLU /* 527 */, 0xF04A4933083066A5LLU /* 528 */, 0x8D970ACDD7289AF5LLU /* 529 */, 0x8F96E8E031C8C25ELLU /* 530 */, 0xF3FEC02276875D47LLU /* 531 */, 0xEC7BF310056190DDLLU /* 532 */, 0xF5ADB0AEBB0F1491LLU /* 533 */, 0x9B50F8850FD58892LLU /* 534 */, 0x4975488358B74DE8LLU /* 535 */, 0xA3354FF691531C61LLU /* 536 */, 0x0702BBE481D2C6EELLU /* 537 */, 0x89FB24057DEDED98LLU /* 538 */, 0xAC3075138596E902LLU /* 539 */, 0x1D2D3580172772EDLLU /* 540 */, 0xEB738FC28E6BC30DLLU /* 541 */, 0x5854EF8F63044326LLU /* 542 */, 0x9E5C52325ADD3BBELLU /* 543 */, 0x90AA53CF325C4623LLU /* 544 */, 0xC1D24D51349DD067LLU /* 545 */, 0x2051CFEEA69EA624LLU /* 546 */, 0x13220F0A862E7E4FLLU /* 547 */, 0xCE39399404E04864LLU /* 548 */, 0xD9C42CA47086FCB7LLU /* 549 */, 0x685AD2238A03E7CCLLU /* 550 */, 0x066484B2AB2FF1DBLLU /* 551 */, 0xFE9D5D70EFBF79ECLLU /* 552 */, 0x5B13B9DD9C481854LLU /* 553 */, 0x15F0D475ED1509ADLLU /* 554 */, 0x0BEBCD060EC79851LLU /* 555 */, 0xD58C6791183AB7F8LLU /* 556 */, 0xD1187C5052F3EEE4LLU /* 557 */, 0xC95D1192E54E82FFLLU /* 558 */, 0x86EEA14CB9AC6CA2LLU /* 559 */, 0x3485BEB153677D5DLLU /* 560 */, 0xDD191D781F8C492ALLU /* 561 */, 0xF60866BAA784EBF9LLU /* 562 */, 0x518F643BA2D08C74LLU /* 563 */, 0x8852E956E1087C22LLU /* 564 */, 0xA768CB8DC410AE8DLLU /* 565 */, 0x38047726BFEC8E1ALLU /* 566 */, 0xA67738B4CD3B45AALLU /* 567 */, 0xAD16691CEC0DDE19LLU /* 568 */, 0xC6D4319380462E07LLU /* 569 */, 0xC5A5876D0BA61938LLU /* 570 */, 0x16B9FA1FA58FD840LLU /* 571 */, 0x188AB1173CA74F18LLU /* 572 */, 0xABDA2F98C99C021FLLU /* 573 */, 0x3E0580AB134AE816LLU /* 574 */, 0x5F3B05B773645ABBLLU /* 575 */, 0x2501A2BE5575F2F6LLU /* 576 */, 0x1B2F74004E7E8BA9LLU /* 577 */, 0x1CD7580371E8D953LLU /* 578 */, 0x7F6ED89562764E30LLU /* 579 */, 0xB15926FF596F003DLLU /* 580 */, 0x9F65293DA8C5D6B9LLU /* 581 */, 0x6ECEF04DD690F84CLLU /* 582 */, 0x4782275FFF33AF88LLU /* 583 */, 0xE41433083F820801LLU /* 584 */, 0xFD0DFE409A1AF9B5LLU /* 585 */, 0x4325A3342CDB396BLLU /* 586 */, 0x8AE77E62B301B252LLU /* 587 */, 0xC36F9E9F6655615ALLU /* 588 */, 0x85455A2D92D32C09LLU /* 589 */, 0xF2C7DEA949477485LLU /* 590 */, 0x63CFB4C133A39EBALLU /* 591 */, 0x83B040CC6EBC5462LLU /* 592 */, 0x3B9454C8FDB326B0LLU /* 593 */, 0x56F56A9E87FFD78CLLU /* 594 */, 0x2DC2940D99F42BC6LLU /* 595 */, 0x98F7DF096B096E2DLLU /* 596 */, 0x19A6E01E3AD852BFLLU /* 597 */, 0x42A99CCBDBD4B40BLLU /* 598 */, 0xA59998AF45E9C559LLU /* 599 */, 0x366295E807D93186LLU /* 600 */, 0x6B48181BFAA1F773LLU /* 601 */, 0x1FEC57E2157A0A1DLLU /* 602 */, 0x4667446AF6201AD5LLU /* 603 */, 0xE615EBCACFB0F075LLU /* 604 */, 0xB8F31F4F68290778LLU /* 605 */, 0x22713ED6CE22D11ELLU /* 606 */, 0x3057C1A72EC3C93BLLU /* 607 */, 0xCB46ACC37C3F1F2FLLU /* 608 */, 0xDBB893FD02AAF50ELLU /* 609 */, 0x331FD92E600B9FCFLLU /* 610 */, 0xA498F96148EA3AD6LLU /* 611 */, 0xA8D8426E8B6A83EALLU /* 612 */, 0xA089B274B7735CDCLLU /* 613 */, 0x87F6B3731E524A11LLU /* 614 */, 0x118808E5CBC96749LLU /* 615 */, 0x9906E4C7B19BD394LLU /* 616 */, 0xAFED7F7E9B24A20CLLU /* 617 */, 0x6509EADEEB3644A7LLU /* 618 */, 0x6C1EF1D3E8EF0EDELLU /* 619 */, 0xB9C97D43E9798FB4LLU /* 620 */, 0xA2F2D784740C28A3LLU /* 621 */, 0x7B8496476197566FLLU /* 622 */, 0x7A5BE3E6B65F069DLLU /* 623 */, 0xF96330ED78BE6F10LLU /* 624 */, 0xEEE60DE77A076A15LLU /* 625 */, 0x2B4BEE4AA08B9BD0LLU /* 626 */, 0x6A56A63EC7B8894ELLU /* 627 */, 0x02121359BA34FEF4LLU /* 628 */, 0x4CBF99F8283703FCLLU /* 629 */, 0x398071350CAF30C8LLU /* 630 */, 0xD0A77A89F017687ALLU /* 631 */, 0xF1C1A9EB9E423569LLU /* 632 */, 0x8C7976282DEE8199LLU /* 633 */, 0x5D1737A5DD1F7ABDLLU /* 634 */, 0x4F53433C09A9FA80LLU /* 635 */, 0xFA8B0C53DF7CA1D9LLU /* 636 */, 0x3FD9DCBC886CCB77LLU /* 637 */, 0xC040917CA91B4720LLU /* 638 */, 0x7DD00142F9D1DCDFLLU /* 639 */, 0x8476FC1D4F387B58LLU /* 640 */, 0x23F8E7C5F3316503LLU /* 641 */, 0x032A2244E7E37339LLU /* 642 */, 0x5C87A5D750F5A74BLLU /* 643 */, 0x082B4CC43698992ELLU /* 644 */, 0xDF917BECB858F63CLLU /* 645 */, 0x3270B8FC5BF86DDALLU /* 646 */, 0x10AE72BB29B5DD76LLU /* 647 */, 0x576AC94E7700362BLLU /* 648 */, 0x1AD112DAC61EFB8FLLU /* 649 */, 0x691BC30EC5FAA427LLU /* 650 */, 0xFF246311CC327143LLU /* 651 */, 0x3142368E30E53206LLU /* 652 */, 0x71380E31E02CA396LLU /* 653 */, 0x958D5C960AAD76F1LLU /* 654 */, 0xF8D6F430C16DA536LLU /* 655 */, 0xC8FFD13F1BE7E1D2LLU /* 656 */, 0x7578AE66004DDBE1LLU /* 657 */, 0x05833F01067BE646LLU /* 658 */, 0xBB34B5AD3BFE586DLLU /* 659 */, 0x095F34C9A12B97F0LLU /* 660 */, 0x247AB64525D60CA8LLU /* 661 */, 0xDCDBC6F3017477D1LLU /* 662 */, 0x4A2E14D4DECAD24DLLU /* 663 */, 0xBDB5E6D9BE0A1EEBLLU /* 664 */, 0x2A7E70F7794301ABLLU /* 665 */, 0xDEF42D8A270540FDLLU /* 666 */, 0x01078EC0A34C22C1LLU /* 667 */, 0xE5DE511AF4C16387LLU /* 668 */, 0x7EBB3A52BD9A330ALLU /* 669 */, 0x77697857AA7D6435LLU /* 670 */, 0x004E831603AE4C32LLU /* 671 */, 0xE7A21020AD78E312LLU /* 672 */, 0x9D41A70C6AB420F2LLU /* 673 */, 0x28E06C18EA1141E6LLU /* 674 */, 0xD2B28CBD984F6B28LLU /* 675 */, 0x26B75F6C446E9D83LLU /* 676 */, 0xBA47568C4D418D7FLLU /* 677 */, 0xD80BADBFE6183D8ELLU /* 678 */, 0x0E206D7F5F166044LLU /* 679 */, 0xE258A43911CBCA3ELLU /* 680 */, 0x723A1746B21DC0BCLLU /* 681 */, 0xC7CAA854F5D7CDD3LLU /* 682 */, 0x7CAC32883D261D9CLLU /* 683 */, 0x7690C26423BA942CLLU /* 684 */, 0x17E55524478042B8LLU /* 685 */, 0xE0BE477656A2389FLLU /* 686 */, 0x4D289B5E67AB2DA0LLU /* 687 */, 0x44862B9C8FBBFD31LLU /* 688 */, 0xB47CC8049D141365LLU /* 689 */, 0x822C1B362B91C793LLU /* 690 */, 0x4EB14655FB13DFD8LLU /* 691 */, 0x1ECBBA0714E2A97BLLU /* 692 */, 0x6143459D5CDE5F14LLU /* 693 */, 0x53A8FBF1D5F0AC89LLU /* 694 */, 0x97EA04D81C5E5B00LLU /* 695 */, 0x622181A8D4FDB3F3LLU /* 696 */, 0xE9BCD341572A1208LLU /* 697 */, 0x1411258643CCE58ALLU /* 698 */, 0x9144C5FEA4C6E0A4LLU /* 699 */, 0x0D33D06565CF620FLLU /* 700 */, 0x54A48D489F219CA1LLU /* 701 */, 0xC43E5EAC6D63C821LLU /* 702 */, 0xA9728B3A72770DAFLLU /* 703 */, 0xD7934E7B20DF87EFLLU /* 704 */, 0xE35503B61A3E86E5LLU /* 705 */, 0xCAE321FBC819D504LLU /* 706 */, 0x129A50B3AC60BFA6LLU /* 707 */, 0xCD5E68EA7E9FB6C3LLU /* 708 */, 0xB01C90199483B1C7LLU /* 709 */, 0x3DE93CD5C295376CLLU /* 710 */, 0xAED52EDF2AB9AD13LLU /* 711 */, 0x2E60F512C0A07884LLU /* 712 */, 0xBC3D86A3E36210C9LLU /* 713 */, 0x35269D9B163951CELLU /* 714 */, 0x0C7D6E2AD0CDB5FALLU /* 715 */, 0x59E86297D87F5733LLU /* 716 */, 0x298EF221898DB0E7LLU /* 717 */, 0x55000029D1A5AA7ELLU /* 718 */, 0x8BC08AE1B5061B45LLU /* 719 */, 0xC2C31C2B6C92703ALLU /* 720 */, 0x94CC596BAF25EF42LLU /* 721 */, 0x0A1D73DB22540456LLU /* 722 */, 0x04B6A0F9D9C4179ALLU /* 723 */, 0xEFFDAFA2AE3D3C60LLU /* 724 */, 0xF7C8075BB49496C4LLU /* 725 */, 0x9CC5C7141D1CD4E3LLU /* 726 */, 0x78BD1638218E5534LLU /* 727 */, 0xB2F11568F850246ALLU /* 728 */, 0xEDFABCFA9502BC29LLU /* 729 */, 0x796CE5F2DA23051BLLU /* 730 */, 0xAAE128B0DC93537CLLU /* 731 */, 0x3A493DA0EE4B29AELLU /* 732 */, 0xB5DF6B2C416895D7LLU /* 733 */, 0xFCABBD25122D7F37LLU /* 734 */, 0x70810B58105DC4B1LLU /* 735 */, 0xE10FDD37F7882A90LLU /* 736 */, 0x524DCAB5518A3F5CLLU /* 737 */, 0x3C9E85878451255BLLU /* 738 */, 0x4029828119BD34E2LLU /* 739 */, 0x74A05B6F5D3CECCBLLU /* 740 */, 0xB610021542E13ECALLU /* 741 */, 0x0FF979D12F59E2ACLLU /* 742 */, 0x6037DA27E4F9CC50LLU /* 743 */, 0x5E92975A0DF1847DLLU /* 744 */, 0xD66DE190D3E623FELLU /* 745 */, 0x5032D6B87B568048LLU /* 746 */, 0x9A36B7CE8235216ELLU /* 747 */, 0x80272A7A24F64B4ALLU /* 748 */, 0x93EFED8B8C6916F7LLU /* 749 */, 0x37DDBFF44CCE1555LLU /* 750 */, 0x4B95DB5D4B99BD25LLU /* 751 */, 0x92D3FDA169812FC0LLU /* 752 */, 0xFB1A4A9A90660BB6LLU /* 753 */, 0x730C196946A4B9B2LLU /* 754 */, 0x81E289AA7F49DA68LLU /* 755 */, 0x64669A0F83B1A05FLLU /* 756 */, 0x27B3FF7D9644F48BLLU /* 757 */, 0xCC6B615C8DB675B3LLU /* 758 */, 0x674F20B9BCEBBE95LLU /* 759 */, 0x6F31238275655982LLU /* 760 */, 0x5AE488713E45CF05LLU /* 761 */, 0xBF619F9954C21157LLU /* 762 */, 0xEABAC46040A8EAE9LLU /* 763 */, 0x454C6FE9F2C0C1CDLLU /* 764 */, 0x419CF6496412691CLLU /* 765 */, 0xD3DC3BEF265B0F70LLU /* 766 */, 0x6D0E60F5C3578A9ELLU /* 767 */, 0x5B0E608526323C55LLU /* 768 */, 0x1A46C1A9FA1B59F5LLU /* 769 */, 0xA9E245A17C4C8FFALLU /* 770 */, 0x65CA5159DB2955D7LLU /* 771 */, 0x05DB0A76CE35AFC2LLU /* 772 */, 0x81EAC77EA9113D45LLU /* 773 */, 0x528EF88AB6AC0A0DLLU /* 774 */, 0xA09EA253597BE3FFLLU /* 775 */, 0x430DDFB3AC48CD56LLU /* 776 */, 0xC4B3A67AF45CE46FLLU /* 777 */, 0x4ECECFD8FBE2D05ELLU /* 778 */, 0x3EF56F10B39935F0LLU /* 779 */, 0x0B22D6829CD619C6LLU /* 780 */, 0x17FD460A74DF2069LLU /* 781 */, 0x6CF8CC8E8510ED40LLU /* 782 */, 0xD6C824BF3A6ECAA7LLU /* 783 */, 0x61243D581A817049LLU /* 784 */, 0x048BACB6BBC163A2LLU /* 785 */, 0xD9A38AC27D44CC32LLU /* 786 */, 0x7FDDFF5BAAF410ABLLU /* 787 */, 0xAD6D495AA804824BLLU /* 788 */, 0xE1A6A74F2D8C9F94LLU /* 789 */, 0xD4F7851235DEE8E3LLU /* 790 */, 0xFD4B7F886540D893LLU /* 791 */, 0x247C20042AA4BFDALLU /* 792 */, 0x096EA1C517D1327CLLU /* 793 */, 0xD56966B4361A6685LLU /* 794 */, 0x277DA5C31221057DLLU /* 795 */, 0x94D59893A43ACFF7LLU /* 796 */, 0x64F0C51CCDC02281LLU /* 797 */, 0x3D33BCC4FF6189DBLLU /* 798 */, 0xE005CB184CE66AF1LLU /* 799 */, 0xFF5CCD1D1DB99BEALLU /* 800 */, 0xB0B854A7FE42980FLLU /* 801 */, 0x7BD46A6A718D4B9FLLU /* 802 */, 0xD10FA8CC22A5FD8CLLU /* 803 */, 0xD31484952BE4BD31LLU /* 804 */, 0xC7FA975FCB243847LLU /* 805 */, 0x4886ED1E5846C407LLU /* 806 */, 0x28CDDB791EB70B04LLU /* 807 */, 0xC2B00BE2F573417FLLU /* 808 */, 0x5C9590452180F877LLU /* 809 */, 0x7A6BDDFFF370EB00LLU /* 810 */, 0xCE509E38D6D9D6A4LLU /* 811 */, 0xEBEB0F00647FA702LLU /* 812 */, 0x1DCC06CF76606F06LLU /* 813 */, 0xE4D9F28BA286FF0ALLU /* 814 */, 0xD85A305DC918C262LLU /* 815 */, 0x475B1D8732225F54LLU /* 816 */, 0x2D4FB51668CCB5FELLU /* 817 */, 0xA679B9D9D72BBA20LLU /* 818 */, 0x53841C0D912D43A5LLU /* 819 */, 0x3B7EAA48BF12A4E8LLU /* 820 */, 0x781E0E47F22F1DDFLLU /* 821 */, 0xEFF20CE60AB50973LLU /* 822 */, 0x20D261D19DFFB742LLU /* 823 */, 0x16A12B03062A2E39LLU /* 824 */, 0x1960EB2239650495LLU /* 825 */, 0x251C16FED50EB8B8LLU /* 826 */, 0x9AC0C330F826016ELLU /* 827 */, 0xED152665953E7671LLU /* 828 */, 0x02D63194A6369570LLU /* 829 */, 0x5074F08394B1C987LLU /* 830 */, 0x70BA598C90B25CE1LLU /* 831 */, 0x794A15810B9742F6LLU /* 832 */, 0x0D5925E9FCAF8C6CLLU /* 833 */, 0x3067716CD868744ELLU /* 834 */, 0x910AB077E8D7731BLLU /* 835 */, 0x6A61BBDB5AC42F61LLU /* 836 */, 0x93513EFBF0851567LLU /* 837 */, 0xF494724B9E83E9D5LLU /* 838 */, 0xE887E1985C09648DLLU /* 839 */, 0x34B1D3C675370CFDLLU /* 840 */, 0xDC35E433BC0D255DLLU /* 841 */, 0xD0AAB84234131BE0LLU /* 842 */, 0x08042A50B48B7EAFLLU /* 843 */, 0x9997C4EE44A3AB35LLU /* 844 */, 0x829A7B49201799D0LLU /* 845 */, 0x263B8307B7C54441LLU /* 846 */, 0x752F95F4FD6A6CA6LLU /* 847 */, 0x927217402C08C6E5LLU /* 848 */, 0x2A8AB754A795D9EELLU /* 849 */, 0xA442F7552F72943DLLU /* 850 */, 0x2C31334E19781208LLU /* 851 */, 0x4FA98D7CEAEE6291LLU /* 852 */, 0x55C3862F665DB309LLU /* 853 */, 0xBD0610175D53B1F3LLU /* 854 */, 0x46FE6CB840413F27LLU /* 855 */, 0x3FE03792DF0CFA59LLU /* 856 */, 0xCFE700372EB85E8FLLU /* 857 */, 0xA7BE29E7ADBCE118LLU /* 858 */, 0xE544EE5CDE8431DDLLU /* 859 */, 0x8A781B1B41F1873ELLU /* 860 */, 0xA5C94C78A0D2F0E7LLU /* 861 */, 0x39412E2877B60728LLU /* 862 */, 0xA1265EF3AFC9A62CLLU /* 863 */, 0xBCC2770C6A2506C5LLU /* 864 */, 0x3AB66DD5DCE1CE12LLU /* 865 */, 0xE65499D04A675B37LLU /* 866 */, 0x7D8F523481BFD216LLU /* 867 */, 0x0F6F64FCEC15F389LLU /* 868 */, 0x74EFBE618B5B13C8LLU /* 869 */, 0xACDC82B714273E1DLLU /* 870 */, 0xDD40BFE003199D17LLU /* 871 */, 0x37E99257E7E061F8LLU /* 872 */, 0xFA52626904775AAALLU /* 873 */, 0x8BBBF63A463D56F9LLU /* 874 */, 0xF0013F1543A26E64LLU /* 875 */, 0xA8307E9F879EC898LLU /* 876 */, 0xCC4C27A4150177CCLLU /* 877 */, 0x1B432F2CCA1D3348LLU /* 878 */, 0xDE1D1F8F9F6FA013LLU /* 879 */, 0x606602A047A7DDD6LLU /* 880 */, 0xD237AB64CC1CB2C7LLU /* 881 */, 0x9B938E7225FCD1D3LLU /* 882 */, 0xEC4E03708E0FF476LLU /* 883 */, 0xFEB2FBDA3D03C12DLLU /* 884 */, 0xAE0BCED2EE43889ALLU /* 885 */, 0x22CB8923EBFB4F43LLU /* 886 */, 0x69360D013CF7396DLLU /* 887 */, 0x855E3602D2D4E022LLU /* 888 */, 0x073805BAD01F784CLLU /* 889 */, 0x33E17A133852F546LLU /* 890 */, 0xDF4874058AC7B638LLU /* 891 */, 0xBA92B29C678AA14ALLU /* 892 */, 0x0CE89FC76CFAADCDLLU /* 893 */, 0x5F9D4E0908339E34LLU /* 894 */, 0xF1AFE9291F5923B9LLU /* 895 */, 0x6E3480F60F4A265FLLU /* 896 */, 0xEEBF3A2AB29B841CLLU /* 897 */, 0xE21938A88F91B4ADLLU /* 898 */, 0x57DFEFF845C6D3C3LLU /* 899 */, 0x2F006B0BF62CAAF2LLU /* 900 */, 0x62F479EF6F75EE78LLU /* 901 */, 0x11A55AD41C8916A9LLU /* 902 */, 0xF229D29084FED453LLU /* 903 */, 0x42F1C27B16B000E6LLU /* 904 */, 0x2B1F76749823C074LLU /* 905 */, 0x4B76ECA3C2745360LLU /* 906 */, 0x8C98F463B91691BDLLU /* 907 */, 0x14BCC93CF1ADE66ALLU /* 908 */, 0x8885213E6D458397LLU /* 909 */, 0x8E177DF0274D4711LLU /* 910 */, 0xB49B73B5503F2951LLU /* 911 */, 0x10168168C3F96B6BLLU /* 912 */, 0x0E3D963B63CAB0AELLU /* 913 */, 0x8DFC4B5655A1DB14LLU /* 914 */, 0xF789F1356E14DE5CLLU /* 915 */, 0x683E68AF4E51DAC1LLU /* 916 */, 0xC9A84F9D8D4B0FD9LLU /* 917 */, 0x3691E03F52A0F9D1LLU /* 918 */, 0x5ED86E46E1878E80LLU /* 919 */, 0x3C711A0E99D07150LLU /* 920 */, 0x5A0865B20C4E9310LLU /* 921 */, 0x56FBFC1FE4F0682ELLU /* 922 */, 0xEA8D5DE3105EDF9BLLU /* 923 */, 0x71ABFDB12379187ALLU /* 924 */, 0x2EB99DE1BEE77B9CLLU /* 925 */, 0x21ECC0EA33CF4523LLU /* 926 */, 0x59A4D7521805C7A1LLU /* 927 */, 0x3896F5EB56AE7C72LLU /* 928 */, 0xAA638F3DB18F75DCLLU /* 929 */, 0x9F39358DABE9808ELLU /* 930 */, 0xB7DEFA91C00B72ACLLU /* 931 */, 0x6B5541FD62492D92LLU /* 932 */, 0x6DC6DEE8F92E4D5BLLU /* 933 */, 0x353F57ABC4BEEA7ELLU /* 934 */, 0x735769D6DA5690CELLU /* 935 */, 0x0A234AA642391484LLU /* 936 */, 0xF6F9508028F80D9DLLU /* 937 */, 0xB8E319A27AB3F215LLU /* 938 */, 0x31AD9C1151341A4DLLU /* 939 */, 0x773C22A57BEF5805LLU /* 940 */, 0x45C7561A07968633LLU /* 941 */, 0xF913DA9E249DBE36LLU /* 942 */, 0xDA652D9B78A64C68LLU /* 943 */, 0x4C27A97F3BC334EFLLU /* 944 */, 0x76621220E66B17F4LLU /* 945 */, 0x967743899ACD7D0BLLU /* 946 */, 0xF3EE5BCAE0ED6782LLU /* 947 */, 0x409F753600C879FCLLU /* 948 */, 0x06D09A39B5926DB6LLU /* 949 */, 0x6F83AEB0317AC588LLU /* 950 */, 0x01E6CA4A86381F21LLU /* 951 */, 0x66FF3462D19F3025LLU /* 952 */, 0x72207C24DDFD3BFBLLU /* 953 */, 0x4AF6B6D3E2ECE2EBLLU /* 954 */, 0x9C994DBEC7EA08DELLU /* 955 */, 0x49ACE597B09A8BC4LLU /* 956 */, 0xB38C4766CF0797BALLU /* 957 */, 0x131B9373C57C2A75LLU /* 958 */, 0xB1822CCE61931E58LLU /* 959 */, 0x9D7555B909BA1C0CLLU /* 960 */, 0x127FAFDD937D11D2LLU /* 961 */, 0x29DA3BADC66D92E4LLU /* 962 */, 0xA2C1D57154C2ECBCLLU /* 963 */, 0x58C5134D82F6FE24LLU /* 964 */, 0x1C3AE3515B62274FLLU /* 965 */, 0xE907C82E01CB8126LLU /* 966 */, 0xF8ED091913E37FCBLLU /* 967 */, 0x3249D8F9C80046C9LLU /* 968 */, 0x80CF9BEDE388FB63LLU /* 969 */, 0x1881539A116CF19ELLU /* 970 */, 0x5103F3F76BD52457LLU /* 971 */, 0x15B7E6F5AE47F7A8LLU /* 972 */, 0xDBD7C6DED47E9CCFLLU /* 973 */, 0x44E55C410228BB1ALLU /* 974 */, 0xB647D4255EDB4E99LLU /* 975 */, 0x5D11882BB8AAFC30LLU /* 976 */, 0xF5098BBB29D3212ALLU /* 977 */, 0x8FB5EA14E90296B3LLU /* 978 */, 0x677B942157DD025ALLU /* 979 */, 0xFB58E7C0A390ACB5LLU /* 980 */, 0x89D3674C83BD4A01LLU /* 981 */, 0x9E2DA4DF4BF3B93BLLU /* 982 */, 0xFCC41E328CAB4829LLU /* 983 */, 0x03F38C96BA582C52LLU /* 984 */, 0xCAD1BDBD7FD85DB2LLU /* 985 */, 0xBBB442C16082AE83LLU /* 986 */, 0xB95FE86BA5DA9AB0LLU /* 987 */, 0xB22E04673771A93FLLU /* 988 */, 0x845358C9493152D8LLU /* 989 */, 0xBE2A488697B4541ELLU /* 990 */, 0x95A2DC2DD38E6966LLU /* 991 */, 0xC02C11AC923C852BLLU /* 992 */, 0x2388B1990DF2A87BLLU /* 993 */, 0x7C8008FA1B4F37BELLU /* 994 */, 0x1F70D0C84D54E503LLU /* 995 */, 0x5490ADEC7ECE57D4LLU /* 996 */, 0x002B3C27D9063A3ALLU /* 997 */, 0x7EAEA3848030A2BFLLU /* 998 */, 0xC602326DED2003C0LLU /* 999 */, 0x83A7287D69A94086LLU /* 1000 */, 0xC57A5FCB30F57A8ALLU /* 1001 */, 0xB56844E479EBE779LLU /* 1002 */, 0xA373B40F05DCBCE9LLU /* 1003 */, 0xD71A786E88570EE2LLU /* 1004 */, 0x879CBACDBDE8F6A0LLU /* 1005 */, 0x976AD1BCC164A32FLLU /* 1006 */, 0xAB21E25E9666D78BLLU /* 1007 */, 0x901063AAE5E5C33CLLU /* 1008 */, 0x9818B34448698D90LLU /* 1009 */, 0xE36487AE3E1E8ABBLLU /* 1010 */, 0xAFBDF931893BDCB4LLU /* 1011 */, 0x6345A0DC5FBBD519LLU /* 1012 */, 0x8628FE269B9465CALLU /* 1013 */, 0x1E5D01603F9C51ECLLU /* 1014 */, 0x4DE44006A15049B7LLU /* 1015 */, 0xBF6C70E5F776CBB1LLU /* 1016 */, 0x411218F2EF552BEDLLU /* 1017 */, 0xCB0C0708705A36A3LLU /* 1018 */, 0xE74D14754F986044LLU /* 1019 */, 0xCD56D9430EA8280ELLU /* 1020 */, 0xC12591D7535F5065LLU /* 1021 */, 0xC83223F1720AEF96LLU /* 1022 */, 0xC3A0396F7363A51FLLU /* 1023 */ }; #define sbox1 (table+256*0) #define sbox2 (table+256*1) #define sbox3 (table+256*2) #define sbox4 (table+256*3) int roar_hash_tiger_init(struct roar_hash_tiger * state) { if ( state == NULL ) return -1; memset(state, 0, sizeof(struct roar_hash_tiger)); state->a = 0x0123456789ABCDEFLLU; state->b = 0xFEDCBA9876543210LLU; state->c = 0xF096A5B4C3B2E187LLU; state->inlen = 0; state->blocks = 0; state->is_final = 0; return 0; } int roar_hash_tiger_uninit(struct roar_hash_tiger * state) { (void)state; return 0; } int roar_hash_tiger_init_from_pstate(struct roar_hash_tiger * state, void * oldstate) { uint64_t blocks; unsigned char * p = oldstate; if ( state == NULL || oldstate == NULL ) return -1; if ( roar_hash_tiger_init(state) == -1 ) return -1; #if BYTE_ORDER == BIG_ENDIAN && !defined(ROAR_TARGET_WIN32) #define _in(m) do { m = *(uint64_t*)p; p += 8; } while(0) #elif BYTE_ORDER == LITTLE_ENDIAN #define _S(x, n) (((uint64_t)(p[(n)])) << (uint64_t)(x)) #define _in(m) do { m = (uint64_t)(_S(56, 0) | _S(48, 1) | _S(40, 2) | _S(32, 3) | \ _S(24, 4) | _S(16, 5) | _S( 8, 6) | _S( 0, 7) \ ); p += 8; } while (0) #else ROAR_ERR("roar_hash_tiger_init_from_pstate(state=%p, ...): Tiger not implemented for non little or big endian systems!", state); return -1; #define _in #endif _in(state->a); _in(state->b); _in(state->c); _in(blocks); state->blocks = blocks; #undef _in return 0; } static int roar_hash_tiger_export(struct roar_hash_tiger * state, void * newstate, size_t * len, int is_pstate) { unsigned char * p = newstate; size_t needlen; uint64_t blocks; if ( is_pstate ) { needlen = PSTATE_LEN; } else { needlen = STATE_LEN; } if ( state == NULL || newstate == NULL || len == NULL ) return -1; if ( state->inlen != 0 ) return -1; if ( *len < needlen ) return -1; *len = needlen; #if BYTE_ORDER == BIG_ENDIAN && !defined(ROAR_TARGET_WIN32) #define _out(m) do { *(uint64_t*)p = m ; p += 8; } while(0) #elif BYTE_ORDER == LITTLE_ENDIAN #define _out(m) do { *p++ = m >> 56; *p++ = m >> 48; \ *p++ = m >> 40; *p++ = m >> 32; \ *p++ = m >> 24; *p++ = m >> 16; \ *p++ = m >> 8; *p++ = m; } while(0) #else ROAR_ERR("roar_hash_tiger_export(state=%p, ...): Tiger not implemented for non little or big endian systems!", state); return -1; #define _out #endif _out(state->a); _out(state->b); _out(state->c); if ( is_pstate ) { blocks = state->blocks; _out(blocks); } #undef _out return 0; } int roar_hash_tiger_to_pstate(struct roar_hash_tiger * state, void * newstate, size_t * len) { return roar_hash_tiger_export(state, newstate, len, 1); } ssize_t roar_hash_tiger_statelen(struct roar_hash_tiger * state) { (void)state; return PSTATE_LEN; } int roar_hash_tiger_finalize(struct roar_hash_tiger * state) { uint64_t len; if ( state == NULL ) return -1; if ( state->is_final ) return 0; len = state->blocks * BLOCK_LEN + state->inlen; len *= 8; // byte -> bit if ( state->inlen < 56 ) { /* enough room */ state->inbuf[state->inlen++] = 0x01; /* pad */ while ( state->inlen < 56 ) state->inbuf[state->inlen++] = 0; /* pad */ } else { /* need one extra block */ state->inbuf[state->inlen++] = 0x01; /* pad character */ while( state->inlen < 64 ) state->inbuf[state->inlen++] = 0; roar_hash_tiger_proc_block(state, state->inbuf); memset(state->inbuf, 0, 56); /* fill next block with zeroes */ } state->inbuf[56] = (len >> 0) & 0xFF; state->inbuf[57] = (len >> 8) & 0xFF; state->inbuf[58] = (len >> 16) & 0xFF; state->inbuf[59] = (len >> 24) & 0xFF; state->inbuf[60] = (len >> 32) & 0xFF; state->inbuf[61] = (len >> 40) & 0xFF; state->inbuf[62] = (len >> 48) & 0xFF; state->inbuf[63] = (len >> 56) & 0xFF; roar_hash_tiger_proc_block(state, state->inbuf); state->inlen = 0; state->is_final = 1; return 0; } int roar_hash_tiger_get_digest(struct roar_hash_tiger * state, void * digest, size_t * len) { if ( state == NULL || digest == NULL ) return -1; if ( roar_hash_tiger_finalize(state) == -1 ) return -1; return roar_hash_tiger_export(state, digest, len, 0); } static void tiger_round( uint64_t * ra, uint64_t * rb, uint64_t * rc, uint64_t x, uint64_t mul) { uint64_t a = *ra; uint64_t b = *rb; uint64_t c = *rc; c ^= x; a -= ( sbox1[ c & 0xff ] ^ sbox2[ (c >> 16) & 0xff ] ^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]); b += ( sbox4[ (c >> 8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ] ^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]); b *= mul; *ra = a; *rb = b; *rc = c; a = b = c = 0; } static void pass(uint64_t * ra, uint64_t * rb, uint64_t * rc, uint64_t * x, uint64_t mul) { tiger_round(ra, rb, rc, x[0], mul); tiger_round(rb, rc, ra, x[1], mul); tiger_round(rc, ra, rb, x[2], mul); tiger_round(ra, rb, rc, x[3], mul); tiger_round(rb, rc, ra, x[4], mul); tiger_round(rc, ra, rb, x[5], mul); tiger_round(ra, rb, rc, x[6], mul); tiger_round(rb, rc, ra, x[7], mul); } static void key_schedule(uint64_t * x) { x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL; x[1] ^= x[0]; x[2] += x[1]; x[3] -= x[2] ^ ((~x[1]) << 19 ); x[4] ^= x[3]; x[5] += x[4]; x[6] -= x[5] ^ ((~x[4]) >> 23 ); x[7] ^= x[6]; x[0] += x[7]; x[1] -= x[0] ^ ((~x[7]) << 19 ); x[2] ^= x[1]; x[3] += x[2]; x[4] -= x[3] ^ ((~x[2]) >> 23 ); x[5] ^= x[4]; x[6] += x[5]; x[7] -= x[6] ^ 0x0123456789abcdefLL; } int roar_hash_tiger_proc_block(struct roar_hash_tiger * state, void * block) { #if BYTE_ORDER == BIG_ENDIAN && !defined(ROAR_TARGET_WIN32) uint64_t * block64 = block; #endif uint64_t a, b, c, aa, bb, cc; uint64_t x[8]; ROAR_DBG("roar_hash_tiger_proc_block(state=%p, block=%p) = ?", state, block); if ( state == NULL || block == NULL ) return -1; #if BYTE_ORDER == BIG_ENDIAN && !defined(ROAR_TARGET_WIN32) #define MKWORD(d,n) \ ( ((uint64_t)(d)[8*(n)+7]) << 56 | ((uint64_t)(d)[8*(n)+6]) << 48 \ | ((uint64_t)(d)[8*(n)+5]) << 40 | ((uint64_t)(d)[8*(n)+4]) << 32 \ | ((uint64_t)(d)[8*(n)+3]) << 24 | ((uint64_t)(d)[8*(n)+2]) << 16 \ | ((uint64_t)(d)[8*(n)+1]) << 8 | ((uint64_t)(d)[8*(n) ]) ) x[0] = MKWORD(block64, 0); x[1] = MKWORD(block64, 1); x[2] = MKWORD(block64, 2); x[3] = MKWORD(block64, 3); x[4] = MKWORD(block64, 4); x[5] = MKWORD(block64, 5); x[6] = MKWORD(block64, 6); x[7] = MKWORD(block64, 7); #undef MKWORD #elif BYTE_ORDER == LITTLE_ENDIAN memcpy(x, block, 64); #else ROAR_ERR("roar_hash_tiger_proc_block(state=%p, block=%p): Tiger not implemented for non little or big endian systems!", state, block); return -1; #endif // save_abc aa = a = state->a; bb = b = state->b; cc = c = state->c; // main calcs: pass(&a, &b, &c, x, 5); key_schedule(x); pass(&c, &a, &b, x, 7); key_schedule(x); pass(&b, &c, &a, x, 9); // feedforward state->a = a ^ aa; state->b = b - bb; state->c = c + cc; state->blocks++; a = b = c = aa = bb = cc = 0; ROAR_DBG("roar_hash_tiger_proc_block(state=%p, block=%p) = 0", state, block); return 0; } ssize_t roar_hash_tiger_blocklen(struct roar_hash_tiger * state) { (void)state; return BLOCK_LEN; } int roar_hash_tiger_proc(struct roar_hash_tiger * state, void * data, size_t len) { size_t needlen; ROAR_DBG("roar_hash_tiger_proc(state=%p, data=%p, len=%llu) = ?", state, data, (long long unsigned int)len); if ( state == NULL ) return -1; if ( len == 0 ) return 0; if ( data == NULL ) return -1; if ( state->inlen ) { needlen = BLOCK_LEN - state->inlen; ROAR_DBG("roar_hash_tiger_proc(state=%p, ...): adding %llu byte to inbuf block", state, (long long unsigned int)needlen); if ( len < needlen ) { ROAR_DBG("roar_hash_tiger_proc(state=%p, ...): inbufblock is short", state); memcpy(state->inbuf + state->inlen, data, len); state->inlen += len; ROAR_DBG("roar_hash_tiger_proc(state=%p, ...) = 0", state); return 0; } memcpy(state->inbuf + state->inlen, data, needlen); len -= needlen; data += needlen; state->inlen = 0; if ( roar_hash_tiger_proc_block(state, state->inbuf) == -1 ) return -1; } for (; len >= BLOCK_LEN; ) { ROAR_DBG("roar_hash_tiger_proc(state=%p, ...): running normal block...", state); if ( roar_hash_tiger_proc_block(state, data) == -1 ) return -1; len -= BLOCK_LEN; data += BLOCK_LEN; } if ( len ) { ROAR_DBG("roar_hash_tiger_proc(state=%p, ...): adding %llu byte to new inbuf", state, (long long unsigned int)len); memcpy(state->inbuf, data, len); state->inlen = len; } ROAR_DBG("roar_hash_tiger_proc(state=%p, ...) = 0", state); return 0; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/keyval.c����������������������������������������������������������������0000644�0001750�0001750�00000012520�12264733541�015557� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//keyval.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" struct roar_keyval * roar_keyval_lookup (struct roar_keyval * kv, const char * key, ssize_t len, int casesens) { int (*sc)(const char *s1, const char *s2) = strcasecmp; ssize_t i; ROAR_DBG("roar_keyval_lookup(kv=%p, key=%p'%s', len=%li, casesens=%i) = ?", kv, key, key, (long int)len, casesens); if ( kv == NULL || key == NULL ) { ROAR_DBG("roar_keyval_lookup(kv=%p, key=%p'%s', len=%li, casesens=%i) = NULL //error=FAULT", kv, key, key, (long int)len, casesens); roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( casesens ) sc = strcmp; for (i = 0; len != -1 ? (i < len) : kv[i].key != NULL; i++) { if ( kv[i].key != NULL && !sc(key, kv[i].key) ) return &(kv[i]); } ROAR_DBG("roar_keyval_lookup(kv=%p, key=%p'%s', len=%li, casesens=%i) = NULL //error=NOENT", kv, key, key, (long int)len, casesens); roar_err_set(ROAR_ERROR_NOENT); return NULL; } static inline int is_in (const char c, const char * delm) { for (; *delm != 0; delm++) if ( *delm == c ) return 1; return 0; } static inline void skip_char(char * str) { memmove(str, str+1, roar_mm_strlen(str)); } ssize_t roar_keyval_split (struct roar_keyval ** kv, char * str, const char * fdel, const char * kdel, int quotes) { struct roar_keyval * kvs; int pos = -1; size_t len = 0; char * sp; char quote = 0; int last_was_seg = 0; if ( kv == NULL || str == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( fdel == NULL ) fdel = " \t,"; if ( kdel == NULL ) kdel = "=:"; // count num of segements: for (sp = str; *sp != 0; sp++) { if ( quote ) { if ( *sp == quote ) quote = 0; } else if ( quotes && (*sp == '\'' || *sp == '\"') ) { quote = *sp; } else { if ( last_was_seg ) { last_was_seg = !is_in(*sp, fdel); } else { if ( !is_in(*sp, fdel) ) { last_was_seg = 1; len++; } } } } kvs = roar_mm_malloc(sizeof(struct roar_keyval)*(len+1)); if ( kvs == NULL ) return -1; *kv = kvs; // End of Array Mark: kvs[len].key = NULL; kvs[len].value = NULL; // do the acctual filling: last_was_seg = 0; for (sp = str; *sp != 0; sp++) { if ( quote ) { if ( *sp == quote ) { skip_char(sp); quote = 0; } else { continue; } } else if ( quotes && (*sp == '\'' || *sp == '\"') ) { quote = *sp; skip_char(sp); continue; } if ( last_was_seg ) { if ( is_in(*sp, fdel) ) { last_was_seg = 0; *sp = 0; } else { last_was_seg = 1; if ( kvs[pos].value == NULL && is_in(*sp, kdel) ) { *sp = 0; kvs[pos].value = sp+1; } } } else { if ( !is_in(*sp, fdel) ) { last_was_seg = 1; pos++; kvs[pos].key = sp; kvs[pos].value = NULL; } } } return len; } static inline void _copy_str(char ** dst, const char * src) { for (; *src; src++, (*dst)++) **dst = *src; *((*dst)++) = 0; } void * roar_keyval_copy(struct roar_keyval ** copy, const struct roar_keyval * src, ssize_t len) { size_t buflen = 0; ssize_t i; void * ret; char * p; struct roar_keyval * c; if ( copy == NULL || src == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } // TODO: optimize this. if ( len == -1 ) { len = 0; for (i = 0; src[i].key != NULL || src[i].value != NULL; i++) len++; } for (i = 0; i < len; i++) { if ( src[i].key != NULL ) buflen += roar_mm_strlen(src[i].key) + 1; if ( src[i].value != NULL ) buflen += roar_mm_strlen(src[i].value) + 1; } c = roar_mm_malloc(len * sizeof(struct roar_keyval)); if ( c == NULL ) return NULL; memset(c, 0, len * sizeof(struct roar_keyval)); ret = roar_mm_malloc(buflen); if ( ret == NULL ) return NULL; memset(ret, 0, buflen); p = ret; for (i = 0; i < len; i++) { if ( src[i].key == NULL ) { c[i].key = NULL; } else { c[i].key = p; _copy_str(&p, src[i].key); } if ( src[i].value == NULL ) { c[i].value = NULL; } else { c[i].value = p; _copy_str(&p, src[i].value); } } *copy = c; return ret; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/kstore.c����������������������������������������������������������������0000644�0001750�0001750�00000013062�12264733541�015575� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//kstore.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define _LEN_DEFAULT 16 struct binkv { char * key; void * value; }; struct roar_kstore { size_t refc; int (*ref)(void *); int (*unref)(void *); const char * (*get_key)(void *); size_t len; struct binkv * kv; }; struct roar_kstore * roar_kstore_new(ssize_t len, int (*ref)(void *), int (*unref)(void *), const char * (*get_key)(void *)) { struct roar_kstore * ret = roar_mm_malloc(sizeof(struct roar_kstore)); int err; if ( ret == NULL ) return NULL; memset(ret, 0, sizeof(struct roar_kstore)); if ( len == -1 ) len = _LEN_DEFAULT; ret->kv = roar_mm_malloc(len*sizeof(struct binkv)); if ( ret->kv == NULL ) { err = roar_error; roar_mm_free(ret); roar_error = err; return NULL; } memset(ret->kv, 0, len*sizeof(struct binkv)); ret->refc = 1; ret->ref = ref; ret->unref = unref; ret->get_key = get_key; ret->len = len; return ret; } int roar_kstore_ref(struct roar_kstore * store) { if ( store == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } store->refc++; return 0; } int roar_kstore_unref(struct roar_kstore * store) { size_t i; if ( store == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } store->refc--; if ( store->refc ) return 0; if ( store->unref != NULL ) { for (i = 0; i < store->len; i++) { if ( store->kv[i].key == NULL ) continue; if ( store->unref(store->kv[i].value) == -1 ) return -1; roar_mm_free(store->kv[i].key); store->kv[i].key = NULL; store->kv[i].value = NULL; } } roar_mm_free(store->kv); roar_mm_free(store); return 0; } int roar_kstore_add(struct roar_kstore * store, void * obj, const char * key) { size_t i; int err; if ( store == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( key == NULL && store->get_key != NULL ) key = store->get_key(obj); if ( key == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } for (i = 0; i < store->len; i++) { if ( store->kv[i].key == NULL ) continue; if ( !strcmp(store->kv[i].key, key) ) { roar_err_set(ROAR_ERROR_EXIST); return -1; } } for (i = 0; i < store->len; i++) { if ( store->kv[i].key != NULL ) continue; store->kv[i].key = roar_mm_strdup(key); if ( store->kv[i].key == NULL ) return -1; store->kv[i].value = obj; if ( store->ref != NULL ) { if ( store->ref(obj) == -1 ) { err = roar_error; roar_mm_free(store->kv[i].key); store->kv[i].key = NULL; roar_error = err; return -1; } } return 0; } roar_err_set(ROAR_ERROR_NOSPC); return -1; } void * roar_kstore_get(struct roar_kstore * store, const char * key) { size_t i; if ( store == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } for (i = 0; i < store->len; i++) { if ( store->kv[i].key != NULL && !strcmp(store->kv[i].key, key) ) { if ( store->ref != NULL ) if ( store->ref(store->kv[i].value) == -1 ) return NULL; return store->kv[i].value; } } roar_err_set(ROAR_ERROR_NOENT); return NULL; } int roar_kstore_delete(struct roar_kstore * store, const char * key) { size_t i; if ( store == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; i < store->len; i++) { if ( store->kv[i].key != NULL && !strcmp(store->kv[i].key, key) ) { if ( store->unref != NULL ) if ( store->unref(store->kv[i].value) == -1 ) return -1; roar_mm_free(store->kv[i].key); store->kv[i].key = NULL; store->kv[i].value = NULL; return 0; } } roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_kstore_name(struct roar_kstore * store, const void * obj) { size_t i; if ( store == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } for (i = 0; i < store->len; i++) { ROAR_DBG("roar_kstore_name(store=%p, obj=%p): store->kv[%i].key=%p'%s', store->kv[%i].value=%p", store, obj, (int)i, store->kv[i].key, store->kv[i].key, (int)i, store->kv[i].value); if ( store->kv[i].key != NULL && store->kv[i].value == obj ) return store->kv[i].key; } roar_err_set(ROAR_ERROR_NOENT); return NULL; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/libroar.c���������������������������������������������������������������0000644�0001750�0001750�00000020367�12264733541�015726� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ /* ckport options: * ckport: ignore-symbol: sleep of target win32 -- checked by configure */ #include "libroar.h" #ifndef roar_mm_mlock int roar_mm_mlock(const void *addr, size_t len) { #if defined(ROAR_TARGET_WIN32) /* GlobalLock() generates errors. Maybe we do not use correctly. * We just ignore that at the moment and throw NOSYS. * * return GlobalLock(addr) == addr ? 0 : -1; */ roar_err_set(ROAR_ERROR_NOSYS); return -1; #elif defined(ROAR_TARGET_MICROCONTROLLER) return 0; #elif defined(_SC_PAGESIZE) long sz = sysconf(_SC_PAGESIZE); unsigned long int pos = (unsigned long int) addr; len += sz - (len % sz); pos -= pos % sz; return mlock((void*)pos, len); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } #endif #ifndef roar_mm_munlock int roar_mm_munlock(const void *addr, size_t len) { #if defined(ROAR_TARGET_WIN32) // TODO: find out what do do here. GlobalUnLock()? does such a function exist? // return GlobalLock(addr) == addr ? 0 : -1; roar_err_set(ROAR_ERROR_NOSYS); return -1; #elif defined(ROAR_TARGET_MICROCONTROLLER) return 0; #elif defined(_SC_PAGESIZE) long sz = sysconf(_SC_PAGESIZE); unsigned long int pos = (unsigned long int) addr; len += sz - (len % sz); pos -= pos % sz; return munlock((void*)pos, len); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } #endif // for compatibility with old versions: int _ROAR_MLOCK(const void *addr, size_t len) { roar_debug_warn_obsolete("_ROAR_MLOCK", "roar_mm_mlock", NULL); return roar_mm_mlock(addr, len); } int roar_usleep(uint_least32_t t) { #ifdef ROAR_TARGET_WIN32 Sleep(t/(uint_least32_t)1000); return 0; #elif defined(ROAR_HAVE_NANOSLEEP) struct timespec tv; struct timespec left; if ( t >= (uint_least32_t)1000000 ) { tv.tv_sec = t/(uint_least32_t)1000000; t -= tv.tv_sec*(uint_least32_t)1000000; } else { tv.tv_sec = 0; } tv.tv_nsec = t*(uint_least32_t)1000; while (nanosleep(&tv, &left) == -1) memcpy(&tv, &left, sizeof(tv)); return 0; #elif defined(ROAR_HAVE_USLEEP) usleep(t); return 0; #else ROAR_ERR("roar_usleep(t=%" LIBROAR__ll "u): can not sleep: not implemented", (LIBROAR__longlong unsigned int)t); roar_strap(ROAR_TRAP_GROUP_LIBROAR, "usleep.not-implemented"); roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } int roar_sleep(int t) { if ( t < 0 ) { roar_err_set(ROAR_ERROR_CAUSALITY); return -1; } #ifdef ROAR_TARGET_WIN32 Sleep(1000L*(long)t); #elif defined(ROAR_HAVE_SLEEP) while (t) t = sleep(t); #else while (t) { if ( roar_usleep(500000) == -1 ) return -1; if ( roar_usleep(500000) == -1 ) return -1; t--; } #endif return 0; } static pid_t _libroar_fork(void ** context, void * userdata) { #ifdef ROAR_HAVE_FORK pid_t ret; (void)context, (void)userdata; ret = fork(); if ( ret == -1 ) roar_err_from_errno(); return ret; #else roar_err_set(ROAR_ERROR_NOSYS); return (pid_t)-1; #endif } static const struct roar_libroar_forkapi _libroar_forkapi = { .prefork = NULL, .fork = _libroar_fork, .failed = NULL, .parent = NULL, .child = NULL, .userdata = NULL }; pid_t roar_fork(const struct roar_libroar_forkapi * api) { void * context = NULL; pid_t ret; if ( api == NULL ) api = &_libroar_forkapi; if ( api->fork == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( api->prefork != NULL ) { if ( api->prefork(&context, api->userdata) != 0 ) { if ( api->failed != NULL ) api->failed(&context, api->userdata); if ( context != NULL ) roar_mm_free_noerror(context); return (pid_t)-1; } } if ( (ret = api->fork(&context, api->userdata)) == (pid_t)-1 ) { if ( api->failed != NULL ) api->failed(&context, api->userdata); if ( context != NULL ) roar_mm_free_noerror(context); return (pid_t)-1; } if ( ret == (pid_t)0 ) { if ( api->child != NULL ) api->child(&context, api->userdata); } else { if ( api->parent != NULL ) api->parent(&context, api->userdata, ret); } if ( context != NULL ) roar_mm_free_noerror(context); return ret; } int roar_reset(enum roar_reset what) { char c; int i; enum roar_reset subsets = ROAR_RESET_NONE; roar_err_set(ROAR_ERROR_NONE); switch (what) { case ROAR_RESET_NONE: return 0; break; case ROAR_RESET_UNKNOWN: case ROAR_RESET_EOL: roar_err_set(ROAR_ERROR_INVAL); return -1; break; case ROAR_RESET_ON_FORK: subsets |= ROAR_RESET_MEMORY|ROAR_RESET_RANDOMPOOL; break; case ROAR_RESET_ON_EXIT: case ROAR_RESET_ON_PRE_EXEC: subsets |= ROAR_RESET_MEMORY|ROAR_RESET_CONFIG; break; default: if ( what & 0x80 ) { subsets |= what; } else { roar_err_set(ROAR_ERROR_INVAL); return -1; } break; } // strip 0x80 so we can easly test on the other bit per subsystem. what |= 0x80; what -= 0x80; if ( what & ROAR_RESET_MEMORY ) { (void)roar_mm_reset(); } if ( what & ROAR_RESET_CONFIG ) { roar_libroar_reset_config(); } if ( what & ROAR_RESET_RANDOMPOOL ) { for (i = 0; i < 16; i++) { roar_random_gen_nonce(&c, 1); roar_random_uint16(); roar_random_uint32(); } } roar_err_set(ROAR_ERROR_NONE); return 0; } void roar_panic_real(enum roar_fatal_error error, const char * info, unsigned long int line, const char * file, const char * prefix, const char * func) { const char * errname = NULL; //#define ROAR_ERR(format, args...) roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, __LINE__, __FILE__, ROAR_DBG_PREFIX, format, ## args) // we do not support info-text at the moment. (void)info; if ( func == NULL ) func = "<unknown>"; switch (error) { case ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD: roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, line, file, prefix, "in %s() a guard segment memory corruption was detected. Backup your data and terminate this program. Report this lion to developer. Thanks.", func); return; break; case ROAR_FATAL_ERROR_UNKNOWN: errname = "<unknown error>"; break; case ROAR_FATAL_ERROR_MEMORY_CORRUPTION: errname = "Memory corruption"; break; case ROAR_FATAL_ERROR_CPU_FAILURE: errname = "CPU failure, replace hardware"; break; case ROAR_FATAL_ERROR_MEMORY_USED_AFTER_FREE: errname = "Memory used after free"; break; case ROAR_FATAL_ERROR_MEMORY_DOUBLE_FREE: errname = "Memory double freed"; break; case ROAR_FATAL_ERROR_WATCHDOG: errname = "Watchdog Timeout"; break; default: errname = "<unknown error code, BAD>"; break; } roar_debug_msg(ROAR_DEBUG_TYPE_ERROR, line, file, prefix, "in %s() a _FATAL_ error of type \"%s\" was detected. Terminating program. Report this lion to developer. Thanks.", func, errname); #ifdef SIGKILL raise(SIGKILL); #endif abort(); #ifdef ROAR_HAVE_U_EXIT ROAR_U_EXIT(1); #endif while(1); } const char * roar_version_string(void) { return ROAR_VERSION_STRING; } uint32_t roar_version_num(void) { return _ROAR_MKVERSION(ROAR_VERSION_MAJOR, ROAR_VERSION_MINOR, ROAR_VERSION_REV); } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/ltm.c�������������������������������������������������������������������0000644�0001750�0001750�00000020621�12264733541�015061� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ltm.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" struct roar_ltm_result { int mt; int window; size_t streams; size_t nummt; size_t structlen; int64_t data[1]; }; static int roar_ltm_numbits(int f) { int found = 0; while (f) { if ( f & 0x1 ) found++; f >>= 1; } return found; } static int roar_ltm_pack_req(int mt, int window, int * streams, size_t slen, struct roar_message * mes, char ** buf, int regtype) { uint16_t * data; size_t i; if ( mt == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( streams == NULL || slen == 0 || mes == NULL || buf == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(mes, 0, sizeof(struct roar_message)); switch (regtype) { case ROAR_LTM_SST_REGISTER: case ROAR_LTM_SST_UNREGISTER: mes->cmd = ROAR_CMD_SET_STREAM_PARA; break; case ROAR_LTM_SST_GET_RAW: mes->cmd = ROAR_CMD_GET_STREAM_PARA; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } if ( slen == 1 ) { mes->stream = *streams; mes->datalen = 6 * 2; } else { mes->stream = -1; mes->datalen = (6 + slen) * 2; } if ( mes->datalen > LIBROAR_BUFFER_MSGDATA ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } *buf = NULL; data = (uint16_t*)mes->data; data[0] = 0; data[1] = ROAR_STREAM_PARA_LTM; data[2] = regtype; data[3] = window; data[4] = 0; data[5] = mt; for (i = 0; i < slen; i++) { data[6+i] = streams[i]; } for (i = 0; i < (mes->datalen/2); i++) { data[i] = ROAR_HOST2NET16(data[i]); } return 0; } static int roar_ltm_regunreg(struct roar_connection * con, int mt, int window, int * streams, size_t slen, int type) { struct roar_message mes; char * buf = NULL; int ret; if ( roar_ltm_pack_req(mt, window, streams, slen, &mes, &buf, type) == -1 ) return -1; ret = roar_req(con, &mes, &buf); if ( buf != NULL ) roar_mm_free(buf); if ( ret != -1 ) { if ( mes.cmd != ROAR_CMD_OK ) ret = -1; } return ret; } int roar_ltm_register(struct roar_connection * con, int mt, int window, int * streams, size_t slen) { return roar_ltm_regunreg(con, mt, window, streams, slen, ROAR_LTM_SST_REGISTER); } int roar_ltm_unregister(struct roar_connection * con, int mt, int window, int * streams, size_t slen) { return roar_ltm_regunreg(con, mt, window, streams, slen, ROAR_LTM_SST_UNREGISTER); } #ifdef DEBUG #define HEXDUMP64(x) roar_ltm_hexdump64((x)) static void roar_ltm_hexdump64(void * p) { unsigned char * d = p; ROAR_DBG("roar_ltm_hexdump64(p=%p): hex: %.2x%.2x %.2x%.2x %.2x%.2x %.2x%.2x", p, d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]); } #else #define HEXDUMP64(x) #endif struct roar_ltm_result * roar_ltm_get(struct roar_connection * con, int mt, int window, int * streams, size_t slen, struct roar_ltm_result * oldresult) { struct roar_ltm_result * res = NULL; struct roar_message mes; size_t needed_structlen = 0; int64_t * d64; char * buf = NULL; int ret; size_t i; if ( con == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( streams == NULL || slen == 0 ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( roar_ltm_pack_req(mt, window, streams, slen, &mes, &buf, ROAR_LTM_SST_GET_RAW) == -1 ) return NULL; ret = roar_req(con, &mes, &buf); if ( ret == -1 || mes.cmd != ROAR_CMD_OK ) { if ( buf != NULL ) roar_mm_free(buf); return NULL; } if ( buf == NULL ) { d64 = ( int64_t*)&(mes.data); } else { d64 = ( int64_t*)buf; } for (i = 0; i < mes.datalen/8; i++) { ROAR_DBG("roar_ltm_get(*): d64[i=%i]=%lli", i, (long long int)d64[i]); HEXDUMP64(&(d64[i])); d64[i] = ROAR_NET2HOST64(d64[i]); HEXDUMP64(&(d64[i])); ROAR_DBG("roar_ltm_get(*): d64[i=%i]=%lli", i, (long long int)d64[i]); } needed_structlen = sizeof(struct roar_ltm_result) + mes.datalen; if ( oldresult != NULL ) { if ( oldresult->structlen >= needed_structlen ) { res = oldresult; needed_structlen = oldresult->structlen; } else { roar_ltm_freeres(oldresult); } } else { res = roar_mm_malloc(needed_structlen); } if ( res == NULL ) { if ( buf != NULL ) roar_mm_free(buf); return NULL; } memset(res, 0, needed_structlen); res->structlen = needed_structlen; res->mt = mt; res->window = window; res->streams = slen; res->nummt = roar_ltm_numbits(mt); memcpy(res->data, d64, mes.datalen); if ( buf != NULL ) roar_mm_free(buf); return res; } #define _CKNULL(x) if ( (x) == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } #define _RETMEMBERCKED(x,m) _CKNULL(x) return (x)->m int roar_ltm_get_numstreams(struct roar_ltm_result * res) { _RETMEMBERCKED(res, streams); } int roar_ltm_get_mt(struct roar_ltm_result * res) { _RETMEMBERCKED(res, mt); } int roar_ltm_get_window(struct roar_ltm_result * res) { _RETMEMBERCKED(res, window); } static int64_t * roar_ltm_get_streamptr(struct roar_ltm_result * res, size_t streamidx) { int64_t * ptr; int numchans; size_t i; ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i) = ?", res, streamidx); if ( res == NULL || streamidx >= res->streams ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } ptr = res->data; ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i): res->data=%p", res, streamidx, res->data); for (i = 0; i < streamidx; i++) { numchans = *ptr & 0xFFFF; ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i): i=%i, numchans=%i", res, streamidx, i, numchans); ptr += res->nummt * numchans; ptr++; } ROAR_DBG("roar_ltm_get_streamptr(res=%p, streamidx=%i) = %p", res, streamidx, ptr); return ptr; } int roar_ltm_get_numchans(struct roar_ltm_result * res, size_t streamidx) { int64_t * ptr = roar_ltm_get_streamptr(res, streamidx); if ( ptr == NULL ) return -1; return *ptr & 0xFFFF; } int64_t roar_ltm_extract(struct roar_ltm_result * res, int mt, size_t streamidx, int channel) { int64_t * ptr = roar_ltm_get_streamptr(res, streamidx); int numchans; int resmt; ROAR_DBG("roar_ltm_extract(res=%p, mt=0x%.4x, streamidx=%i, channel=%i) = ?", res, mt, streamidx, channel); if ( roar_ltm_numbits(mt) != 1 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } ROAR_DBG("roar_ltm_extract(res=%p, mt=0x%.4x, streamidx=%i, channel=%i) = ?", res, mt, streamidx, channel); if ( ptr == NULL ) return -1; numchans = *ptr & 0xFFFF; ROAR_DBG("roar_ltm_extract(res=%p, mt=0x%.4x, streamidx=%i, channel=%i): numchans=%i", res, mt, streamidx, channel, numchans); if ( channel >= numchans ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } ptr++; ptr += res->nummt * channel; // now ptr points to the first mt for the given channel. resmt = res->mt; while (!(mt & 0x1)) { if ( resmt & 0x1 ) ptr++; mt >>= 1; resmt >>= 1; } ROAR_DBG("roar_ltm_extract(res=%p, mt=?, streamidx=%i, channel=%i): ptr=%p", res, streamidx, channel, ptr); ROAR_DBG("roar_ltm_extract(res=%p, mt=?, streamidx=%i, channel=%i) = %lli", res, streamidx, channel, (long long int)*ptr); return *ptr; } //ll ���������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/memmgr.c����������������������������������������������������������������0000644�0001750�0001750�00000026127�12264733542�015561� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//memmgr.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_USE_MEMMGR #define NULL_BUFFER_CONST "RoarAudio" static char _libroar_null_buffer[] = NULL_BUFFER_CONST; // A byte sequense >= 8 byte. static inline void _libroar_null_buffer_check(void) { if ( memcmp(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer)) != 0 ) roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD, NULL); memcpy(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer)); } #endif #define _err(x) do { roar_err_set((x)); return NULL; } while (0) #ifdef ROAR_HAVE_CALLOC static void * __libroar_calloc (void * userdata, size_t nmemb, size_t size) { void * ret; roar_err_clear_all(); ret = calloc(nmemb, size); roar_err_update(); return ret; } #endif #ifdef ROAR_HAVE_MALLOC static void * __libroar_malloc (void * userdata, size_t size) { void * ret; roar_err_clear_all(); ret = malloc(size); roar_err_update(); return ret; } #endif #ifdef ROAR_HAVE_FREE static int __libroar_free (void * userdata, void * ptr) { free(ptr); return 0; } #endif #ifdef ROAR_HAVE_REALLOC static void * __libroar_realloc (void * userdata, void * ptr, size_t size) { void * ret; roar_err_clear_all(); ret = realloc(ptr, size); roar_err_update(); return ret; } #endif static const struct roar_libroar_memmgrapi __memory_default_api = { #ifdef ROAR_HAVE_CALLOC .calloc = __libroar_calloc, #else .calloc = NULL, #endif #ifdef ROAR_HAVE_MALLOC .malloc = __libroar_malloc, #else .malloc = NULL, #endif #ifdef ROAR_HAVE_FREE .free = __libroar_free, #else .free = NULL, #endif #ifdef ROAR_HAVE_REALLOC .realloc = __libroar_realloc, #else .realloc = NULL, #endif .reset = NULL, // not needed .sizeofbuf = NULL, // not supported // Not yet supported: .mlock = NULL, .munlock = NULL, .mlockall = NULL, .munlockall = NULL, // no need with C API. .userdata = NULL }; static const struct roar_libroar_memmgrapi * memory_api = &__memory_default_api; int roar_libroar_set_memmgrapi(const struct roar_libroar_memmgrapi * api) { if ( api == NULL ) memory_api = &__memory_default_api; memory_api = api; return 0; } #ifdef ROAR_USE_MEMMGR int roar_mm_reset(void) { // currently this does nothing. // we need to free pools and such here later. if ( memory_api->reset != NULL ) return memory_api->reset(memory_api->userdata); return 0; } ssize_t roar_mm_sizeof(void * buf) { if ( buf == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( buf == _libroar_null_buffer_check ) return 0; if ( memory_api->sizeofbuf != NULL ) return memory_api->sizeofbuf(memory_api->userdata, buf); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } void * roar_mm_calloc(size_t nmemb, size_t size) { void * ret; if ( nmemb == 0 || size == 0 ) { _libroar_null_buffer_check(); return _libroar_null_buffer; } if ( memory_api->calloc != NULL ) { return memory_api->calloc(memory_api->userdata, nmemb, size); } else { ret = roar_mm_malloc(nmemb*size); if ( ret == NULL ) return NULL; memset(ret, 0, nmemb*size); return ret; } } void * roar_mm_malloc(size_t size) { if ( size == 0 ) { _libroar_null_buffer_check(); return _libroar_null_buffer; } if ( memory_api->malloc != NULL ) { return memory_api->malloc(memory_api->userdata, size); } else if ( memory_api->calloc != NULL ) { return roar_mm_calloc(1, size); } else if ( memory_api->realloc != NULL ) { return roar_mm_realloc(NULL, size); } else { _err(ROAR_ERROR_NOSYS); } } int roar_mm_free(void *ptr) { if ( ptr == _libroar_null_buffer ) { _libroar_null_buffer_check(); return 0; } if ( memory_api->free != NULL ) { return memory_api->free(memory_api->userdata, ptr); } else if ( memory_api->realloc != NULL ) { if ( roar_mm_realloc(ptr, 0) != _libroar_null_buffer ) return -1; return 0; } else { roar_err_set(ROAR_ERROR_NOSYS); return -1; } } void * roar_mm_realloc(void *ptr, size_t size) { void * ret; ssize_t len; if ( ptr == NULL ) return roar_mm_malloc(size); if ( size == 0 ) { roar_mm_free(ptr); _libroar_null_buffer_check(); return _libroar_null_buffer; } if ( memory_api->realloc != NULL ) { return memory_api->realloc(memory_api->userdata, ptr, size); } else { len = roar_mm_sizeof(ptr); if ( len == -1 ) return NULL; ret = roar_mm_malloc(size); if ( ret == NULL ) return NULL; memcpy(ret, ptr, len > (ssize_t)size ? size : len); return ret; } } #endif void * roar_mm_memdup(const void * s, size_t len) { void * ret; if ( s == NULL ) _err(ROAR_ERROR_FAULT); #ifdef ROAR_USE_MEMMGR if ( len == 0 ) { _libroar_null_buffer_check(); return _libroar_null_buffer; } #endif ret = roar_mm_malloc(len); if ( ret == NULL ) return NULL; memcpy(ret, s, len); return ret; } void roar_mm_free_retvoid(void *ptr) { roar_mm_free(ptr); } void roar_mm_free_noerror(void *ptr) { struct roar_error_state state; if ( ptr == NULL ) return; roar_err_store(&state); roar_mm_free(ptr); roar_err_restore(&state); } #if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRDUP) char * roar_mm_strdup(const char *s) { void * ret; #ifndef ROAR_HAVE_STRDUP ssize_t len; #endif if ( s == NULL ) _err(ROAR_ERROR_FAULT); #ifdef ROAR_HAVE_STRDUP roar_err_clear_all(); ret = strdup(s); if ( ret == NULL ) roar_err_update(); #else len = roar_mm_strlen(s); if ( len == -1 ) return NULL; ret = roar_mm_memdup(s, len+1); #endif return ret; } #endif #if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRNDUP) char *roar_mm_strndup(const char *s, size_t n) { void * ret; #ifndef ROAR_HAVE_STRNDUP ssize_t len; #endif if ( s == NULL ) _err(ROAR_ERROR_FAULT); #ifdef ROAR_USE_MEMMGR if ( n == 0 ) { _libroar_null_buffer_check(); return _libroar_null_buffer; } #endif #ifdef ROAR_HAVE_STRNDUP roar_err_clear_all(); ret = strndup(s, n); if ( ret == NULL ) roar_err_update(); #else len = roar_mm_strnlen(s, n); if ( len == -1 ) return NULL; ret = roar_mm_memdup(s, len+1); #endif return ret; } #endif char * roar_mm_strdup2(const char *s, const char *def) { if ( s == NULL ) s = def; if ( s == NULL ) { roar_err_clear(); return NULL; } return roar_mm_strdup(s); } #ifndef ROAR_HAVE_STRLEN ssize_t roar_mm_strlen(const char *s) { size_t ret = 0; if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (; *s != 0; s++, ret++); return ret; } #endif ssize_t roar_mm_strnlen(const char *s, size_t maxlen) { size_t ret = 0; if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } #ifdef ROAR_HAVE_STRNLEN ret = strnlen(s, maxlen); #else for (; ret < maxlen && *s != 0; s++, ret++); #endif if ( ret == maxlen ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } return ret; } #ifndef ROAR_HAVE_STRLCPY ssize_t roar_mm_strlcpy(char *dst, const char *src, size_t size) { ssize_t len; if ( dst == NULL || src == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( size == 0 ) return 0; len = roar_mm_strlen(src); if ( len == -1 ) return -1; if ( len < (ssize_t)size ) { memcpy(dst, src, len); dst[len] = 0; } else { memcpy(dst, src, size - 1); dst[size-1] = 0; } return len; } #endif #ifndef ROAR_HAVE_STRLCAT ssize_t roar_mm_strlcat(char *dst, const char *src, size_t size) { ssize_t slen; ssize_t dlen; int err; if ( dst == NULL || src == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( size == 0 ) return 0; slen = roar_mm_strlen(src); if ( slen == -1 ) return -1; dlen = roar_mm_strnlen(dst, size); err = roar_error; if ( dlen == -1 && err == ROAR_ERROR_MSGSIZE ) dlen = size; if ( dlen == -1 ) return -1; if ( (dlen + slen) < (ssize_t)size ) { memcpy(dst+dlen, src, slen); dst[dlen+slen] = 0; } else if ( dlen != (ssize_t)size ) { memcpy(dst+dlen, src, size-dlen-1); dst[size-1] = 0; } return dlen+slen; } #endif #ifndef ROAR_HAVE_STRTOK_R char * roar_mm_strtok_r(char *str, const char *delim, char **saveptr) { char * next; if ( delim == NULL || saveptr == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( delim[0] == 0 ) { roar_err_set(ROAR_ERROR_NOTSUP); return NULL; } if ( delim[1] != 0 ) { roar_err_set(ROAR_ERROR_NOTSUP); return NULL; } if ( str != NULL ) { next = str; } else { next = *saveptr; } if ( next == NULL ) { roar_err_set(ROAR_ERROR_NODATA); return NULL; } *saveptr = strstr(next, delim); if ( *saveptr != NULL ) { **saveptr = 0; (*saveptr)++; } return next; } #endif int roar_mm_strselcmp(const char *s1, const char *s2) { register char a, b; if ( s1 == s2 ) return 0; if ( s1 == NULL || s2 == NULL ) return -1; for (; ; s1++, s2++) { a = *s1; b = *s2; if ( a == '*' ) { s1++; a = *s1; if ( a == 0 ) { if ( b == 0 ) { return 1; // no match! ('*' does not mach no-chars) } else { return 0; // match! (string ends with '*' and something not EOS is in b) } } else { for (; *s2 != 0 && *s2 != a; s2++); if ( a != *s2 ) return 1; // no match! (did not find correct char) } } else if ( a == 0 || b == 0 ) { if ( a == b ) { return 0; // match! } else { return 1; // no match! (dffrent length) } } else if ( a != b ) { return 1; // no match! (diffrent chars) } } return -1; } ssize_t roar_mm_strseltok(const char *s1, char *s2, char ** tok, size_t toks) { register char a, b; size_t idx = 0; if ( s1 == NULL || s2 == NULL ) return -1; for (; ; s1++, s2++) { a = *s1; b = *s2; if ( a == 0 || b == 0 ) { if ( a == b ) { return idx; } else { return -1; } } else if ( a == '*' ) { s1++; a = *s1; if ( idx == toks ) return -1; tok[idx] = s2; idx++; for (; *s2 != 0 && *s2 != a; s2++); if ( a == 0 ) return idx; if ( *s1 == 0 ) return -1; *s2 = 0; } } return -1; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/meta.c������������������������������������������������������������������0000644�0001750�0001750�00000065537�12264733542�015233� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//meta.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" /* grep ^'#define ROAR_META_TYPE_' meta.h | cut -d' ' -f2 | while read line; do printf ' {%-30s "%-16s},\n' $line, $(echo $line | cut -d_ -f4)\"; done */ static struct { int id; const char * name; } _libroar_meta_typelist[] = { {ROAR_META_TYPE_NONE, "NONE" }, {ROAR_META_TYPE_TITLE, "TITLE" }, {ROAR_META_TYPE_ALBUM, "ALBUM" }, {ROAR_META_TYPE_AUTHOR, "AUTHOR" }, {ROAR_META_TYPE_AUTOR, "AUTOR" }, {ROAR_META_TYPE_ARTIST, "ARTIST" }, {ROAR_META_TYPE_VERSION, "VERSION" }, {ROAR_META_TYPE_DATE, "DATE" }, {ROAR_META_TYPE_LICENSE, "LICENSE" }, {ROAR_META_TYPE_TRACKNUMBER, "TRACKNUMBER" }, {ROAR_META_TYPE_ORGANIZATION, "ORGANIZATION" }, {ROAR_META_TYPE_DESCRIPTION, "DESCRIPTION" }, {ROAR_META_TYPE_GENRE, "GENRE" }, {ROAR_META_TYPE_LOCATION, "LOCATION" }, {ROAR_META_TYPE_CONTACT, "CONTACT" }, {ROAR_META_TYPE_STREAMURL, "STREAMURL" }, {ROAR_META_TYPE_HOMEPAGE, "HOMEPAGE" }, {ROAR_META_TYPE_THUMBNAIL, "THUMBNAIL" }, {ROAR_META_TYPE_LENGTH, "LENGTH" }, {ROAR_META_TYPE_COMMENT, "COMMENT" }, {ROAR_META_TYPE_OTHER, "OTHER" }, {ROAR_META_TYPE_FILENAME, "FILENAME" }, {ROAR_META_TYPE_FILEURL, "FILEURL" }, {ROAR_META_TYPE_SERVER, "SERVER" }, {ROAR_META_TYPE_DURATION, "DURATION" }, {ROAR_META_TYPE_WWW, "WWW" }, {ROAR_META_TYPE_WOAF, "WOAF" }, {ROAR_META_TYPE_ENCODER, "ENCODER" }, {ROAR_META_TYPE_ENCODEDBY, "ENCODEDBY" }, {ROAR_META_TYPE_ENCODEDBY, "ENCODED-BY" }, // alias {ROAR_META_TYPE_YEAR, "YEAR" }, {ROAR_META_TYPE_DISCID, "DISCID" }, {ROAR_META_TYPE_RPG_TRACK_PEAK, "REPLAYGAIN_TRACK_PEAK" }, {ROAR_META_TYPE_RPG_TRACK_GAIN, "REPLAYGAIN_TRACK_GAIN" }, {ROAR_META_TYPE_RPG_ALBUM_PEAK, "REPLAYGAIN_ALBUM_PEAK" }, {ROAR_META_TYPE_RPG_ALBUM_GAIN, "REPLAYGAIN_ALBUM_GAIN" }, {ROAR_META_TYPE_HASH, "HASH" }, {ROAR_META_TYPE_SIGNALINFO, "SIGNALINFO" }, {ROAR_META_TYPE_AUDIOINFO, "AUDIOINFO" }, {ROAR_META_TYPE_OFFSET, "OFFSET" }, {ROAR_META_TYPE_PERFORMER, "PERFORMER" }, {ROAR_META_TYPE_COPYRIGHT, "COPYRIGHT" }, {ROAR_META_TYPE_LIKENESS, "LIKENESS" }, {ROAR_META_TYPE_COMPOSER, "COMPOSER" }, {ROAR_META_TYPE_RIGHTS, "RIGHTS" }, {ROAR_META_TYPE_ISRC, "ISRC" }, {ROAR_META_TYPE_LANGUAGE, "LANGUAGE" }, {ROAR_META_TYPE_GTIN, "GTIN" }, {ROAR_META_TYPE_GTIN, "EAN/UPN" }, // alias {ROAR_META_TYPE_GTIN, "UPN" }, // alias {ROAR_META_TYPE_ISBN, "ISBN" }, {ROAR_META_TYPE_EAN, "EAN" }, {ROAR_META_TYPE_PUBLISHER, "PUBLISHER" }, {ROAR_META_TYPE_DISCNUMBER, "DISCNUMBER" }, {ROAR_META_TYPE_SOURCEMEDIA, "SOURCEMEDIA" }, {ROAR_META_TYPE_LABEL, "LABEL" }, {ROAR_META_TYPE_LABELNO, "LABELNO" }, {-1, "EOL"} }; static struct { int id; const char * name; } _libroar_meta_genrelist[] = { {ROAR_META_GENRE_META_NONE, "meta_none"}, {ROAR_META_GENRE_META_NONE, "none"}, {ROAR_META_GENRE_META_OTHER, "meta_other"}, {ROAR_META_GENRE_META_OTHER, "other"}, {ROAR_META_GENRE_META_MUSIC, "meta_music"}, {ROAR_META_GENRE_META_MUSIC, "music"}, {ROAR_META_GENRE_META_MODERATION, "meta_moderation"}, {ROAR_META_GENRE_META_MODERATION, "moderation"}, {ROAR_META_GENRE_META_TEXT, "meta_text"}, {ROAR_META_GENRE_META_TEXT, "text"}, {ROAR_META_GENRE_META_COMMERCIAL, "meta_commercial"}, {ROAR_META_GENRE_META_COMMERCIAL, "commercial"}, {ROAR_META_GENRE_RDS_EU_NONE, "rds_eu_none"}, {ROAR_META_GENRE_RDS_EU_NONE, "none"}, {ROAR_META_GENRE_RDS_EU_NEWS, "rds_eu_news"}, {ROAR_META_GENRE_RDS_EU_NEWS, "news"}, {ROAR_META_GENRE_RDS_EU_CURRENT_AFFAIRS, "rds_eu_current_affairs"}, {ROAR_META_GENRE_RDS_EU_CURRENT_AFFAIRS, "current affairs"}, {ROAR_META_GENRE_RDS_EU_INFORMATION, "rds_eu_information"}, {ROAR_META_GENRE_RDS_EU_INFORMATION, "information"}, {ROAR_META_GENRE_RDS_EU_SPORT, "rds_eu_sport"}, {ROAR_META_GENRE_RDS_EU_SPORT, "sport"}, {ROAR_META_GENRE_RDS_EU_EDUCATION, "rds_eu_education"}, {ROAR_META_GENRE_RDS_EU_EDUCATION, "education"}, {ROAR_META_GENRE_RDS_EU_DRAMA, "rds_eu_drama"}, {ROAR_META_GENRE_RDS_EU_DRAMA, "drama"}, {ROAR_META_GENRE_RDS_EU_CULTURE, "rds_eu_culture"}, {ROAR_META_GENRE_RDS_EU_CULTURE, "culture"}, {ROAR_META_GENRE_RDS_EU_SCIENCE, "rds_eu_science"}, {ROAR_META_GENRE_RDS_EU_SCIENCE, "science"}, {ROAR_META_GENRE_RDS_EU_VARIED, "rds_eu_varied"}, {ROAR_META_GENRE_RDS_EU_VARIED, "varied"}, {ROAR_META_GENRE_RDS_EU_POP_MUSIC, "rds_eu_pop_music"}, {ROAR_META_GENRE_RDS_EU_POP_MUSIC, "pop music"}, {ROAR_META_GENRE_RDS_EU_ROCK_MUSIC, "rds_eu_rock_music"}, {ROAR_META_GENRE_RDS_EU_ROCK_MUSIC, "rock music"}, {ROAR_META_GENRE_RDS_EU_EASY_LISTENING, "rds_eu_easy_listening"}, {ROAR_META_GENRE_RDS_EU_EASY_LISTENING, "easy listening"}, {ROAR_META_GENRE_RDS_EU_LIGHT_CLASSICAL, "rds_eu_light_classical"}, {ROAR_META_GENRE_RDS_EU_LIGHT_CLASSICAL, "light classical"}, {ROAR_META_GENRE_RDS_EU_SERIOUS_CLASSICAL, "rds_eu_serious_classical"}, {ROAR_META_GENRE_RDS_EU_SERIOUS_CLASSICAL, "serious classical"}, {ROAR_META_GENRE_RDS_EU_OTHER_MUSIC, "rds_eu_other_music"}, {ROAR_META_GENRE_RDS_EU_OTHER_MUSIC, "other music"}, {ROAR_META_GENRE_RDS_EU_WEATHER, "rds_eu_weather"}, {ROAR_META_GENRE_RDS_EU_WEATHER, "weather"}, {ROAR_META_GENRE_RDS_EU_FINANCE, "rds_eu_finance"}, {ROAR_META_GENRE_RDS_EU_FINANCE, "finance"}, {ROAR_META_GENRE_RDS_EU_CHILDREN_S_PROGRAMMES, "rds_eu_children_s_programmes"}, {ROAR_META_GENRE_RDS_EU_CHILDREN_S_PROGRAMMES, "children s programmes"}, {ROAR_META_GENRE_RDS_EU_SOCIAL_AFFAIRS, "rds_eu_social_affairs"}, {ROAR_META_GENRE_RDS_EU_SOCIAL_AFFAIRS, "social affairs"}, {ROAR_META_GENRE_RDS_EU_RELIGION, "rds_eu_religion"}, {ROAR_META_GENRE_RDS_EU_RELIGION, "religion"}, {ROAR_META_GENRE_RDS_EU_PHONE_IN, "rds_eu_phone_in"}, {ROAR_META_GENRE_RDS_EU_PHONE_IN, "phone in"}, {ROAR_META_GENRE_RDS_EU_TRAVEL, "rds_eu_travel"}, {ROAR_META_GENRE_RDS_EU_TRAVEL, "travel"}, {ROAR_META_GENRE_RDS_EU_LEISURE, "rds_eu_leisure"}, {ROAR_META_GENRE_RDS_EU_LEISURE, "leisure"}, {ROAR_META_GENRE_RDS_EU_JAZZ_MUSIC, "rds_eu_jazz_music"}, {ROAR_META_GENRE_RDS_EU_JAZZ_MUSIC, "jazz music"}, {ROAR_META_GENRE_RDS_EU_COUNTRY_MUSIC, "rds_eu_country_music"}, {ROAR_META_GENRE_RDS_EU_COUNTRY_MUSIC, "country music"}, {ROAR_META_GENRE_RDS_EU_NATIONAL_MUSIC, "rds_eu_national_music"}, {ROAR_META_GENRE_RDS_EU_NATIONAL_MUSIC, "national music"}, {ROAR_META_GENRE_RDS_EU_OLDIES_MUSIC, "rds_eu_oldies_music"}, {ROAR_META_GENRE_RDS_EU_OLDIES_MUSIC, "oldies music"}, {ROAR_META_GENRE_RDS_EU_FOLK_MUSIC, "rds_eu_folk_music"}, {ROAR_META_GENRE_RDS_EU_FOLK_MUSIC, "folk music"}, {ROAR_META_GENRE_RDS_EU_DOCUMENTARY, "rds_eu_documentary"}, {ROAR_META_GENRE_RDS_EU_DOCUMENTARY, "documentary"}, {ROAR_META_GENRE_RDS_EU_ALARM_TEST, "rds_eu_alarm_test"}, {ROAR_META_GENRE_RDS_EU_ALARM_TEST, "alarm test"}, {ROAR_META_GENRE_RDS_EU_ALARM, "rds_eu_alarm"}, {ROAR_META_GENRE_RDS_EU_ALARM, "alarm"}, {ROAR_META_GENRE_RDS_EU_EMERGENCY_TEST, "rds_eu_emergency_test"}, {ROAR_META_GENRE_RDS_EU_EMERGENCY_TEST, "emergency test"}, {ROAR_META_GENRE_RDS_EU_EMERGENCY, "rds_eu_emergency"}, {ROAR_META_GENRE_RDS_EU_EMERGENCY, "emergency"}, {ROAR_META_GENRE_RDS_NA_NONE, "rds_na_none"}, {ROAR_META_GENRE_RDS_NA_NONE, "none"}, {ROAR_META_GENRE_RDS_NA_NEWS, "rds_na_news"}, {ROAR_META_GENRE_RDS_NA_NEWS, "news"}, {ROAR_META_GENRE_RDS_NA_INFORMATION, "rds_na_information"}, {ROAR_META_GENRE_RDS_NA_INFORMATION, "information"}, {ROAR_META_GENRE_RDS_NA_SPORTS, "rds_na_sports"}, {ROAR_META_GENRE_RDS_NA_SPORTS, "sports"}, {ROAR_META_GENRE_RDS_NA_TALK, "rds_na_talk"}, {ROAR_META_GENRE_RDS_NA_TALK, "talk"}, {ROAR_META_GENRE_RDS_NA_ROCK, "rds_na_rock"}, {ROAR_META_GENRE_RDS_NA_ROCK, "rock"}, {ROAR_META_GENRE_RDS_NA_CLASSIC_ROCK, "rds_na_classic_rock"}, {ROAR_META_GENRE_RDS_NA_CLASSIC_ROCK, "classic rock"}, {ROAR_META_GENRE_RDS_NA_ADULT_HITS, "rds_na_adult_hits"}, {ROAR_META_GENRE_RDS_NA_ADULT_HITS, "adult hits"}, {ROAR_META_GENRE_RDS_NA_SOFT_ROCK, "rds_na_soft_rock"}, {ROAR_META_GENRE_RDS_NA_SOFT_ROCK, "soft rock"}, {ROAR_META_GENRE_RDS_NA_TOP_40, "rds_na_top_40"}, {ROAR_META_GENRE_RDS_NA_TOP_40, "top 40"}, {ROAR_META_GENRE_RDS_NA_COUNTRY, "rds_na_country"}, {ROAR_META_GENRE_RDS_NA_COUNTRY, "country"}, {ROAR_META_GENRE_RDS_NA_OLDIES, "rds_na_oldies"}, {ROAR_META_GENRE_RDS_NA_OLDIES, "oldies"}, {ROAR_META_GENRE_RDS_NA_SOFT, "rds_na_soft"}, {ROAR_META_GENRE_RDS_NA_SOFT, "soft"}, {ROAR_META_GENRE_RDS_NA_NOSTALGIA, "rds_na_nostalgia"}, {ROAR_META_GENRE_RDS_NA_NOSTALGIA, "nostalgia"}, {ROAR_META_GENRE_RDS_NA_JAZZ, "rds_na_jazz"}, {ROAR_META_GENRE_RDS_NA_JAZZ, "jazz"}, {ROAR_META_GENRE_RDS_NA_CLASSICAL, "rds_na_classical"}, {ROAR_META_GENRE_RDS_NA_CLASSICAL, "classical"}, {ROAR_META_GENRE_RDS_NA_RHYTHM_AND_BLUES, "rds_na_rhythm_and_blues"}, {ROAR_META_GENRE_RDS_NA_RHYTHM_AND_BLUES, "rhythm and blues"}, {ROAR_META_GENRE_RDS_NA_SOFT_RHYTHM_AND_BLUES, "rds_na_soft_rhythm_and_blues"}, {ROAR_META_GENRE_RDS_NA_SOFT_RHYTHM_AND_BLUES, "soft rhythm and blues"}, {ROAR_META_GENRE_RDS_NA_LANGUAGE, "rds_na_language"}, {ROAR_META_GENRE_RDS_NA_LANGUAGE, "language"}, {ROAR_META_GENRE_RDS_NA_RELIGIOUS_MUSIC, "rds_na_religious_music"}, {ROAR_META_GENRE_RDS_NA_RELIGIOUS_MUSIC, "religious music"}, {ROAR_META_GENRE_RDS_NA_RELIGIOUS_TALK, "rds_na_religious_talk"}, {ROAR_META_GENRE_RDS_NA_RELIGIOUS_TALK, "religious talk"}, {ROAR_META_GENRE_RDS_NA_PERSONALITY, "rds_na_personality"}, {ROAR_META_GENRE_RDS_NA_PERSONALITY, "personality"}, {ROAR_META_GENRE_RDS_NA_PUBLIC, "rds_na_public"}, {ROAR_META_GENRE_RDS_NA_PUBLIC, "public"}, {ROAR_META_GENRE_RDS_NA_COLLEGE, "rds_na_college"}, {ROAR_META_GENRE_RDS_NA_COLLEGE, "college"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_0, "rds_na_unassigned_0"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_0, "unassigned 0"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_1, "rds_na_unassigned_1"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_1, "unassigned 1"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_2, "rds_na_unassigned_2"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_2, "unassigned 2"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_3, "rds_na_unassigned_3"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_3, "unassigned 3"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_4, "rds_na_unassigned_4"}, {ROAR_META_GENRE_RDS_NA_UNASSIGNED_4, "unassigned 4"}, {ROAR_META_GENRE_RDS_NA_WEATHER, "rds_na_weather"}, {ROAR_META_GENRE_RDS_NA_WEATHER, "weather"}, {ROAR_META_GENRE_RDS_NA_EMERGENCY_TEST, "rds_na_emergency_test"}, {ROAR_META_GENRE_RDS_NA_EMERGENCY_TEST, "emergency test"}, {ROAR_META_GENRE_RDS_NA_EMERGENCY, "rds_na_emergency"}, {ROAR_META_GENRE_RDS_NA_EMERGENCY, "emergency"}, {ROAR_META_GENRE_RDS_NA_ALARM_TEST, "rds_na_alarm_test"}, {ROAR_META_GENRE_RDS_NA_ALARM_TEST, "alarm test"}, {ROAR_META_GENRE_RDS_NA_ALARM, "rds_na_alarm"}, {ROAR_META_GENRE_RDS_NA_ALARM, "alarm"}, {ROAR_META_GENRE_ID3_BLUES, "id3_blues"}, {ROAR_META_GENRE_ID3_BLUES, "blues"}, {ROAR_META_GENRE_ID3_CLASSIC_ROCK, "id3_classic_rock"}, {ROAR_META_GENRE_ID3_CLASSIC_ROCK, "classic rock"}, {ROAR_META_GENRE_ID3_COUNTRY, "id3_country"}, {ROAR_META_GENRE_ID3_COUNTRY, "country"}, {ROAR_META_GENRE_ID3_DANCE, "id3_dance"}, {ROAR_META_GENRE_ID3_DANCE, "dance"}, {ROAR_META_GENRE_ID3_DISCO, "id3_disco"}, {ROAR_META_GENRE_ID3_DISCO, "disco"}, {ROAR_META_GENRE_ID3_FUNK, "id3_funk"}, {ROAR_META_GENRE_ID3_FUNK, "funk"}, {ROAR_META_GENRE_ID3_GRUNGE, "id3_grunge"}, {ROAR_META_GENRE_ID3_GRUNGE, "grunge"}, {ROAR_META_GENRE_ID3_HIP_HOP, "id3_hip_hop"}, {ROAR_META_GENRE_ID3_HIP_HOP, "hip hop"}, {ROAR_META_GENRE_ID3_JAZZ, "id3_jazz"}, {ROAR_META_GENRE_ID3_JAZZ, "jazz"}, {ROAR_META_GENRE_ID3_METAL, "id3_metal"}, {ROAR_META_GENRE_ID3_METAL, "metal"}, {ROAR_META_GENRE_ID3_NEW_AGE, "id3_new_age"}, {ROAR_META_GENRE_ID3_NEW_AGE, "new age"}, {ROAR_META_GENRE_ID3_OLDIES, "id3_oldies"}, {ROAR_META_GENRE_ID3_OLDIES, "oldies"}, {ROAR_META_GENRE_ID3_OTHER, "id3_other"}, {ROAR_META_GENRE_ID3_OTHER, "other"}, {ROAR_META_GENRE_ID3_POP, "id3_pop"}, {ROAR_META_GENRE_ID3_POP, "pop"}, {ROAR_META_GENRE_ID3_R_AND_B, "id3_r_and_b"}, {ROAR_META_GENRE_ID3_R_AND_B, "r and b"}, {ROAR_META_GENRE_ID3_RAP, "id3_rap"}, {ROAR_META_GENRE_ID3_RAP, "rap"}, {ROAR_META_GENRE_ID3_REGGAE, "id3_reggae"}, {ROAR_META_GENRE_ID3_REGGAE, "reggae"}, {ROAR_META_GENRE_ID3_ROCK, "id3_rock"}, {ROAR_META_GENRE_ID3_ROCK, "rock"}, {ROAR_META_GENRE_ID3_TECHNO, "id3_techno"}, {ROAR_META_GENRE_ID3_TECHNO, "techno"}, {ROAR_META_GENRE_ID3_INDUSTRIAL, "id3_industrial"}, {ROAR_META_GENRE_ID3_INDUSTRIAL, "industrial"}, {ROAR_META_GENRE_ID3_ALTERNATIVE, "id3_alternative"}, {ROAR_META_GENRE_ID3_ALTERNATIVE, "alternative"}, {ROAR_META_GENRE_ID3_SKA, "id3_ska"}, {ROAR_META_GENRE_ID3_SKA, "ska"}, {ROAR_META_GENRE_ID3_DEATH_METAL, "id3_death_metal"}, {ROAR_META_GENRE_ID3_DEATH_METAL, "death metal"}, {ROAR_META_GENRE_ID3_PRANKS, "id3_pranks"}, {ROAR_META_GENRE_ID3_PRANKS, "pranks"}, {ROAR_META_GENRE_ID3_SOUNDTRACK, "id3_soundtrack"}, {ROAR_META_GENRE_ID3_SOUNDTRACK, "soundtrack"}, {ROAR_META_GENRE_ID3_EURO_TECHNO, "id3_euro_techno"}, {ROAR_META_GENRE_ID3_EURO_TECHNO, "euro techno"}, {ROAR_META_GENRE_ID3_AMBIENT, "id3_ambient"}, {ROAR_META_GENRE_ID3_AMBIENT, "ambient"}, {ROAR_META_GENRE_ID3_TRIP_HOP, "id3_trip_hop"}, {ROAR_META_GENRE_ID3_TRIP_HOP, "trip hop"}, {ROAR_META_GENRE_ID3_VOCAL, "id3_vocal"}, {ROAR_META_GENRE_ID3_VOCAL, "vocal"}, {ROAR_META_GENRE_ID3_JAZZ_FUNK, "id3_jazz_funk"}, {ROAR_META_GENRE_ID3_JAZZ_FUNK, "jazz funk"}, {ROAR_META_GENRE_ID3_FUSION, "id3_fusion"}, {ROAR_META_GENRE_ID3_FUSION, "fusion"}, {ROAR_META_GENRE_ID3_TRANCE, "id3_trance"}, {ROAR_META_GENRE_ID3_TRANCE, "trance"}, {ROAR_META_GENRE_ID3_CLASSICAL, "id3_classical"}, {ROAR_META_GENRE_ID3_CLASSICAL, "classical"}, {ROAR_META_GENRE_ID3_INSTRUMENTAL, "id3_instrumental"}, {ROAR_META_GENRE_ID3_INSTRUMENTAL, "instrumental"}, {ROAR_META_GENRE_ID3_ACID, "id3_acid"}, {ROAR_META_GENRE_ID3_ACID, "acid"}, {ROAR_META_GENRE_ID3_HOUSE, "id3_house"}, {ROAR_META_GENRE_ID3_HOUSE, "house"}, {ROAR_META_GENRE_ID3_GAME, "id3_game"}, {ROAR_META_GENRE_ID3_GAME, "game"}, {ROAR_META_GENRE_ID3_SOUND_CLIP, "id3_sound_clip"}, {ROAR_META_GENRE_ID3_SOUND_CLIP, "sound clip"}, {ROAR_META_GENRE_ID3_GOSPEL, "id3_gospel"}, {ROAR_META_GENRE_ID3_GOSPEL, "gospel"}, {ROAR_META_GENRE_ID3_NOISE, "id3_noise"}, {ROAR_META_GENRE_ID3_NOISE, "noise"}, {ROAR_META_GENRE_ID3_ALTERNROCK, "id3_alternrock"}, {ROAR_META_GENRE_ID3_ALTERNROCK, "alternrock"}, {ROAR_META_GENRE_ID3_BASS, "id3_bass"}, {ROAR_META_GENRE_ID3_BASS, "bass"}, {ROAR_META_GENRE_ID3_SOUL, "id3_soul"}, {ROAR_META_GENRE_ID3_SOUL, "soul"}, {ROAR_META_GENRE_ID3_PUNK, "id3_punk"}, {ROAR_META_GENRE_ID3_PUNK, "punk"}, {ROAR_META_GENRE_ID3_SPACE, "id3_space"}, {ROAR_META_GENRE_ID3_SPACE, "space"}, {ROAR_META_GENRE_ID3_MEDITATIVE, "id3_meditative"}, {ROAR_META_GENRE_ID3_MEDITATIVE, "meditative"}, {ROAR_META_GENRE_ID3_INSTRUMENTAL_POP, "id3_instrumental_pop"}, {ROAR_META_GENRE_ID3_INSTRUMENTAL_POP, "instrumental pop"}, {ROAR_META_GENRE_ID3_INSTRUMENTAL_ROCK, "id3_instrumental_rock"}, {ROAR_META_GENRE_ID3_INSTRUMENTAL_ROCK, "instrumental rock"}, {ROAR_META_GENRE_ID3_ETHNIC, "id3_ethnic"}, {ROAR_META_GENRE_ID3_ETHNIC, "ethnic"}, {ROAR_META_GENRE_ID3_GOTHIC, "id3_gothic"}, {ROAR_META_GENRE_ID3_GOTHIC, "gothic"}, {ROAR_META_GENRE_ID3_DARKWAVE, "id3_darkwave"}, {ROAR_META_GENRE_ID3_DARKWAVE, "darkwave"}, {ROAR_META_GENRE_ID3_TECHNO_INDUSTRIAL, "id3_techno_industrial"}, {ROAR_META_GENRE_ID3_TECHNO_INDUSTRIAL, "techno industrial"}, {ROAR_META_GENRE_ID3_ELECTRONIC, "id3_electronic"}, {ROAR_META_GENRE_ID3_ELECTRONIC, "electronic"}, {ROAR_META_GENRE_ID3_POP_FOLK, "id3_pop_folk"}, {ROAR_META_GENRE_ID3_POP_FOLK, "pop folk"}, {ROAR_META_GENRE_ID3_EURODANCE, "id3_eurodance"}, {ROAR_META_GENRE_ID3_EURODANCE, "eurodance"}, {ROAR_META_GENRE_ID3_DREAM, "id3_dream"}, {ROAR_META_GENRE_ID3_DREAM, "dream"}, {ROAR_META_GENRE_ID3_SOUTHERN_ROCK, "id3_southern_rock"}, {ROAR_META_GENRE_ID3_SOUTHERN_ROCK, "southern rock"}, {ROAR_META_GENRE_ID3_COMEDY, "id3_comedy"}, {ROAR_META_GENRE_ID3_COMEDY, "comedy"}, {ROAR_META_GENRE_ID3_CULT, "id3_cult"}, {ROAR_META_GENRE_ID3_CULT, "cult"}, {ROAR_META_GENRE_ID3_GANGSTA, "id3_gangsta"}, {ROAR_META_GENRE_ID3_GANGSTA, "gangsta"}, {ROAR_META_GENRE_ID3_TOP_40, "id3_top_40"}, {ROAR_META_GENRE_ID3_TOP_40, "top 40"}, {ROAR_META_GENRE_ID3_CHRISTIAN_RAP, "id3_christian_rap"}, {ROAR_META_GENRE_ID3_CHRISTIAN_RAP, "christian rap"}, {ROAR_META_GENRE_ID3_POP_FUNK, "id3_pop_funk"}, {ROAR_META_GENRE_ID3_POP_FUNK, "pop funk"}, {ROAR_META_GENRE_ID3_JUNGLE, "id3_jungle"}, {ROAR_META_GENRE_ID3_JUNGLE, "jungle"}, {ROAR_META_GENRE_ID3_NATIVE_AMERICAN, "id3_native_american"}, {ROAR_META_GENRE_ID3_NATIVE_AMERICAN, "native american"}, {ROAR_META_GENRE_ID3_CABARET, "id3_cabaret"}, {ROAR_META_GENRE_ID3_CABARET, "cabaret"}, {ROAR_META_GENRE_ID3_NEW_WAVE, "id3_new_wave"}, {ROAR_META_GENRE_ID3_NEW_WAVE, "new wave"}, {ROAR_META_GENRE_ID3_PSYCHADELIC, "id3_psychadelic"}, {ROAR_META_GENRE_ID3_PSYCHADELIC, "psychadelic"}, {ROAR_META_GENRE_ID3_RAVE, "id3_rave"}, {ROAR_META_GENRE_ID3_RAVE, "rave"}, {ROAR_META_GENRE_ID3_SHOWTUNES, "id3_showtunes"}, {ROAR_META_GENRE_ID3_SHOWTUNES, "showtunes"}, {ROAR_META_GENRE_ID3_TRAILER, "id3_trailer"}, {ROAR_META_GENRE_ID3_TRAILER, "trailer"}, {ROAR_META_GENRE_ID3_LO_FI, "id3_lo_fi"}, {ROAR_META_GENRE_ID3_LO_FI, "lo fi"}, {ROAR_META_GENRE_ID3_TRIBAL, "id3_tribal"}, {ROAR_META_GENRE_ID3_TRIBAL, "tribal"}, {ROAR_META_GENRE_ID3_ACID_PUNK, "id3_acid_punk"}, {ROAR_META_GENRE_ID3_ACID_PUNK, "acid punk"}, {ROAR_META_GENRE_ID3_ACID_JAZZ, "id3_acid_jazz"}, {ROAR_META_GENRE_ID3_ACID_JAZZ, "acid jazz"}, {ROAR_META_GENRE_ID3_POLKA, "id3_polka"}, {ROAR_META_GENRE_ID3_POLKA, "polka"}, {ROAR_META_GENRE_ID3_RETRO, "id3_retro"}, {ROAR_META_GENRE_ID3_RETRO, "retro"}, {ROAR_META_GENRE_ID3_MUSICAL, "id3_musical"}, {ROAR_META_GENRE_ID3_MUSICAL, "musical"}, {ROAR_META_GENRE_ID3_ROCK_AND_ROLL, "id3_rock_and_roll"}, {ROAR_META_GENRE_ID3_ROCK_AND_ROLL, "rock and roll"}, {ROAR_META_GENRE_ID3_HARD_ROCK, "id3_hard_rock"}, {ROAR_META_GENRE_ID3_HARD_ROCK, "hard rock"}, {-1, "EOL"} }; const char * roar_meta_strtype(const int type) { int i; static char name[ROAR_META_MAX_NAMELEN]; for (i = 0; _libroar_meta_typelist[i].id != -1; i++) if ( _libroar_meta_typelist[i].id == type ) { strncpy(name, _libroar_meta_typelist[i].name, ROAR_META_MAX_NAMELEN); return name; } return NULL; } int roar_meta_inttype(const char * type) { int i; for (i = 0; _libroar_meta_typelist[i].id != -1; i++) if ( strcasecmp(_libroar_meta_typelist[i].name, type) == 0 ) { return _libroar_meta_typelist[i].id; } return -1; } int roar_stream_meta_set (struct roar_connection * con, struct roar_stream * s, int mode, struct roar_meta * meta) { struct roar_message m; int len; memset(&m, 0, sizeof(struct roar_message)); // make valgrind happy! m.cmd = ROAR_CMD_SET_META; m.stream = s->id; // m.datalen = len; if ( (mode == ROAR_META_MODE_FINALIZE || mode == ROAR_META_MODE_CLEAR) && meta->value == NULL ) meta->value = ""; if ( meta->value == NULL ) return -1; m.data[0] = 0; m.data[1] = mode; m.data[2] = meta->type; m.data[3] = strlen(meta->key); m.data[4] = len = strlen(meta->value); if ( len > 255 ) return -1; m.datalen = (int) 5 + (int) m.data[3] + len; if ( m.datalen > LIBROAR_BUFFER_MSGDATA ) return -1; strncpy(&(m.data[5]), meta->key, ROAR_META_MAX_NAMELEN); strncpy(&(m.data[5+m.data[3]]), meta->value, len); ROAR_DBG("roar_stream_meta_set(*): meta value length is %i byte", len); ROAR_DBG("roar_stream_meta_set(*): message data length is %i byte", m.datalen); if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd == ROAR_CMD_OK ) return 0; return -1; } int roar_stream_meta_get (struct roar_connection * con, struct roar_stream * s, struct roar_meta * meta) { struct roar_message m; char * c; memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_GET_META; m.stream = s->id; // m.datalen = len; m.data[0] = 0; m.data[1] = meta->type; m.datalen = 2; if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; if ( m.datalen < 2 ) return -1; if ( m.data[0] != 0 ) return -1; if ( (c = roar_mm_malloc(((unsigned) m.data[1]) + 1)) == NULL ) return -1; strncpy(c, &(m.data[2]), (unsigned) m.data[1]); c[(unsigned) m.data[1]] = 0; meta->value = c; meta->key[0] = 0; return 0; } int roar_stream_meta_list (struct roar_connection * con, struct roar_stream * s, int * types, size_t len) { size_t i; struct roar_message m; memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_LIST_META; m.stream = s->id; m.pos = 0; m.data[0] = 0; m.datalen = 1; if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; if ( m.datalen < 1 ) return -1; if ( m.data[0] != 0 ) return -1; if ( len < (m.datalen - 1 ) ) return -1; for (i = 1; i < m.datalen; i++) types[i-1] = (unsigned) m.data[i]; return m.datalen - 1; } int roar_meta_free (struct roar_meta * meta) { if ( meta->value != NULL ) roar_mm_free(meta->value); return 0; } // genere: const char * roar_meta_strgenre(const int genre) { int i; for (i = 0; _libroar_meta_genrelist[i].id != -1; i++) if ( _libroar_meta_genrelist[i].id == genre ) { return _libroar_meta_genrelist[i].name; } return NULL; } int roar_meta_intgenre(const char * genre) { int i; for (i = 0; _libroar_meta_genrelist[i].id != -1; i++) if ( strcasecmp(_libroar_meta_genrelist[i].name, genre) == 0 ) { return _libroar_meta_genrelist[i].id; } return -1; } int roar_meta_parse_audioinfo(struct roar_audio_info * info, const char * str) { char * lc; char * cur, * next; char * k, * v; if ( info == NULL || str == NULL ) return -1; memset(info, 0, sizeof(struct roar_audio_info)); info->codec = -1; if ( (lc = roar_mm_strdup(str)) == NULL ) return -1; cur = lc; while (cur != NULL) { next = strstr(cur, " "); if ( next != NULL ) { *next = 0; next++; } k = cur; v = strstr(cur, ":"); if ( v != NULL ) { *v = 0; v++; } else { v = ""; } // we test for the key, unknown keys get ignored. if ( !strcasecmp(k, "rate") ) { info->rate = roar_str2rate(v); } else if ( !strcasecmp(k, "bits") ) { info->bits = roar_str2bits(v); } else if ( !strcasecmp(k, "channels") ) { info->channels = roar_str2channels(v); } else if ( !strcasecmp(k, "codec") ) { info->codec = roar_str2codec(v); } cur = next; } roar_mm_free(lc); return 0; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/nnode.c�����������������������������������������������������������������0000644�0001750�0001750�00000021551�12264733542�015374� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//nnode.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define _CHECK(x) if ( (x) == NULL ) return -1 int roar_nnode_new (struct roar_nnode * nnode, int socktype) { _CHECK(nnode); memset(nnode, 0, sizeof(struct roar_nnode)); nnode->socktype = socktype; return 0; } int roar_nnode_new_from_af(struct roar_nnode * nnode, int af) { int socktype; _CHECK(nnode); switch (af) { #ifdef ROAR_HAVE_IPV4 case AF_INET: socktype = ROAR_SOCKET_TYPE_INET; break; #endif #ifdef ROAR_HAVE_IPV6 case AF_INET6: socktype = ROAR_SOCKET_TYPE_INET6; break; #endif #ifdef ROAR_HAVE_UNIX case AF_UNIX: socktype = ROAR_SOCKET_TYPE_UNIX; break; #endif #ifdef ROAR_HAVE_LIBDNET case AF_DECnet: socktype = ROAR_SOCKET_TYPE_DECNET; break; #endif #ifdef ROAR_HAVE_IPX case AF_IPX: socktype = ROAR_SOCKET_TYPE_IPX; break; #endif default: return -1; break; } if ( roar_nnode_new(nnode, socktype) == -1 ) return -1; return 0; } int roar_nnode_new_from_sockaddr(struct roar_nnode * nnode, struct sockaddr * addr, socklen_t len) { _CHECK(nnode); _CHECK(addr); ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = ?", nnode, addr, (unsigned long)len); if ( len < sizeof(addr->sa_family) ) return -1; ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = ?", nnode, addr, (unsigned long)len); if ( roar_nnode_new_from_af(nnode, addr->sa_family) == -1 ) return -1; ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = ?", nnode, addr, (unsigned long)len); switch (addr->sa_family) { #ifdef ROAR_HAVE_IPV4 case AF_INET: if ( len < sizeof(struct sockaddr_in) ) return -1; memcpy(nnode->addr.inet4, &(((struct sockaddr_in*)addr)->sin_addr), sizeof(nnode->addr.inet4)); break; #endif #ifdef ROAR_HAVE_IPV6 case AF_INET6: if ( len < sizeof(struct sockaddr_in6) ) return -1; memcpy(nnode->addr.inet6, ((struct sockaddr_in6*)addr)->sin6_addr.s6_addr, sizeof(nnode->addr.inet6)); break; #endif #ifdef ROAR_HAVE_UNIX case AF_UNIX: // nothing to do/save here. break; #endif #ifdef ROAR_HAVE_LIBDNET case AF_DECnet: if ( len < sizeof(struct sockaddr_dn) ) return -1; nnode->addr.decnet.node = ((struct sockaddr_dn*)addr)->sdn_add.a_addr[0]; nnode->addr.decnet.node |= (((struct sockaddr_dn*)addr)->sdn_add.a_addr[1] & 0x03) << 8; nnode->addr.decnet.area = ((struct sockaddr_dn*)addr)->sdn_add.a_addr[1] >> 2; break; #endif #ifdef ROAR_HAVE_IPX case AF_IPX: return -1; break; #endif default: return -1; break; } ROAR_DBG("roar_nnode_new_from_sockaddr(nnode=%p, addr=%p, len=%lu) = 0", nnode, addr, (unsigned long)len); return 0; } int roar_nnode_new_from_fh(struct roar_nnode * nnode, int fh, int remote) { // TODO: fix this in a nice way #ifndef ROAR_TARGET_MICROCONTROLLER struct sockaddr_storage sa; socklen_t len = sizeof(sa); int ret; _CHECK(nnode); if ( fh == -1 ) return -1; if ( remote ) { ret = getpeername(fh, (struct sockaddr*)&sa, &len); } else { ret = getsockname(fh, (struct sockaddr*)&sa, &len); } if ( ret == -1 ) return -1; return roar_nnode_new_from_sockaddr(nnode, (struct sockaddr*)&sa, len); #else return -1; #endif } int roar_nnode_free (struct roar_nnode * nnode) { _CHECK(nnode); return 0; } int roar_nnode_get_socktype (struct roar_nnode * nnode) { _CHECK(nnode); return nnode->socktype; } int roar_nnode_to_str (struct roar_nnode * nnode, char * str, size_t len) { // Format: PROTO: nodename[nodeaddr] char proto[7] = "???"; char nodename[4] = ""; char nodeaddr[48 /* IPv6 */] = "???"; _CHECK(nnode); if ( len == 0 ) return 0; _CHECK(str); if ( len == 1 ) { *str = 0; return 0; } switch (nnode->socktype) { case ROAR_SOCKET_TYPE_UNIX: roar_mm_strscpy(proto, "UNIX"); roar_mm_strscpy(nodeaddr, "LOCAL"); break; case ROAR_SOCKET_TYPE_INET: roar_mm_strscpy(proto, "IPv4"); snprintf(nodeaddr, sizeof(nodeaddr), "%i.%i.%i.%i", nnode->addr.inet4[0], nnode->addr.inet4[1], nnode->addr.inet4[2], nnode->addr.inet4[3] ); break; case ROAR_SOCKET_TYPE_DECNET: roar_mm_strscpy(proto, "DECnet"); snprintf(nodeaddr, sizeof(nodeaddr), "%i.%i", nnode->addr.decnet.area, nnode->addr.decnet.node); break; case ROAR_SOCKET_TYPE_INET6: roar_mm_strscpy(proto, "IPv6"); break; case ROAR_SOCKET_TYPE_IPX: roar_mm_strscpy(proto, "IPX"); break; default: snprintf(proto, sizeof(proto), "P#%i", nnode->socktype); break; } if ( *nodename ) { snprintf(str, len, "%s: %s[%s]", proto, nodename, nodeaddr); } else { snprintf(str, len, "%s: %s", proto, nodeaddr); } str[len-1] = 0; return 0; } int roar_nnode_from_blob (struct roar_nnode * nnode, void * blob, size_t * len) { uint16_t socktype; _CHECK(nnode); _CHECK(blob); _CHECK(len); if ( *len < 2 ) return -1; memcpy(&socktype, blob, 2); socktype = ROAR_NET2HOST16(socktype); if ( roar_nnode_new(nnode, socktype) == -1 ) return -1; switch (socktype) { case ROAR_SOCKET_TYPE_UNIX: *len = 2; break; case ROAR_SOCKET_TYPE_INET: if ( *len < 6 ) return -1; memcpy(nnode->addr.inet4, blob+2, 4); *len = 6; break; case ROAR_SOCKET_TYPE_DECNET: if ( *len < 4 ) return -1; nnode->addr.decnet.node = ((unsigned char*)blob)[2]; nnode->addr.decnet.node = (((unsigned char*)blob)[3] & 0x03) << 8; nnode->addr.decnet.area = ((unsigned char*)blob)[3] >> 2; *len = 4; break; case ROAR_SOCKET_TYPE_INET6: if ( *len < 18 ) return -1; memcpy(nnode->addr.inet4, blob+2, 16); *len = 18; break; case ROAR_SOCKET_TYPE_IPX: default: return -1; break; } return 0; } int roar_nnode_to_blob (struct roar_nnode * nnode, void * blob, size_t * len) { uint16_t socktype_net; _CHECK(nnode); _CHECK(blob); _CHECK(len); if ( *len < 2 ) return -1; socktype_net = ROAR_HOST2NET16(nnode->socktype); memcpy(blob, &socktype_net, 2); switch (nnode->socktype) { case ROAR_SOCKET_TYPE_UNIX: // all UNIX sockets allways match. *len = 2; break; case ROAR_SOCKET_TYPE_INET: if ( *len < 6 ) return -1; memcpy(blob+2, nnode->addr.inet4, 4); *len = 6; break; case ROAR_SOCKET_TYPE_DECNET: if ( *len < 4 ) return -1; ((unsigned char*)blob)[2] = nnode->addr.decnet.node & 0x00FF; ((unsigned char*)blob)[3] = ((nnode->addr.decnet.node & 0x0300) >> 8) | (nnode->addr.decnet.area << 2); *len = 4; return -1; break; case ROAR_SOCKET_TYPE_INET6: if ( *len < 18 ) return -1; memcpy(blob+2, nnode->addr.inet4, 16); *len = 18; break; case ROAR_SOCKET_TYPE_IPX: default: return -1; break; } return 0; } int roar_nnode_cmp (struct roar_nnode * n0, struct roar_nnode * n1) { _CHECK(n0); _CHECK(n1); if ( n0->socktype != n1->socktype ) return 1; switch (n0->socktype) { case ROAR_SOCKET_TYPE_UNIX: // all UNIX sockets allways match. break; case ROAR_SOCKET_TYPE_INET: if ( memcmp(n0->addr.inet4, n1->addr.inet4, sizeof(n0->addr.inet4)) != 0 ) return 1; break; case ROAR_SOCKET_TYPE_DECNET: if ( n0->addr.decnet.area != n1->addr.decnet.area || n0->addr.decnet.node != n1->addr.decnet.node ) return 1; break; case ROAR_SOCKET_TYPE_INET6: if ( memcmp(n0->addr.inet6, n1->addr.inet6, sizeof(n0->addr.inet6)) != 0 ) return 1; break; case ROAR_SOCKET_TYPE_IPX: default: return -1; break; } return 0; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/notify.c����������������������������������������������������������������0000644�0001750�0001750�00000032434�12264733542�015603� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//notify.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" struct roar_subscriber { uint32_t flags; uint32_t event; int emitter; int target; int target_type; void (*cb)(struct roar_notify_core * core, struct roar_event * event, void * userdata); void * userdata; size_t refc; unsigned int hash; // struct roar_subscriber * prev; struct roar_subscriber * next; }; struct roar_notify_core { size_t refc; size_t listc; struct roar_subscriber ** lists; void (*proxy)(struct roar_notify_core * core, struct roar_event * event, void * userdata); void * proxy_userdata; }; static struct roar_notify_core * _libroar_notify_core = NULL; #define _CKRCORE(ret) if ( core == NULL ) { if ( _libroar_notify_core == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return (ret); } else { core = _libroar_notify_core; } } #define _CKICORE() _CKRCORE(-1) static unsigned int _hash_event (struct roar_notify_core * core, struct roar_event * event) { unsigned int hash = 0; unsigned int mask = core->listc - 1; hash ^= event->event >> 0; hash ^= event->event >> 8; hash ^= event->event >> 16; hash ^= event->event >> 24; return hash & mask; } struct roar_notify_core * roar_notify_core_new(ssize_t lists) { struct roar_notify_core * core = NULL; switch (lists) { case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128: case 256: case 512: case 1024: // they all are ok. break; case -1: // handle defult: lists = 16; break; default: roar_err_set(ROAR_ERROR_INVAL); return NULL; break; } if ( (core = roar_mm_malloc(sizeof(struct roar_notify_core))) == NULL ) { return NULL; } memset(core, 0, sizeof(struct roar_notify_core)); core->refc = 1; core->listc = lists; core->lists = roar_mm_malloc(lists*sizeof(struct roar_subscriber *)); core->proxy = NULL; core->proxy_userdata = NULL; if ( core->lists == NULL ) { roar_mm_free(core); return NULL; } memset(core->lists, 0, lists*sizeof(struct roar_subscriber *)); return core; } int roar_notify_core_ref(struct roar_notify_core * core) { _CKICORE(); core->refc++; return 0; } int roar_notify_core_unref(struct roar_notify_core * core) { struct roar_subscriber * cur, * next; size_t i; _CKICORE(); if ( core->refc == 0 ) { ROAR_ERR("roar_notify_core_unref(core=%p): refc is zero, must be greater zero. resolving by setting to one.", core); core->refc = 1; roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); } core->refc--; if ( core->refc > 0 ) { return 0; } // if we work on the global core, reset it to NULL if we free it. if ( core == _libroar_notify_core ) { _libroar_notify_core = NULL; } for (i = 0; i < core->listc; i++) { cur = core->lists[i]; while (cur != NULL) { next = cur->next; roar_mm_free(cur); cur = next; } } roar_mm_free(core->lists); roar_mm_free(core); return 0; } int roar_notify_core_new_global(ssize_t lists) { if ( _libroar_notify_core != NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( (_libroar_notify_core = roar_notify_core_new(lists)) == NULL ) return -1; return 0; } struct roar_notify_core * roar_notify_core_swap_global(struct roar_notify_core * core) { struct roar_notify_core * ret = _libroar_notify_core; if ( core != NULL ) if ( roar_notify_core_ref(core) == -1 ) return NULL; _libroar_notify_core = core; return ret; } int roar_notify_core_register_proxy(struct roar_notify_core * core, void (*cb)(struct roar_notify_core * core, struct roar_event * event, void * userdata), void * userdata) { _CKICORE(); core->proxy = cb; core->proxy_userdata = userdata; return 0; } struct roar_subscriber * roar_notify_core_subscribe(struct roar_notify_core * core, struct roar_event * event, void (*cb)(struct roar_notify_core * core, struct roar_event * event, void * userdata), void * userdata) { struct roar_subscriber * subs = NULL; struct roar_subscriber * cur, * old; ROAR_DBG("roar_notify_core_subscribe(core=%p, event=%p, cb=%p, userdata=%p) = ?", core, event, cb, userdata); _CKRCORE(NULL); if ( event == NULL || cb == NULL ) { ROAR_DBG("roar_notify_core_subscribe(core=%p, event=%p, cb=%p, userdata=%p) = NULL // errno = EINVAL", core, event, cb, userdata); roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( (subs = roar_mm_malloc(sizeof(struct roar_subscriber))) == NULL ) { ROAR_DBG("roar_notify_core_subscribe(core=%p, event=%p, cb=%p, userdata=%p) = NULL // errno = ENOMEM?", core, event, cb, userdata); return NULL; } memset(subs, 0, sizeof(struct roar_subscriber)); subs->flags = 0; subs->event = event->event; subs->emitter = event->emitter; subs->target = event->target; subs->target_type = event->target_type; subs->cb = cb; subs->userdata = userdata; subs->refc = 1; subs->hash = _hash_event(core, event); subs->next = NULL; if ( (cur = core->lists[subs->hash]) == NULL ) { core->lists[subs->hash] = subs; } else { old = cur; while (cur != NULL) { old = cur; cur = cur->next; } old->next = subs; } ROAR_DBG("roar_notify_core_subscribe(core=%p, event=%p, cb=%p, userdata=%p) = %p", core, event, cb, userdata, subs); return subs; } int roar_notify_core_unsubscribe(struct roar_notify_core * core, struct roar_subscriber * subscriber) { struct roar_subscriber * cur, * old; _CKICORE(); if ( subscriber == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( (cur = core->lists[subscriber->hash]) == subscriber ) { core->lists[subscriber->hash] = core->lists[subscriber->hash]->next; } else { old = NULL; while (cur != NULL && cur != subscriber ) { old = cur; cur = cur->next; } if ( cur != subscriber ) return -1; old->next = cur->next; roar_mm_free(cur); } return 0; } int roar_notify_core_emit(struct roar_notify_core * core, struct roar_event * event) { struct roar_subscriber * cur; struct roar_error_state errstate; _CKICORE(); if ( event == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( core->proxy != NULL && !(event->flags & ROAR_EVENT_FLAG_PROXYEVENT) ) { core->proxy(core, event, core->proxy_userdata); } cur = core->lists[_hash_event(core, event)]; ROAR_DBG("roar_notify_core_emit(core=%p, event=%p): cur=%p", core, event, cur); while (cur != NULL) { ROAR_DBG("roar_notify_core_emit(core=%p, event=%p): cur=%p", core, event, cur); // test if we can skip this one: if ( !( (cur->event == ROAR_NOTIFY_SPECIAL || cur->event == event->event) && (cur->emitter == -1 || cur->emitter == event->emitter) && (cur->target == -1 || cur->target == event->target) && (cur->target_type == -1 || cur->target_type == event->target_type) ) ) { cur = cur->next; continue; } if ( cur->cb == NULL ) { ROAR_ERR("roar_notify_core_emit(core=%p, event=%p): cur=%p, cb is set NULL, bad.", core, event, cur); } else { // The callback is started in an clear error context which is destroyed after it finished so it // does not alter our caller's context. roar_err_store(&errstate); roar_err_clear_all(); cur->cb(core, event, cur->userdata); roar_err_restore(&errstate); } cur = cur->next; } return 0; } int roar_notify_core_emit_simple(uint32_t event, int emitter, int target, int target_type, int arg0, int arg1, void * arg2, ssize_t arg2_len) { struct roar_event locevent; memset(&locevent, 0, sizeof(locevent)); locevent.event = event; locevent.emitter = emitter; locevent.target = target; locevent.target_type = target_type; locevent.arg0 = arg0; locevent.arg1 = arg1; locevent.arg2 = arg2; locevent.arg2_len = arg2_len; if ( arg2 == NULL && (arg2_len == 0 || arg2_len == -1) ) { locevent.flags |= ROAR_EVENT_FLAG_NETTRANS; // we guess packages with only int args are network transparent. } return roar_notify_core_emit(NULL, &locevent); } int roar_event_to_blob(struct roar_event * event, void * blob, size_t * len) { size_t needed_len = (2 * 4) + (4 * 2); uint32_t * u32 = blob; uint16_t * u16 = blob; size_t data_offset_neg = 0; u16 += 4; // error checking: if ( event == NULL || blob == NULL || len == NULL ) return -1; if ( *len == 0 ) return -1; // calc and check length: if ( event->flags & ROAR_EVENT_FLAG_PROXYEVENT ) needed_len += 4; if ( event->flags & ROAR_EVENT_FLAG_NETTRANS ) { // this is not a real maximum but a value good to detect all kinds of errors. // a notify event should not be longer anyway. if ( event->arg2_len > 32767 ) return -1; needed_len += 4; if ( event->arg2_len > 0 ) { needed_len += event->arg2_len; data_offset_neg = event->arg2_len; } } if ( *len < needed_len ) return -1; *len = 0; // fill in the data... memset(blob, 0, needed_len); u32[1] = ROAR_HOST2NET32(0); if ( event->flags & ROAR_EVENT_FLAG_PROXYEVENT ) { u32[0] |= ROAR_HOST2NET32(ROAR_EVENT_NETFLAG_PROXYEVENT); u16 += 2; } if ( event->flags & ROAR_EVENT_FLAG_NETTRANS ) { u32[0] |= ROAR_HOST2NET32(ROAR_EVENT_NETFLAG_DATA); } u32[1] = ROAR_HOST2NET32(event->event); if ( event->flags & ROAR_EVENT_FLAG_PROXYEVENT ) u32[2] = ROAR_HOST2NET32(event->event_proxy); u16[0] = ROAR_HOST2NET16(event->emitter); u16[1] = ROAR_HOST2NET16(event->target); u16[2] = ROAR_HOST2NET16(event->target_type); if ( event->flags & ROAR_EVENT_FLAG_NETTRANS ) { u16[3] = ROAR_HOST2NET16(event->arg2_len); u16[4] = ROAR_HOST2NET16(event->arg0); u16[5] = ROAR_HOST2NET16(event->arg1); } else { u16[3] = ROAR_HOST2NET16(0); } memcpy(blob + needed_len - data_offset_neg, event->arg2, event->arg2_len); *len = needed_len; return 0; } int roar_event_from_blob(struct roar_event * event, void * blob, size_t * len) { size_t needed_len = (2 * 4) + (4 * 2); uint32_t * u32 = blob; uint16_t * u16 = blob; uint32_t flags; u16 += 4; // error checking: if ( event == NULL || blob == NULL || len == NULL ) return -1; // check for minimum length. if ( *len < needed_len ) return -1; flags = ROAR_NET2HOST32(u32[0]); #if 0 if ( event->flags & ROAR_EVENT_FLAG_PROXYEVENT ) { u32[0] |= ROAR_HOST2NET32(ROAR_EVENT_NETFLAG_PROXYEVENT); u16 += 2; } if ( event->flags & ROAR_EVENT_FLAG_NETTRANS ) { u32[0] |= ROAR_HOST2NET32(ROAR_EVENT_NETFLAG_DATA); } #endif if ( flags & ROAR_EVENT_NETFLAG_PROXYEVENT ) { needed_len += 4; u16 += 2; } if ( flags & ROAR_EVENT_NETFLAG_DATA ) { needed_len += 4; } // do we have a full header? if ( *len < needed_len ) return -1; needed_len += ROAR_NET2HOST16(u16[3]); // is all of the event complet? if ( *len < needed_len ) return -1; // now we know everything is complet we can start to extract data... *len = 0; memset(event, 0, sizeof(struct roar_event)); if ( flags & ROAR_EVENT_NETFLAG_PROXYEVENT ) { flags -= ROAR_EVENT_NETFLAG_PROXYEVENT; event->flags |= ROAR_EVENT_FLAG_PROXYEVENT; } if ( flags & ROAR_EVENT_NETFLAG_DATA ) { flags -= ROAR_EVENT_NETFLAG_DATA; event->flags |= ROAR_EVENT_FLAG_NETTRANS; } // test if there are flags left we do not understand: if ( flags ) { return -1; } event->event = ROAR_NET2HOST32(u32[1]); if ( event->flags & ROAR_EVENT_FLAG_PROXYEVENT ) event->event_proxy = ROAR_NET2HOST32(u32[2]); event->emitter = ROAR_NET2HOST16(u16[0]); event->target = ROAR_NET2HOST16(u16[1]); event->target_type = ROAR_NET2HOST16(u16[2]); event->arg2_len = ROAR_NET2HOST16(u16[3]); if ( event->emitter == (uint16_t)-1) event->emitter = -1; if ( event->target == (uint16_t)-1) event->target = -1; if ( event->target_type == (uint16_t)-1) event->target_type = -1; if ( event->flags & ROAR_EVENT_FLAG_NETTRANS ) { event->arg0 = ROAR_NET2HOST16(u16[4]); event->arg1 = ROAR_NET2HOST16(u16[5]); if ( event->arg0 == (uint16_t)-1) event->arg0 = -1; if ( event->arg1 == (uint16_t)-1) event->arg1 = -1; event->arg2 = blob + needed_len - event->arg2_len; } else { event->arg0 = -1; event->arg1 = -1; event->arg2 = NULL; } *len = needed_len; return 0; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/notify_proxy.c����������������������������������������������������������0000644�0001750�0001750�00000006326�12264733542�017045� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//notify_proxy.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define MAX_EVENTS_PER_GROUP 4 #define EOL ROAR_NOTIFY_SPECIAL // TODO: FIXME: ROAR_NOTIFY_EGRP2EVENT() on _OE_ events? // TODO: refthink design of this proxy. void roar_notify_proxy_std(struct roar_notify_core * core, struct roar_event * event, void * userdata) { struct { uint32_t event_min, event_max; uint32_t events[MAX_EVENTS_PER_GROUP]; } * ptr, list[] = { {.event_min = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_CLIENTS), .event_max = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_CLIENTS + 0xff), .events = { ROAR_EGRP_ANY_CLIENT_EVENT, EOL } }, {.event_min = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS), .event_max = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_STREAMS + 0xff), .events = { ROAR_EGRP_ANY_STREAM_EVENT, EOL } }, {.event_min = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_SOURCES), .event_max = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_SOURCES + 0xff), .events = { ROAR_EGRP_ANY_SOURCE_EVENT, EOL } }, {.event_min = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_SAMPLES), .event_max = ROAR_NOTIFY_OE2EVENT(ROAR_NOTIFY_OE_GROUP_SAMPLES + 0xff), .events = { ROAR_EGRP_ANY_SAMPLE_EVENT, EOL } } }; struct roar_event locevent; size_t i, e; register uint32_t oe = event->event; (void)userdata; memcpy(&locevent, event, sizeof(locevent)); locevent.event_proxy = locevent.event; locevent.flags |= ROAR_EVENT_FLAG_PROXYEVENT; locevent.event = ROAR_EGRP_ANY_EVENT; roar_notify_core_emit(core, &locevent); for (i = 0; i < sizeof(list)/sizeof(*list); i++) { ptr = &(list[i]); if ( ptr->event_min <= oe && ptr->event_max >= oe ) { for (e = 0; ptr->events[e] != EOL; e++) { locevent.event = ptr->events[e]; roar_notify_core_emit(core, &locevent); } } } } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/passwordapi.c�����������������������������������������������������������0000644�0001750�0001750�00000004404�12264733543�016624� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//passwordapi.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" ssize_t roar_passwd_simple_ask_pw (char ** pw, char * prompt, const char * cachetoken) { #ifdef ROAR_SUPPORT_PASSWORD_API struct roar_pinentry pe; if ( pw == NULL ) return -1; if ( prompt == NULL ) { ROAR_WARN("roar_passwd_simple_ask_pw(pw=%p, prompt=NULL, cachetoken='%s'): No prompt given. This may be a bug in application.", pw, cachetoken); prompt = "Please enter Password"; } *pw = NULL; // TODO: test for cache here. if ( *pw == NULL ) { if ( roar_pinentry_simple_open(&pe) != -1 ) { if ( roar_pinentry_getpin(&pe, pw, NULL, prompt) == -1 ) { *pw = NULL; } roar_pinentry_close(&pe); } } if ( *pw == NULL ) { if ( roar_sshaskpass_getpass(pw, prompt) == -1 ) { *pw = NULL; } } if ( *pw == NULL ) return -1; // TODO: save to cache here. return strlen(*pw); #else return -1; #endif } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/pinentry.c��������������������������������������������������������������0000644�0001750�0001750�00000017032�12264733543�016141� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//pinentry.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" // TODO: need to check: && defined(ROAR_HAVE_TTYNAME) #if defined(ROAR_HAVE_FORK) && defined(ROAR_HAVE_PIPE) && defined(ROAR_HAVE_FDOPEN) #define _CAN_POSIX #endif #if defined(ROAR_HAVE_BIN_PINENTRY) && defined(ROAR_SUPPORT_PASSWORD_API) && defined(_CAN_POSIX) #define _CAN_OPERATE #endif int roar_pinentry_open (struct roar_pinentry * pe, int flags, const char * display, const char * tty, const char * term) { #ifdef _CAN_OPERATE int in[2], out[2]; char * bin_pinentry; if ( pe == NULL ) return -1; memset(pe, 0, sizeof(struct roar_pinentry)); pe->in = -1; pe->out = -1; if ( display == NULL ) display = roar_env_get("DISPLAY"); if ( display == NULL ) display = "(NONE)"; if ( tty == NULL ) tty = ttyname(ROAR_STDIN); if ( tty == NULL ) #ifdef ROAR_DEFAULT_TTY tty = ROAR_DEFAULT_TTY; #else return -1; #endif if ( term == NULL ) term = roar_env_get("TERM"); if ( term == NULL ) term = "dumb"; // open some pipes... if ( pipe(in) != 0 ) return -1; if ( pipe(out) != 0 ) { close(in[0]); close(in[1]); return -1; } pe->pid = roar_fork(NULL); switch (pe->pid) { case -1: close(in[0]); close(in[1]); close(out[0]); close(out[1]); return -1; break; case 0: roar_watchdog_stop(); close(in[0]); close(out[1]); close(ROAR_STDIN); close(ROAR_STDOUT); if ( dup2(out[0], ROAR_STDIN) == -1 ) ROAR_U_EXIT(1); if ( dup2(in[1], ROAR_STDOUT) == -1 ) ROAR_U_EXIT(1); bin_pinentry = roar_libroar_get_path("bin-pinentry", 0, NULL, NULL); if ( bin_pinentry == NULL ) ROAR_U_EXIT(1); execlp(bin_pinentry, "RoarAudio", "--display", display, "--ttytype", term, "--ttyname", tty, NULL); roar_mm_free(bin_pinentry); ROAR_U_EXIT(1); break; } close(in[1]); close(out[0]); pe->in = in[0]; pe->out = out[1]; pe->fin = fdopen(in[0], "r"); roar_pinentry_recv(pe, NULL, NULL); return 0; #else return -1; #endif } int roar_pinentry_simple_open(struct roar_pinentry * pe) { return roar_pinentry_open(pe, 0, NULL, NULL, NULL); } int roar_pinentry_close(struct roar_pinentry * pe) { #ifdef _CAN_OPERATE int status; if ( pe == NULL ) return -1; if ( pe->opened == 0 ) return 0; if ( pe->out != -1 ) close(pe->out); if ( pe->fin != NULL ) fclose(pe->fin); if ( pe->in != -1 ) close(pe->in); waitpid(pe->pid, &status, 0); memset(pe, 0, sizeof(struct roar_pinentry)); return 0; #else return -1; #endif } int roar_pinentry_send (struct roar_pinentry * pe, char * cmd, char * args) { #ifdef _CAN_OPERATE size_t len; if ( pe == NULL ) return -1; if ( cmd == NULL ) return -1; len = strlen(cmd); if ( write(pe->out, cmd, len) != (ssize_t)len ) return -1; if ( args != NULL ) { if ( write(pe->out, " ", 1) != 1 ) return -1; len = strlen(args); if ( write(pe->out, args, len) != (ssize_t)len ) return -1; } if ( write(pe->out, "\n", 1) != 1 ) return -1; return 0; #else return -1; #endif } #define MAX_LINE_SIZE 2048 int roar_pinentry_recv (struct roar_pinentry * pe, char ** line, char ** opts) { #ifdef _CAN_OPERATE char realbuf[MAX_LINE_SIZE]; char * tp; if ( pe == NULL ) return -1; if ( pe->fin == NULL ) return -1; if ( fgets(realbuf, MAX_LINE_SIZE, pe->fin) == NULL ) return -1; tp = realbuf + strlen(realbuf) - 1; for (; *tp == '\r' || *tp == '\n'; tp--) *tp = 0; if ( (tp = strstr(realbuf, " ")) == NULL ) { if ( line != NULL ) *line = roar_mm_strdup(realbuf); if ( opts != NULL ) *opts = NULL; if ( !strcmp(realbuf, "OK") ) { return 0; } else if ( !strcmp(realbuf, "ERR") ) { return 1; } else { return -1; } } else { *tp = 0; if ( !strcmp(realbuf, "D") ) { if ( opts != NULL ) *opts = roar_mm_strdup(tp+1); return roar_pinentry_recv(pe, line, NULL); } if ( line != NULL ) *line = roar_mm_strdup(realbuf); if ( opts != NULL ) *opts = NULL; if ( !strcmp(realbuf, "OK") ) { return 0; } else if ( !strcmp(realbuf, "ERR") ) { return 1; } else { return -1; } } return -1; #else return -1; #endif } int roar_pinentry_req (struct roar_pinentry * pe, char * cmd, char * args, char ** line, char ** opts) { #ifdef ROAR_SUPPORT_PASSWORD_API if ( pe == NULL ) return -1; if ( roar_pinentry_send(pe, cmd, args) != 0 ) return -1; return roar_pinentry_recv(pe, line, opts); #else return -1; #endif } int roar_pinentry_set_desc (struct roar_pinentry * pe, char * desc) { return roar_pinentry_set(pe, "DESC", desc); } int roar_pinentry_set_prompt(struct roar_pinentry * pe, char * prompt) { return roar_pinentry_set(pe, "PROMPT", prompt); } int roar_pinentry_set_yes (struct roar_pinentry * pe, char * yes) { return roar_pinentry_set(pe, "OK", yes); } int roar_pinentry_set_no (struct roar_pinentry * pe, char * no) { return roar_pinentry_set(pe, "CANCEL", no); } int roar_pinentry_set (struct roar_pinentry * pe, char * obj, char * text) { #ifdef ROAR_SUPPORT_PASSWORD_API char req[80] = "SET"; if ( pe == NULL ) return -1; if ( obj == NULL ) return -1; if ( strlen(obj) > (80-(1 /* \0 */ + 3 /* "SET" */)) ) return -1; strncat(req, obj, 80-4); return roar_pinentry_req(pe, req, text, NULL, NULL); #else return -1; #endif } int roar_pinentry_getpin (struct roar_pinentry * pe, char ** pw, char * desc, char * prompt) { #ifdef ROAR_SUPPORT_PASSWORD_API if ( pe == NULL ) return -1; if ( pw == NULL ) return -1; if ( desc != NULL ) if ( roar_pinentry_set_desc(pe, desc) != 0 ) return -1; if ( prompt != NULL ) if ( roar_pinentry_set_prompt(pe, prompt) != 0 ) return -1; if ( roar_pinentry_req(pe, "GETPIN", NULL, NULL, pw) == -1 ) return -1; return 0; #else return -1; #endif } int roar_pinentry_confirm (struct roar_pinentry * pe, char * desc, char * yes, char * no) { #ifdef ROAR_SUPPORT_PASSWORD_API if ( pe == NULL ) return -1; if ( desc != NULL ) if ( roar_pinentry_set_desc(pe, desc) != 0 ) return -1; if ( yes != NULL ) if ( roar_pinentry_set_yes(pe, yes) != 0 ) return -1; if ( no != NULL ) if ( roar_pinentry_set_no(pe, no) != 0 ) return -1; return roar_pinentry_req(pe, "CONFIRM", NULL, NULL, NULL); #else return -1; #endif } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/plugincontainer.c�������������������������������������������������������0000644�0001750�0001750�00000033630�12264733543�017474� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//plugincontainer.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define MAX_PLUGINS 64 #define OPT_AUTOAPPSCHED 0x0001 struct roar_plugincontainer { size_t refc; const struct roar_plugincontainer_callbacks * callbacks; void * userdata; unsigned int options; struct roar_dl_librarypara * default_para; struct roar_dl_lhandle * handle[MAX_PLUGINS]; size_t deprefc[MAX_PLUGINS]; void * context[MAX_PLUGINS]; size_t numhandles; }; static inline void _unload(struct roar_plugincontainer * cont, size_t index) { int err = roar_error; if ( cont->options & OPT_AUTOAPPSCHED ) roar_dl_appsched_trigger(cont->handle[index], ROAR_DL_APPSCHED_FREE); if ( cont->callbacks != NULL && cont->callbacks->preunload != NULL ) cont->callbacks->preunload(cont, &(cont->context[index]), cont->handle[index]); roar_err_set(err); roar_dl_unref(cont->handle[index]); err = roar_error; cont->handle[index] = NULL; cont->numhandles--; if ( cont->callbacks != NULL && cont->callbacks->postunload != NULL ) cont->callbacks->postunload(cont, &(cont->context[index])); if ( cont->context[index] != NULL ) if ( cont->callbacks != NULL && cont->callbacks->freecontext != NULL ) cont->callbacks->freecontext(cont, &(cont->context[index])); if ( cont->context[index] != NULL ) { roar_mm_free(cont->context[index]); cont->context[index] = NULL; } roar_err_set(err); } static int _loader(struct roar_dl_librarypara * lhandle, void * loader_userdata, enum roar_dl_loadercmd cmd, void * argp) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } static struct roar_dl_librarypara * _copy_para(struct roar_dl_librarypara * para, struct roar_plugincontainer * cont) { struct roar_dl_librarypara * ret = NULL; int err; if ( para == NULL || cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } ret = roar_dl_para_new(NULL, para->binargv, para->appname, para->abiversion); if ( para->argc && para->argv != NULL ) { ret->argc = para->argc; ret->args_store = roar_keyval_copy(&(ret->argv), para->argv, para->argc); if ( ret->args_store == NULL ) { err = roar_error; roar_dl_para_unref(ret); roar_error = err; return NULL; } } ret->notifycore = para->notifycore; ret->container = cont; ret->loader = _loader; ret->loader_userdata = NULL; return ret; } static struct roar_plugincontainer * _new_init(void) { struct roar_plugincontainer * ret = roar_mm_malloc(sizeof(struct roar_plugincontainer)); if ( ret == NULL ) return NULL; memset(ret, 0, sizeof(struct roar_plugincontainer)); ret->refc = 1; return ret; } struct roar_plugincontainer * roar_plugincontainer_new(struct roar_dl_librarypara * default_para) { struct roar_plugincontainer * ret = _new_init(); int err; if ( ret == NULL ) return NULL; if ( default_para != NULL ) { ret->default_para = _copy_para(default_para, ret); if ( ret->default_para == NULL ) { err = roar_error; roar_plugincontainer_unref(ret); roar_err_set(err); return NULL; } } return ret; } struct roar_plugincontainer * roar_plugincontainer_new_simple(const char * appname, const char * abiversion) { struct roar_plugincontainer * ret; struct roar_dl_librarypara * para = roar_dl_para_new(NULL, NULL, appname, abiversion); int err; ret = roar_plugincontainer_new(para); err = roar_error; roar_dl_para_unref(para); roar_err_set(err); return ret; } int roar_plugincontainer_ref(struct roar_plugincontainer * cont) { if ( cont == NULL ) { ROAR_DBG("roar_plugincontainer_ref(cont=%p) = -1 // error=FAULT", cont); roar_err_set(ROAR_ERROR_FAULT); return -1; } cont->refc++; ROAR_DBG("roar_plugincontainer_ref(cont=%p) = 0", cont); return 0; } int roar_plugincontainer_unref(struct roar_plugincontainer * cont) { size_t i; if ( cont == NULL ) { ROAR_DBG("roar_plugincontainer_unref(cont=%p) = -1 // error=FAULT", cont); roar_err_set(ROAR_ERROR_FAULT); return -1; } cont->refc--; if ( cont->refc ) { ROAR_DBG("roar_plugincontainer_unref(cont=%p) = 0", cont); return 0; } if ( cont->callbacks != NULL && cont->callbacks->prefree != NULL ) cont->callbacks->prefree(cont, &(cont->userdata)); while (cont->numhandles) { for (i = 0; i < MAX_PLUGINS; i++) { if ( cont->handle[i] == NULL ) continue; // skip plugins in use by others. We will unload them in a later loop. if ( cont->deprefc[i] ) continue; _unload(cont, i); } } // try to free user data... if ( cont->userdata != NULL ) { if ( cont->callbacks != NULL && cont->callbacks->freeuserdata != NULL ) { cont->callbacks->freeuserdata(cont, &(cont->userdata)); } } // if still not freed by caller, free it using memmgr. if ( cont->userdata != NULL ) roar_mm_free(cont->userdata); if ( cont->default_para != NULL ) roar_dl_para_unref(cont->default_para); roar_mm_free(cont); ROAR_DBG("roar_plugincontainer_unref(cont=%p) = 0", cont); return 0; } int roar_plugincontainer_set_autoappsched(struct roar_plugincontainer * cont, int val) { if ( cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( val ) { cont->options |= OPT_AUTOAPPSCHED; return 0; } else { if ( cont->options & OPT_AUTOAPPSCHED ) { roar_err_set(ROAR_ERROR_BUSY); return -1; } else { return 0; } } } int roar_plugincontainer_set_callbacks(struct roar_plugincontainer * cont, const struct roar_plugincontainer_callbacks * callbacks) { if ( cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } cont->callbacks = callbacks; return 0; } int roar_plugincontainer_set_userdata(struct roar_plugincontainer * cont, void * userdata) { if ( cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } cont->userdata = userdata; return 0; } void * roar_plugincontainer_get_userdata(struct roar_plugincontainer * cont) { if ( cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( cont->userdata == NULL ) { roar_err_set(ROAR_ERROR_NOENT); return NULL; } return cont->userdata; } struct roar_plugincontainer_plugininfo roar_plugincontainer_get_info_by_name (struct roar_plugincontainer * cont, const char * name) { struct roar_plugincontainer_plugininfo ret; const struct roar_dl_libraryname * libname; size_t i; memset(&ret, 0, sizeof(ret)); if ( cont == NULL || name == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return ret; } for (i = 0; i < MAX_PLUGINS; i++) { if ( cont->handle[i] == NULL ) continue; libname = roar_dl_getlibname(cont->handle[i]); if ( libname == NULL ) continue; if ( !strcmp(libname->name, name) ) { if ( roar_dl_ref(cont->handle[i]) == -1 ) return ret; ret.libname = libname->name; ret.handle = cont->handle[i]; ret.rdepends = cont->deprefc[i]; ret.context = &(cont->context[i]); return ret; } } roar_err_set(ROAR_ERROR_NOENT); return ret; } struct roar_dl_lhandle * roar_plugincontainer_get_lhandle_by_name (struct roar_plugincontainer * cont, const char * name) { struct roar_plugincontainer_plugininfo info = roar_plugincontainer_get_info_by_name(cont, name); if ( info.libname == NULL ) return NULL; return info.handle; } // plugin loading and unloading: int roar_plugincontainer_load(struct roar_plugincontainer * cont, const char * name, struct roar_dl_librarypara * para) { struct roar_dl_lhandle * ret = roar_plugincontainer_load_lhandle(cont, name, ROAR_DL_FLAG_PLUGIN, 1, para); if ( ret == NULL ) return -1; roar_dl_unref(ret); return 0; } struct roar_dl_lhandle * roar_plugincontainer_load_lhandle (struct roar_plugincontainer * cont, const char * name, int flags, int ra_init, struct roar_dl_librarypara * para) { ssize_t idx = -1; size_t i; int err; if ( cont == NULL || name == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( para == NULL ) { para = cont->default_para; roar_dl_para_ref(para); } else { para = _copy_para(para, cont); } // search for a free index. if ( cont->numhandles == MAX_PLUGINS ) { // return early if we are full. roar_dl_para_unref(para); roar_err_set(ROAR_ERROR_NOSPC); return NULL; } for (i = 0; i < MAX_PLUGINS; i++) { if ( cont->handle[i] == NULL ) { idx = i; break; } } if ( idx == -1 ) { roar_dl_para_unref(para); roar_err_set(ROAR_ERROR_NOSPC); return NULL; } cont->context[idx] = NULL; // clear context. cont->deprefc[idx] = 0; if ( cont->callbacks != NULL && cont->callbacks->preload != NULL ) cont->callbacks->preload(cont, &(cont->context[idx]), name, flags, para); cont->handle[idx] = roar_dl_open(name, flags, 0, para); if ( cont->handle[idx] == NULL ) { err = roar_error; roar_dl_para_unref(para); roar_error = err; return NULL; } cont->numhandles++; if ( cont->callbacks != NULL && cont->callbacks->postload != NULL ) cont->callbacks->postload(cont, &(cont->context[idx]), cont->handle[idx], name, flags, para); if ( ra_init ) { if ( cont->callbacks != NULL && cont->callbacks->prera_init != NULL ) cont->callbacks->prera_init(cont, &(cont->context[idx]), cont->handle[idx], para); if ( roar_dl_ra_init(cont->handle[idx], NULL, para) == -1 ) { err = roar_error; if ( cont->callbacks != NULL && cont->callbacks->postra_init != NULL ) cont->callbacks->postra_init(cont, &(cont->context[idx]), cont->handle[idx], para); _unload(cont, idx); roar_dl_para_unref(para); cont->handle[idx] = NULL; roar_error = err; return NULL; } if ( cont->callbacks != NULL && cont->callbacks->postra_init != NULL ) cont->callbacks->postra_init(cont, &(cont->context[idx]), cont->handle[idx], para); if ( cont->options & OPT_AUTOAPPSCHED ) roar_dl_appsched_trigger(cont->handle[idx], ROAR_DL_APPSCHED_INIT); } roar_dl_para_unref(para); roar_dl_ref(cont->handle[idx]); return cont->handle[idx]; } int roar_plugincontainer_unload(struct roar_plugincontainer * cont, const char * name) { struct roar_dl_lhandle * lhandle; if ( cont == NULL || name == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } lhandle = roar_plugincontainer_get_lhandle_by_name(cont, name); if ( lhandle == NULL ) return -1; roar_dl_unref(lhandle); // we can do this early here as the handle stay valid in the container's array. return roar_plugincontainer_unload_lhandle(cont, lhandle); } int roar_plugincontainer_unload_lhandle(struct roar_plugincontainer * cont, struct roar_dl_lhandle * lhandle) { size_t i; if ( cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( lhandle == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } for (i = 0; i < MAX_PLUGINS; i++) { if ( cont->handle[i] == lhandle ) { if ( cont->deprefc[i] ) { // still in use. roar_err_set(ROAR_ERROR_BUSY); return -1; } _unload(cont, i); return 0; } } roar_err_set(ROAR_ERROR_NOENT); return -1; } int roar_plugincontainer_ra_init (struct roar_plugincontainer * cont) { size_t i; if ( cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; i < MAX_PLUGINS; i++) { if ( cont->handle[i] == NULL ) continue; if ( cont->callbacks != NULL && cont->callbacks->prera_init != NULL ) cont->callbacks->prera_init(cont, &(cont->context[i]), cont->handle[i], cont->default_para); roar_dl_ra_init(cont->handle[i], NULL, cont->default_para); if ( cont->callbacks != NULL && cont->callbacks->postra_init != NULL ) cont->callbacks->postra_init(cont, &(cont->context[i]), cont->handle[i], cont->default_para); if ( cont->options & OPT_AUTOAPPSCHED ) roar_dl_appsched_trigger(cont->handle[i], ROAR_DL_APPSCHED_INIT); } return 0; } // appsched: int roar_plugincontainer_appsched_trigger(struct roar_plugincontainer * cont, enum roar_dl_appsched_trigger trigger) { size_t i; int ret = -1; int rv; if ( cont == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( cont->numhandles == 1 ) { for (i = 0; i < MAX_PLUGINS; i++) { if ( cont->handle[i] == NULL ) continue; return roar_dl_appsched_trigger(cont->handle[i], trigger); } roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; i < MAX_PLUGINS; i++) { if ( cont->handle[i] == NULL ) continue; rv = roar_dl_appsched_trigger(cont->handle[i], trigger); if ( rv == 0 ) ret = 0; } return ret; } //ll ��������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/proto.c�����������������������������������������������������������������0000644�0001750�0001750�00000026234�12264733543�015440� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//proto.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define _ROAR_MESS_BUF_LEN_V0 (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 4 /* pos */ + 2 /* datalen */) #define _ROAR_MESS_BUF_LEN_V1 (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 4 /* pos */ + 2 /* datalen */ + \ 1 /* flags */) #define _ROAR_MESS_BUF_LEN_V2 (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 8 /* pos */ + 2 /* datalen */ + \ 4 /* flags */ + 2 /* seq */) #define _ROAR_MESS_BUF_LEN _ROAR_MESS_BUF_LEN_V0 #define _ROAR_MESS_BUF_LEN_MAX ROAR_MAX3(_ROAR_MESS_BUF_LEN_V0, _ROAR_MESS_BUF_LEN_V1, _ROAR_MESS_BUF_LEN_V2) #define _ROAR_MESS_CRC_LEN_V0 0 /* No CRC */ #define _ROAR_MESS_CRC_LEN_V1 1 #define _ROAR_MESS_CRC_LEN_V2 4 #define _ROAR_MESS_CRC_LEN_MAX ROAR_MAX3(_ROAR_MESS_CRC_LEN_V0, _ROAR_MESS_CRC_LEN_V1, _ROAR_MESS_CRC_LEN_V2) int roar_send_message (struct roar_connection * con, struct roar_message * mes, char * data) { struct roar_vio_calls * vio; if ( (vio = roar_get_connection_vio2(con)) == NULL ) return -1; return roar_vsend_message(vio, mes, data); } int roar_vsend_message(struct roar_vio_calls * vio, struct roar_message * mes, char * data) { char buf[_ROAR_MESS_BUF_LEN_MAX]; char crc[_ROAR_MESS_CRC_LEN_MAX]; size_t headerlen = 0; size_t crclen = 0; char * bufptr; roar_err_set(ROAR_ERROR_UNKNOWN); ROAR_DBG("roar_send_message(*): try to send an request..."); headerlen = _ROAR_MESS_BUF_LEN; buf[0] = mes->version; // first byte is always the version. switch (mes->version) { case 0: buf[1] = (unsigned char) mes->cmd; *(uint16_t*)(buf+2) = ROAR_HOST2NET16(mes->stream); *(uint32_t*)(buf+4) = ROAR_HOST2NET32(mes->pos); *(uint16_t*)(buf+8) = ROAR_HOST2NET16(mes->datalen); headerlen = _ROAR_MESS_BUF_LEN_V0; break; case 1: buf[1] = (unsigned char) (mes->flags & 0xFF); buf[2] = (unsigned char) mes->cmd; // ... roar_err_set(ROAR_ERROR_NSVERSION); return -1; break; case 2: headerlen = 16; buf[1] = (unsigned char) mes->cmd; *(uint16_t*)(buf+2) = ROAR_HOST2NET16(mes->stream); *(uint32_t*)(buf+4) = ROAR_HOST2NET32(mes->flags); if ( mes->flags & ROAR_MF_LSPOS ) { *(uint64_t*)(buf+8) = ROAR_HOST2NET64(mes->pos64); bufptr = buf+16; headerlen += 4; } else { *(uint32_t*)(buf+8) = ROAR_HOST2NET32(mes->pos); bufptr = buf+12; } *(uint16_t*)(bufptr+0) = ROAR_HOST2NET16(mes->datalen); *(uint16_t*)(bufptr+2) = ROAR_HOST2NET16(mes->seq); break; default: roar_err_set(ROAR_ERROR_BADVERSION); return -1; } if ( roar_vio_write(vio, buf, headerlen) != (ssize_t)headerlen ) { return -1; } if ( mes->datalen != 0 ) { if ( roar_vio_write(vio, data == NULL ? mes->data : data, mes->datalen) != (ssize_t)mes->datalen ) { return -1; } } if ( crclen != 0 ) { if ( roar_vio_write(vio, crc, crclen) != (ssize_t)crclen ) { return -1; } } roar_err_clear(); ROAR_DBG("roar_send_message(*) = 0"); return 0; } int roar_recv_message (struct roar_connection * con, struct roar_message * mes, char ** data) { return roar_recv_message2(con, mes, data, NULL); } int roar_recv_message2 (struct roar_connection * con, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe) { struct roar_vio_calls * vio; if ( (vio = roar_get_connection_vio2(con)) == NULL ) return -1; return roar_vrecv_message2(vio, mes, data, errorframe); } int roar_vrecv_message(struct roar_vio_calls * vio, struct roar_message * mes, char ** data) { return roar_vrecv_message2(vio, mes, data, NULL); } static inline int _libroar_msgresyncer(struct roar_vio_calls * vio, size_t len) { char buffer[2*LIBROAR_BUFFER_MSGDATA]; // this is always called with len > LIBROAR_BUFFER_MSGDATA. ssize_t ret; size_t errorc = 0; while (len && errorc < 4) { ret = roar_vio_read(vio, buffer, len > sizeof(buffer) ? sizeof(buffer) : len); if ( ret == (size_t)-1 ) { errorc++; } else { errorc = 0; len -= ret; } } if ( len ) return -1; // last error is still set. return 0; } int roar_vrecv_message2(struct roar_vio_calls * vio, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe) { // TODO: add CRC support. char buf[_ROAR_MESS_BUF_LEN_MAX]; // char crc[_ROAR_MESS_CRC_LEN_MAX]; size_t headerlen = 0; // size_t crclen = 0; size_t needlen; char * bufptr; roar_err_set(ROAR_ERROR_UNKNOWN); ROAR_DBG("roar_vrecv_message2(vio=%p, mes=%p, data=%p, errorframe=%p) = ?", vio, mes, data, errorframe); ROAR_DBG("roar_vrecv_message2(*): try to get a response form the server..."); if ( vio == NULL || mes == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( data != NULL ) *data = NULL; memset(mes, 0, sizeof(struct roar_message)); if ( roar_vio_read(vio, buf, _ROAR_MESS_BUF_LEN_V0) != _ROAR_MESS_BUF_LEN_V0 ) { roar_err_set(ROAR_ERROR_PROTO); return -1; } ROAR_DBG("roar_vrecv_message2(*): Got a header"); mes->version = buf[0]; headerlen = _ROAR_MESS_BUF_LEN_V0; switch (mes->version) { case 0: // we already have all data, so create the struct mes->cmd = (unsigned char)buf[1]; mes->stream = ROAR_NET2HOST16(*(uint16_t*)(buf+2)); mes->pos = ROAR_NET2HOST32(*(uint32_t*)(buf+4)); mes->pos64 = mes->pos; mes->datalen = ROAR_NET2HOST16(*(uint16_t*)(buf+8)); break; case 2: mes->cmd = (unsigned char)buf[1]; mes->stream = ROAR_NET2HOST16(*(uint16_t*)(buf+2)); mes->flags = ROAR_NET2HOST32(*(uint32_t*)(buf+4)); if ( mes->flags & ROAR_MF_LSPOS ) { headerlen = 20; } else { headerlen = 16; } break; default: roar_err_set(ROAR_ERROR_NSVERSION); return -1; break; } // check special case where headerlen < _ROAR_MESS_BUF_LEN_V0, this means that we need to put // some data we read as header into the data part of the message. if ( headerlen > _ROAR_MESS_BUF_LEN_V0 ) { needlen = headerlen - _ROAR_MESS_BUF_LEN_V0; if ( roar_vio_read(vio, buf+_ROAR_MESS_BUF_LEN_V0, needlen) != (ssize_t)needlen ) { roar_err_set(ROAR_ERROR_PROTO); return -1; } } switch (mes->version) { case 2: if ( mes->flags & ROAR_MF_LSPOS ) { mes->pos64 = ROAR_NET2HOST32(*(uint64_t*)(buf+8)); mes->pos = mes->pos64 & (uint64_t)0x0FFFFFFFFLLU; bufptr = buf+16; } else { mes->pos = ROAR_NET2HOST32(*(uint32_t*)(buf+8)); mes->pos64 = mes->pos; bufptr = buf+12; } mes->datalen = ROAR_NET2HOST16(*(uint16_t*)(bufptr+0)); mes->seq = ROAR_NET2HOST16(*(uint16_t*)(bufptr+2)); break; } if ( (int16_t)mes->stream == -1 ) mes->stream = -1; ROAR_DBG("roar_vrecv_message2(*): command=%i(%s)", mes->cmd, mes->cmd == ROAR_CMD_OK ? "OK" : (mes->cmd == ROAR_CMD_ERROR ? "ERROR" : "UNKNOWN")); // Below we only have data handling, handling of header is finished: if ( mes->datalen == 0 ) { ROAR_DBG("roar_vrecv_message2(*): no data in this pkg"); if ( mes->cmd == ROAR_CMD_ERROR && errorframe != NULL ) { roar_err_init(errorframe); } roar_err_clear(); ROAR_DBG("roar_vrecv_message2(*) = 0"); return 0; } if ( mes->datalen <= LIBROAR_BUFFER_MSGDATA ) { if ( roar_vio_read(vio, mes->data, mes->datalen) == (ssize_t)mes->datalen ) { ROAR_DBG("roar_vrecv_message2(*): Got data!"); roar_err_clear(); if ( mes->cmd == ROAR_CMD_ERROR && errorframe != NULL ) { if ( roar_err_parsemsg(mes, *data, errorframe) != 0 ) { roar_err_init(errorframe); } } ROAR_DBG("roar_vrecv_message2(*) = 0"); return 0; } return -1; } else { if ( data == NULL ) { if ( _libroar_msgresyncer(vio, mes->datalen) == -1 ) { roar_err_set(ROAR_ERROR_BADCKSUM); } else { roar_err_set(ROAR_ERROR_MSGSIZE); } return -1; } if ( (*data = roar_mm_malloc(mes->datalen)) == NULL ) { if ( _libroar_msgresyncer(vio, mes->datalen) == -1 ) { roar_err_set(ROAR_ERROR_BADCKSUM); } else { roar_err_set(ROAR_ERROR_NOMEM); } return -1; } if ( mes->datalen == 0 ) { roar_err_clear(); if ( mes->cmd == ROAR_CMD_ERROR && errorframe != NULL ) { roar_err_init(errorframe); } return 0; } if ( roar_vio_read(vio, *data, mes->datalen) == (ssize_t)mes->datalen ) { ROAR_DBG("roar_vrecv_message2(*): Got data!"); roar_err_clear(); if ( mes->cmd == ROAR_CMD_ERROR && errorframe != NULL ) { if ( roar_err_parsemsg(mes, *data, errorframe) != 0 ) { roar_err_init(errorframe); } } ROAR_DBG("roar_vrecv_message2(*) = 0"); return 0; } // error is still set (by roar_vio_read()). return -1; } // what happened here? return -1; } int roar_req (struct roar_connection * con, struct roar_message * mes, char ** data) { return roar_req2(con, mes, data, NULL); } int roar_req2 (struct roar_connection * con, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe) { struct roar_vio_calls * vio; if ( (vio = roar_get_connection_vio2(con)) == NULL ) return -1; if ( mes->version == _ROAR_MESSAGE_VERSION ) mes->version = con->version; if ( mes->version == 2 ) { mes->seq = roar_message_genseq(con, -1); } return roar_vreq2(vio, mes, data, errorframe); } int roar_vreq (struct roar_vio_calls * vio, struct roar_message * mes, char ** data) { return roar_vreq2(vio, mes, data, NULL); } int roar_vreq2 (struct roar_vio_calls * vio, struct roar_message * mes, char ** data, struct roar_error_frame * errorframe) { if ( roar_vsend_message(vio, mes, data != NULL ? *data : NULL) != 0 ) return -1; if ( data != NULL ) roar_mm_free(*data); roar_vio_sync(vio); // we need to do this becasue of ssl/compressed links return roar_vrecv_message2(vio, mes, data, errorframe); } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/random.c����������������������������������������������������������������0000644�0001750�0001750�00000014223�12264733543�015550� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//random.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_LIBGCRYPT #include <gcrypt.h> #endif #ifdef ROAR_HAVE_UNAME #include <sys/utsname.h> #endif static void roar_random_init (void) { static int inited = 0; if (inited) return; // add stuff here needed to bring up random source. roar_crypto_init(); inited = 1; } #define TIGER_BLOCKLEN 64 #define TIGER_DIGESTLEN (3*8) static size_t roar_nonce_salt_len = 0; static void * roar_nonce_salt = NULL; static unsigned char roar_nonce_pool[TIGER_DIGESTLEN]; static size_t roar_nonce_pool_len = 0; int roar_random_gen_nonce(void * buffer, size_t len) { static uint32_t buf[TIGER_BLOCKLEN/4]; static int inited = 0; static int idx = 0; volatile pid_t pid = getpid(); size_t i, writelen; void * off = buf; #ifdef ROAR_HAVE_TIME volatile uint32_t now = time(NULL); #endif #ifdef ROAR_HAVE_UNAME static struct utsname utsname; #endif roar_random_init(); if ( !inited ) { for (i = 0; i < (sizeof(buf)/sizeof(*buf)); i++) { #ifdef ROAR_HAVE_RAND buf[i] = rand() + pid; #else buf[i] = pid; #endif } #ifdef ROAR_HAVE_TIME buf[11] += now; #endif roar_hash_buffer(off, buf, TIGER_BLOCKLEN, ROAR_HT_TIGER); roar_hash_buffer(off+TIGER_DIGESTLEN, buf, TIGER_BLOCKLEN, ROAR_HT_TIGER); // init is now done: inited = 1; // do additional seeding: #ifdef ROAR_HAVE_UNAME if ( uname(&utsname) == 0 ) { roar_random_salt_nonce(&utsname, sizeof(utsname)); } #endif } while (len) { #ifdef ROAR_HAVE_TIME buf[12] += now; #endif #ifdef ROAR_HAVE_RAND buf[12] += rand(); #endif buf[12] += pid; buf[13] += pid; off = buf; if ( idx ) { off += TIGER_DIGESTLEN; idx = 0; } else { idx = 1; } ROAR_DBG("roar_random_gen_nonce(*): buf={0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x}", (unsigned int)buf[0], (unsigned int)buf[1], (unsigned int)buf[2], (unsigned int)buf[3], (unsigned int)buf[4], (unsigned int)buf[5], (unsigned int)buf[6], (unsigned int)buf[7], (unsigned int)buf[8], (unsigned int)buf[9], (unsigned int)buf[10], (unsigned int)buf[11], (unsigned int)buf[12], (unsigned int)buf[13], (unsigned int)buf[14], (unsigned int)buf[15]); roar_hash_salted_buffer(off, buf, TIGER_BLOCKLEN, ROAR_HT_TIGER, roar_nonce_salt, roar_nonce_salt_len); writelen = len >= TIGER_DIGESTLEN ? TIGER_DIGESTLEN : len; memcpy(buffer, off, writelen); buffer += writelen; len -= writelen; } return 0; } int roar_random_salt_nonce (void * salt, size_t len) { char buf[1]; int ret; roar_nonce_salt = salt; roar_nonce_salt_len = len; ret = roar_random_gen_nonce(buf, sizeof(buf)); roar_nonce_salt = NULL; roar_nonce_salt_len = 0; return ret; } uint16_t roar_random_uint16(void) { uint16_t ret; if ( roar_nonce_pool_len < 2 ) { roar_random_gen_nonce(roar_nonce_pool, sizeof(roar_nonce_pool)); roar_nonce_pool_len = sizeof(roar_nonce_pool); } ret = roar_nonce_pool[sizeof(roar_nonce_pool)-roar_nonce_pool_len+0] << 0; ret |= roar_nonce_pool[sizeof(roar_nonce_pool)-roar_nonce_pool_len+1] << 8; roar_nonce_pool_len -= 2; return ret; } uint32_t roar_random_uint32(void) { uint32_t ret; if ( roar_nonce_pool_len < 4 ) { roar_random_gen_nonce(roar_nonce_pool, sizeof(roar_nonce_pool)); roar_nonce_pool_len = sizeof(roar_nonce_pool); } ret = (uint32_t)roar_nonce_pool[sizeof(roar_nonce_pool)-roar_nonce_pool_len+0] << 0; ret |= (uint32_t)roar_nonce_pool[sizeof(roar_nonce_pool)-roar_nonce_pool_len+1] << 8; ret |= (uint32_t)roar_nonce_pool[sizeof(roar_nonce_pool)-roar_nonce_pool_len+2] << 16; ret |= (uint32_t)roar_nonce_pool[sizeof(roar_nonce_pool)-roar_nonce_pool_len+3] << 24; roar_nonce_pool_len -= 4; return ret; } int roar_random_gen(void * buffer, size_t len, int quality) { if ( len == 0 ) return 0; if ( buffer == NULL ) return -1; roar_random_init(); switch (quality) { case ROAR_RANDOM_NONE: // no entropy: memset(buffer, 0, len); break; case ROAR_RANDOM_VERY_WEAK: return roar_random_gen_nonce(buffer, len); break; #ifdef ROAR_HAVE_LIBGCRYPT case ROAR_RANDOM_WEAK: gcry_create_nonce(buffer, len); break; case ROAR_RANDOM_NORMAL: case ROAR_RANDOM_STRONG: gcry_randomize(buffer, len, GCRY_STRONG_RANDOM); break; case ROAR_RANDOM_VERY_STRONG: gcry_randomize(buffer, len, GCRY_VERY_STRONG_RANDOM); break; #endif default: return -1; break; } return 0; } void * roar_random_genbuf(size_t len, int quality, int locked) { void * ret = roar_mm_malloc(len); if (ret == NULL) return NULL; if ( locked ) { if ( roar_mm_mlock(ret, len) == -1 ) { roar_mm_free(ret); return NULL; } } if ( roar_random_gen(ret, len, quality) == -1 ) { roar_mm_free(ret); return NULL; } return ret; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/roardl.c����������������������������������������������������������������0000644�0001750�0001750�00000103166�12264733543�015560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roardl.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_H_DIRENT #include <dirent.h> #endif #if defined(ROAR_HAVE_H_DLFCN) && !defined(RTLD_NEXT) #define RTLD_NEXT ((void *) -1L) #endif #define RTF_RA_INITED 0x0001 #define RTF_APPSCHED_INITED 0x0002 #define RTF_APPSCHED_FREED 0x0004 struct roar_dl_lhandle { size_t refc; // currently unused. int flags; char * libname; // only used for ROAR_DL_FLAG_STATIC. struct roar_dl_librarypara * para; struct roar_dl_libraryinst * lib; struct { struct roar_error_state error_state; void * global_data; void * global_data_state; struct roar_notify_core * notifycore; struct roar_vio_calls * stdvios[3]; } context; unsigned int runtime_flags; #if defined(ROAR_HAVE_H_DLFCN) void * handle; #elif defined(ROAR_TARGET_WIN32) HMODULE handle; #endif }; // TODO: this should be removed on next SONAME change. static struct roar_dl_lhandle * __currently_inited = NULL; static int __currently_inited_fn = -1; struct roar_dl_librarypara * roar_dl_para_new(const char * args, void * binargv, const char * appname, const char * abiversion) { struct roar_dl_librarypara * ret = roar_mm_malloc(sizeof(struct roar_dl_librarypara)); ssize_t argc; int err; if ( ret == NULL ) return NULL; memset(ret, 0, sizeof(struct roar_dl_librarypara)); ret->version = ROAR_DL_LIBPARA_VERSION; ret->len = sizeof(struct roar_dl_librarypara); ret->refc = 1; ret->argc = 0; ret->argv = NULL; ret->args_store = NULL; ret->binargv = binargv; ret->appname = appname; ret->abiversion = abiversion; if ( args != NULL ) { ret->args_store = roar_mm_strdup(args); if ( ret->args_store == NULL ) { roar_mm_free_noerror(ret); return NULL; } argc = roar_keyval_split(&(ret->argv), ret->args_store, NULL, NULL, 1); if ( argc == -1 ) { err = roar_error; roar_mm_free(ret->args_store); roar_mm_free(ret); roar_error = err; return NULL; } ret->argc = argc; } return ret; } int roar_dl_para_ref (struct roar_dl_librarypara * para) { if ( para == NULL ) { ROAR_DBG("roar_dl_para_ref(para=%p) = -1 // error=FAULT", para); roar_err_set(ROAR_ERROR_FAULT); return -1; } para->refc++; ROAR_DBG("roar_dl_para_ref(para=%p) = 0", para); return 0; } int roar_dl_para_unref (struct roar_dl_librarypara * para) { if ( para == NULL ) { ROAR_DBG("roar_dl_para_unref(para=%p) = -1 // error=FAULT", para); roar_err_set(ROAR_ERROR_FAULT); return -1; } para->refc--; if ( para->refc ) { ROAR_DBG("roar_dl_para_unref(para=%p) = 0", para); return 0; } if ( para->notifycore != NULL ) roar_notify_core_unref(para->notifycore); if ( para->args_store != NULL ) { roar_mm_free(para->args_store); roar_mm_free(para->argv); } roar_mm_free(para); ROAR_DBG("roar_dl_para_unref(para=%p) = 0", para); return 0; } int roar_dl_para_check_version (struct roar_dl_librarypara * para, const char * appname, const char * abiversion) { if ( para == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } // check if both appnames are NULL or non-NULL. if ( (para->appname == NULL && appname != NULL) || (para->appname != NULL && appname == NULL) ) { roar_err_set(ROAR_ERROR_BADHOST); return -1; } // check if the appname matches if given. if ( para->appname != NULL && !!strcmp(para->appname, appname) ) { roar_err_set(ROAR_ERROR_BADHOST); return -1; } // check if both ABI versions are NULL or non-NULL. if ( (para->abiversion == NULL && abiversion != NULL) || (para->abiversion != NULL && abiversion == NULL) ) { roar_err_set(ROAR_ERROR_BADVERSION); return -1; } // check if the ABI versions matches if given. if ( para->abiversion != NULL && !!strcmp(para->abiversion, abiversion) ) { roar_err_set(ROAR_ERROR_BADVERSION); return -1; } return 0; } #if defined(ROAR_HAVE_H_DLFCN) static void * _roardl2ldl (struct roar_dl_lhandle * lhandle) { ROAR_DBG("_roardl2ldl(lhandle=%p) = ?", lhandle); if ( (void*)lhandle < (void*)128 ) { switch ((int)(void*)lhandle) { case (int)(void*)ROAR_DL_HANDLE_DEFAULT: case (int)(void*)ROAR_DL_HANDLE_LIBROAR: case (int)(void*)ROAR_DL_HANDLE_APPLICATION: ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_DEFAULT); return RTLD_DEFAULT; break; case (int)(void*)ROAR_DL_HANDLE_NEXT: ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)RTLD_NEXT); return RTLD_NEXT; break; } } ROAR_DBG("_roardl2ldl(lhandle=%p) = %p", lhandle, (void*)(lhandle->handle)); return lhandle->handle; } #elif defined(ROAR_TARGET_WIN32) static HMODULE _roardl2winhandle(struct roar_dl_lhandle * lhandle) { if ( (void*)lhandle < (void*)128 ) { return NULL; } return lhandle->handle; } #endif #ifdef ROAR_HAVE_H_DIRENT // pvn = prefix, host vendor, host name static struct roar_dl_lhandle * _load_from_path_pvn(const char * name, int flags, int ra_init, struct roar_dl_librarypara * para, const char * prefix, const char * hostvendor, const char * hostname) { struct roar_dl_lhandle * ret = NULL; int i, j; char path[1024]; const char * path_format[] = {"%s/%s/%s", "%s/%s/universal", "%s/universal/universal"}; DIR * dir; struct dirent * dirent; char file[1024]; const char * file_format[] = {"%s/%s/%s", "%s/%s/%s" ROAR_SHARED_SUFFIX, "%s/%s/lib%s" ROAR_SHARED_SUFFIX}; // cont->handle[idx] = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, para); //#vars: $PREFIX_PLUGINS, $hostvendor, $hostname, $name //#search order: $PREFIX_PLUGINS/{$hostvendor/{$hostname,universal},universal/universal}/*/{,lib}$name.so for (i = 0; i < 3; i++) { snprintf(path, sizeof(path), path_format[i], prefix, hostvendor, hostname); dir = opendir(path); if ( dir == NULL ) continue; while ((dirent = readdir(dir)) != NULL) { if ( !strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..") ) continue; for (j = 0; j < 3; j++) { snprintf(file, sizeof(file), file_format[j], path, dirent->d_name, name); ret = roar_dl_open(file, flags, ra_init, para); if ( ret != NULL ) { closedir(dir); return ret; } } } closedir(dir); } return NULL; } static struct roar_dl_lhandle * _load_from_path(const char * name, int flags, int ra_init, struct roar_dl_librarypara * para) { struct roar_dl_lhandle * ret = NULL; char * host = NULL; char * hostvendor_buffer = NULL; char * hostvendor = NULL; char * hostname = NULL; size_t hostvendor_len; char * c, * d; if ( para != NULL && para->appname != NULL && para->appname[0] != 0 ) { host = roar_mm_strdup(para->appname); // if we are out of memory we will likely not pass the rest, so just return in error. if ( host == NULL ) return NULL; hostname = host; c = strstr(host, "<"); if ( c != NULL ) { while (c[-1] == ' ') c--; *c = 0; c++; while (*c == ' ' || *c == '<') c++; if ( *c ) { d = strstr(c, ">"); if ( d != NULL ) *d = 0; d = strstr(c, "/"); if ( d != NULL ) { *d = '-'; hostvendor = c; } else { hostvendor_len = roar_mm_strlen(c) + 1 /* tailing \0 */ + 6 /* "unreg-" */; hostvendor_buffer = roar_mm_malloc(hostvendor_len); // see above if ( hostvendor_buffer == NULL ) { roar_mm_free(host); return NULL; } roar_mm_strlcpy(hostvendor_buffer, "unreg-", hostvendor_len); roar_mm_strlcat(hostvendor_buffer, c, hostvendor_len); hostvendor = hostvendor_buffer; } } } } if ( hostvendor == NULL ) hostvendor = "universal"; if ( hostname == NULL ) hostname = "universal"; ret = _load_from_path_pvn(name, flags, ra_init, para, ROAR_PREFIX_PLUGINS, hostvendor, hostname); if ( host != NULL ) roar_mm_free(host); if ( hostvendor_buffer != NULL ) roar_mm_free(hostvendor_buffer); return ret; } #endif static struct roar_dl_lhandle * _roar_dl_open_pluginpath(const char * filename, int flags, int ra_init, struct roar_dl_librarypara * para) { flags |= ROAR_DL_FLAG_PLUGINPATH; flags -= ROAR_DL_FLAG_PLUGINPATH; #ifdef ROAR_HAVE_H_DIRENT // do normal open for everything with a path name. if ( strstr(filename, "/") != NULL ) return roar_dl_open(filename, flags, ra_init, para); return _load_from_path(filename, flags, ra_init, para); #else // fall back to system open function. return roar_dl_open(filename, flags, ra_init, para); #endif } struct roar_dl_lhandle * roar_dl_open(const char * filename, int flags, int ra_init, struct roar_dl_librarypara * para) { struct roar_dl_lhandle * ret = NULL; #if defined(ROAR_HAVE_H_DLFCN) #if defined(RTLD_DEEPBIND) && 0 // FIXME: This is currently disabled. See #296. int libdl_flags = RTLD_DEEPBIND; #else int libdl_flags = 0; #endif #endif int err; switch (flags) { case ROAR_DL_FLAG_DEFAULTS: flags = ROAR_DL_FLAG_NONE; break; case ROAR_DL_FLAG_PLUGIN: flags = ROAR_DL_FLAG_PLUGINPATH; break; } if ( flags & ROAR_DL_FLAG_PLUGINPATH ) return _roar_dl_open_pluginpath(filename, flags, ra_init, para); #if defined(ROAR_HAVE_H_DLFCN) if ( flags & ROAR_DL_FLAG_LAZY ) { libdl_flags |= RTLD_LAZY; } else { libdl_flags |= RTLD_NOW; } #endif if ( (ret = roar_mm_malloc(sizeof(struct roar_dl_lhandle))) == NULL ) return NULL; memset(ret, 0, sizeof(struct roar_dl_lhandle)); roar_err_initstore(&(ret->context.error_state)); ret->flags = flags; ret->refc = 1; if ( flags & ROAR_DL_FLAG_STATIC ) { if ( filename == NULL ) { ret->libname = NULL; } else { ret->libname = roar_mm_strdup(filename); } } else { #if defined(ROAR_HAVE_H_DLFCN) ret->handle = dlopen(filename, libdl_flags); if ( ret->handle == NULL ) { ROAR_DBG("roar_dl_open(filename='%s', flags=%i, ra_init=%i, para=%p): Can not load library: %s", filename, flags, ra_init, para, roar_dl_errstr(ret)); roar_mm_free(ret); return NULL; } #elif defined(ROAR_TARGET_WIN32) ret->handle = LoadLibrary(filename); if ( ret->handle == NULL ) { roar_mm_free(ret); return NULL; } #else roar_mm_free(ret); roar_err_set(ROAR_ERROR_NOSYS); return NULL; #endif } ret->para = para; if ( roar_vio_ref(roar_stdin) == 0 ) ret->context.stdvios[0] = roar_stdin; if ( roar_vio_ref(roar_stdout) == 0 ) ret->context.stdvios[1] = roar_stdout; if ( roar_vio_ref(roar_stderr) == 0 ) ret->context.stdvios[2] = roar_stderr; if ( ra_init ) { if ( roar_dl_ra_init(ret, NULL, para) == -1 ) { err = roar_error; ROAR_WARN("roar_dl_open(filename='%s', flags=%i, ra_init=%i, para=%p): Can not init RA lib: %s", filename, flags, ra_init, para, roar_error2str(err)); #if defined(ROAR_HAVE_H_DLFCN) if ( ret->handle != NULL ) dlclose(ret->handle); #elif defined(ROAR_TARGET_WIN32) if ( ret->handle != NULL ) FreeLibrary(ret->handle); #endif roar_vio_unref(ret->context.stdvios[0]); roar_vio_unref(ret->context.stdvios[1]); roar_vio_unref(ret->context.stdvios[2]); roar_mm_free(ret); roar_error = err; return NULL; } } if ( para != NULL ) roar_dl_para_ref(para); return ret; } int roar_dl_ref (struct roar_dl_lhandle * lhandle) { if ( (void*)lhandle < (void*)128 ) { ROAR_DBG("roar_dl_ref(lhandle=%p) = -1 // error=BADFH", lhandle); roar_err_set(ROAR_ERROR_BADFH); return -1; } lhandle->refc++; ROAR_DBG("roar_dl_ref(lhandle=%p) = 0", lhandle); return 0; } int roar_dl_unref (struct roar_dl_lhandle * lhandle) { int ret = -1; if ( (void*)lhandle < (void*)128 ) { ROAR_DBG("roar_dl_unref(lhandle=%p) = -1 // error=BADFH", lhandle); roar_err_set(ROAR_ERROR_BADFH); return -1; } lhandle->refc--; if ( lhandle->refc ) { ROAR_DBG("roar_dl_unref(lhandle=%p) = 0", lhandle); return 0; } roar_dl_unregister_fn(lhandle); if ( lhandle->lib != NULL && lhandle->lib->unload != NULL ) { roar_dl_context_restore(lhandle); lhandle->lib->unload(lhandle->para, lhandle->lib); roar_dl_context_store(lhandle); } #if defined(ROAR_HAVE_H_DLFCN) if ( lhandle->handle == NULL ) { ret = 0; } else { ret = dlclose(_roardl2ldl(lhandle)); } #elif defined(ROAR_TARGET_WIN32) if ( lhandle->handle == NULL ) { ret = 0; } else { if ( FreeLibrary(_roardl2winhandle(lhandle)) ) { ret = 0; } else { ret = -1; } } #else ret = -1; #endif roar_vio_unref(lhandle->context.stdvios[0]); roar_vio_unref(lhandle->context.stdvios[1]); roar_vio_unref(lhandle->context.stdvios[2]); if ( lhandle->context.global_data != NULL ) roar_mm_free(lhandle->context.global_data); if ( lhandle->para != NULL ) roar_dl_para_unref(lhandle->para); if ( lhandle->libname != NULL ) roar_mm_free(lhandle->libname); roar_mm_free(lhandle); ROAR_DBG("roar_dl_unref(lhandle=%p) = %i", lhandle, ret); return ret; } void * roar_dl_getsym(struct roar_dl_lhandle * lhandle, const char * sym, int type) { #if defined(ROAR_HAVE_H_DLFCN) void * ret = dlsym(_roardl2ldl(lhandle), sym); (void)type; ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i): ret=%p, errno=%s(%i), dlerror()='%s'", lhandle, sym, type, ret, strerror(errno), errno, dlerror()); ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = %p", lhandle, sym, type, ret); return ret; #elif defined(ROAR_TARGET_WIN32) FARPROC ret = GetProcAddress(_roardl2winhandle(lhandle), sym); return (void*)ret; #else ROAR_DBG("roar_dl_getsym(lhandle=%p, sym='%s', type=%i) = NULL // errno=NOSYS", lhandle, sym, type, ret); roar_err_set(ROAR_ERROR_NOSYS); return NULL; #endif } int roar_dl_ra_init(struct roar_dl_lhandle * lhandle, const char * prefix, struct roar_dl_librarypara * para) { struct roar_dl_lhandle * old_init; int old_fn; #define _SUFFIX "_roaraudio_library_init" char name[80] = _SUFFIX; struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para); struct roar_dl_libraryinst * lib; struct roar_dl_lhandle * getsymhandle = lhandle; void * global_data_state = NULL; int i; if ( (void*)lhandle < (void*)128 ) { if ( prefix == NULL ) return -1; } else { if ( lhandle->runtime_flags & RTF_RA_INITED ) return 0; if ( prefix == NULL ) prefix = lhandle->libname; if ( para == NULL ) para = lhandle->para; if ( lhandle->flags & ROAR_DL_FLAG_STATIC ) getsymhandle = ROAR_DL_HANDLE_DEFAULT; } if ( prefix != NULL ) { roar_mm_strscpy(name, "_"); roar_mm_strscat(name, prefix); roar_mm_strscat(name, _SUFFIX); } ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): name='%s'", lhandle, prefix, name); if ( (func = roar_dl_getsym(getsymhandle, name, -1)) == NULL ) { ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s') = -1", lhandle, prefix); return -1; } ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): func=%p", lhandle, prefix, func); roar_err_set(ROAR_ERROR_BADLIB); // set a default error in case it returns NULL but not set an error code. lib = func(para); if ( lib == NULL ) return -1; if ( lib->version != ROAR_DL_LIBINST_VERSION ) return -1; if ( sizeof(struct roar_dl_libraryinst) > lib->len ) return -1; if ( lib->host_appname != NULL || lib->host_abiversion != NULL ) { // check for correct host. if ( para == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( roar_dl_para_check_version(para, lib->host_appname, lib->host_abiversion) == -1 ) return -1; } if ( (lib->libdep == NULL && lib->libdep_len) || (lib->libdep != NULL && !lib->libdep_len) ) { roar_err_set(ROAR_ERROR_BADLIB); return -1; } if ( lib->libdep != NULL && lib->libdep_len ) { // dynamic loader infos are currently not supported. roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( !((void*)lhandle < (void*)128) ) { lhandle->lib = lib; if ( lib->global_data_len ) { lhandle->context.global_data = roar_mm_malloc(lib->global_data_len); if ( lhandle->context.global_data == NULL ) return -1; if ( lib->global_data_init == NULL ) { memset(lhandle->context.global_data, 0, lib->global_data_len); } else { memcpy(lhandle->context.global_data, lib->global_data_init, lib->global_data_len); } } } if ( lib->global_data_pointer != NULL ) { global_data_state = *(lib->global_data_pointer); if ( (void*)lhandle < (void*)128 ) { *(lib->global_data_pointer) = lib->global_data_init; } else { *(lib->global_data_pointer) = lhandle->context.global_data; } } roar_dl_context_restore(lhandle); old_init = __currently_inited; old_fn = __currently_inited_fn; __currently_inited = lhandle; for (i = 0; i < ROAR_DL_FN_MAX; i++) { __currently_inited_fn = i; if ( lib->func[i] != NULL ) lib->func[i](para, lib); } __currently_inited_fn = old_fn; __currently_inited = old_init; roar_dl_context_store(lhandle); if ( lib->global_data_pointer != NULL ) { if ( !((void*)lhandle < (void*)128) ) { *(lib->global_data_pointer) = global_data_state; } } if ( !((void*)lhandle < (void*)128) ) lhandle->runtime_flags |= RTF_RA_INITED; return 0; } const char * roar_dl_errstr(struct roar_dl_lhandle * lhandle) { #if defined(ROAR_HAVE_H_DLFCN) (void)lhandle; return dlerror(); #elif defined(ROAR_TARGET_WIN32) roar_err_from_errno(); return roar_error2str(roar_error); #else return NULL; #endif } struct roar_dl_librarypara * roar_dl_getpara(struct roar_dl_lhandle * lhandle) { if ( (void*)lhandle < (void*)128 ) { roar_err_set(ROAR_ERROR_NOTSUP); return NULL; } if ( lhandle->para == NULL ) { roar_err_set(ROAR_ERROR_NOENT); return NULL; } if ( roar_dl_para_ref(lhandle->para) == -1 ) return NULL; return lhandle->para; } const struct roar_dl_libraryname * roar_dl_getlibname(struct roar_dl_lhandle * lhandle) { if ( (void*)lhandle < (void*)128 ) { roar_err_set(ROAR_ERROR_NOTSUP); return NULL; } if ( lhandle->lib == NULL ) { roar_err_set(ROAR_ERROR_BADLIB); return NULL; } if ( lhandle->lib->libname == NULL ) { roar_err_set(ROAR_ERROR_NOENT); return NULL; } if ( lhandle->lib->libname->version != ROAR_DL_LIBNAME_VERSION ) { roar_err_set(ROAR_ERROR_BADVERSION); return NULL; } if ( lhandle->lib->libname->len != sizeof(struct roar_dl_libraryname) ) { roar_err_set(ROAR_ERROR_HOLE); return NULL; } return lhandle->lib->libname; } static inline void __swap_stdvios(struct roar_dl_lhandle * lhandle) { struct roar_vio_calls * vio; vio = roar_stdin; roar_stdin = lhandle->context.stdvios[0]; lhandle->context.stdvios[0] = vio; vio = roar_stdout; roar_stdout = lhandle->context.stdvios[1]; lhandle->context.stdvios[1] = vio; vio = roar_stderr; roar_stderr = lhandle->context.stdvios[2]; lhandle->context.stdvios[2] = vio; } int roar_dl_context_restore(struct roar_dl_lhandle * lhandle) { struct roar_error_state error_state; ROAR_DBG("roar_dl_context_restore(lhandle=%p) = ?", lhandle); if ( (void*)lhandle < (void*)128 ) { ROAR_DBG("roar_dl_context_restore(lhandle=%p) = -1 // errno=NOTSUP", lhandle); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } roar_err_store(&error_state); roar_err_restore(&(lhandle->context.error_state)); lhandle->context.error_state = error_state; __swap_stdvios(lhandle); if ( lhandle->lib->global_data_pointer != NULL ) { ROAR_DBG("roar_dl_context_restore(lhandle=%p): gptr(%p): %p -> %p", lhandle, lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data); lhandle->context.global_data_state = *(lhandle->lib->global_data_pointer); *(lhandle->lib->global_data_pointer) = lhandle->context.global_data; } if ( lhandle->para != NULL && lhandle->para->notifycore != NULL ) lhandle->context.notifycore = roar_notify_core_swap_global(lhandle->para->notifycore); ROAR_DBG("roar_dl_context_restore(lhandle=%p) = 0", lhandle); return 0; } int roar_dl_context_store(struct roar_dl_lhandle * lhandle) { struct roar_error_state error_state; ROAR_DBG("roar_dl_context_store(lhandle=%p) = ?", lhandle); if ( (void*)lhandle < (void*)128 ) { ROAR_DBG("roar_dl_context_store(lhandle=%p) = -1 // errno=NOTSUP", lhandle); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( lhandle->para != NULL && lhandle->para->notifycore != NULL ) { roar_notify_core_unref(roar_notify_core_swap_global(lhandle->context.notifycore)); roar_notify_core_unref(lhandle->context.notifycore); lhandle->context.notifycore = NULL; } if ( lhandle->lib->global_data_pointer != NULL ) { ROAR_DBG("roar_dl_context_store(lhandle=%p): gptr(%p): %p -> %p", lhandle, lhandle->lib->global_data_pointer, *(lhandle->lib->global_data_pointer), lhandle->context.global_data_state); *(lhandle->lib->global_data_pointer) = lhandle->context.global_data_state; } __swap_stdvios(lhandle); roar_err_store(&error_state); roar_err_restore(&(lhandle->context.error_state)); lhandle->context.error_state = error_state; ROAR_DBG("roar_dl_context_store(lhandle=%p) = 0", lhandle); return 0; } int roar_dl_appsched_trigger__handle_about(struct roar_dl_lhandle * lhandle) { libroar_dl_service_apitype(roar_service_about) api; int ret, err; if ( roar_dl_service_get_api(NULL, ROAR_SERVICE_ABOUT_NAME, ROAR_SERVICE_ABOUT_ABI, &api) == -1 ) return -1; ret = libroar_dl_service_run_func(api, show, int, roar_dl_getlibname(lhandle)); err = roar_error; libroar_dl_service_free_api(api); roar_error = err; return ret; } int roar_dl_appsched_trigger__handle_help(struct roar_dl_lhandle * lhandle) { libroar_dl_service_apitype(roar_service_help) api; int ret, err; if ( roar_dl_service_get_api(NULL, ROAR_SERVICE_HELP_NAME, ROAR_SERVICE_HELP_ABI, &api) == -1 ) return -1; ret = libroar_dl_service_run_func(api, show, int, roar_dl_getlibname(lhandle), NULL); err = roar_error; libroar_dl_service_free_api(api); roar_error = err; return ret; } int roar_dl_appsched_trigger__handle_preferences(struct roar_dl_lhandle * lhandle) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } int roar_dl_appsched_trigger(struct roar_dl_lhandle * lhandle, enum roar_dl_appsched_trigger trigger) { int (*func) (struct roar_dl_librarypara * para) = NULL; int ret; if ( (void*)lhandle < (void*)128 ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( lhandle->lib == NULL ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } if ( lhandle->lib->appsched == NULL ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } switch (trigger) { #define _trig(lname,uname) \ case ROAR_DL_APPSCHED_ ## uname : \ func = lhandle->lib->appsched->lname; \ break; _trig(init, INIT); _trig(free, FREE); _trig(update, UPDATE); _trig(tick, TICK); _trig(wait, WAIT); // not yet supported by struct roar_dl_appsched. case ROAR_DL_APPSCHED_ABOUT: case ROAR_DL_APPSCHED_HELP: case ROAR_DL_APPSCHED_PREFERENCES: func = NULL; break; // use ifndef here so warnings of unhandled enum values will be shown in DEBUG mode. #ifndef DEBUG default: roar_err_set(ROAR_ERROR_BADRQC); return -1; break; #endif } if ( func == NULL ) { if ( trigger == ROAR_DL_APPSCHED_INIT ) { lhandle->runtime_flags |= RTF_APPSCHED_INITED|RTF_APPSCHED_FREED; lhandle->runtime_flags -= RTF_APPSCHED_FREED; } else if ( trigger == ROAR_DL_APPSCHED_FREE ) { lhandle->runtime_flags |= RTF_APPSCHED_INITED|RTF_APPSCHED_FREED; lhandle->runtime_flags -= RTF_APPSCHED_INITED; } switch (trigger) { case ROAR_DL_APPSCHED_ABOUT: return roar_dl_appsched_trigger__handle_about(lhandle); break; case ROAR_DL_APPSCHED_HELP: return roar_dl_appsched_trigger__handle_help(lhandle); break; case ROAR_DL_APPSCHED_PREFERENCES: return roar_dl_appsched_trigger__handle_preferences(lhandle); break; default: roar_err_set(ROAR_ERROR_NOENT); return -1; break; } } if ( trigger == ROAR_DL_APPSCHED_INIT ) { if ( lhandle->runtime_flags & RTF_APPSCHED_INITED ) { roar_err_set(ROAR_ERROR_BUSY); return -1; } } else { if ( !(lhandle->runtime_flags & RTF_APPSCHED_INITED) ) { roar_err_set(ROAR_ERROR_BUSY); return -1; } } roar_dl_context_restore(lhandle); ret = func(lhandle->para); roar_dl_context_store(lhandle); if ( trigger == ROAR_DL_APPSCHED_INIT ) { lhandle->runtime_flags |= RTF_APPSCHED_INITED|RTF_APPSCHED_FREED; lhandle->runtime_flags -= RTF_APPSCHED_FREED; } else if ( trigger == ROAR_DL_APPSCHED_FREE ) { lhandle->runtime_flags |= RTF_APPSCHED_INITED|RTF_APPSCHED_FREED; lhandle->runtime_flags -= RTF_APPSCHED_INITED; } return ret; } #define __MAX_FNREGS 24 static struct __fnregs { struct roar_dl_lhandle * lhandle; int subtype; const void * object; size_t objectlen; int version; int options; } __fnrefs[ROAR_DL_FN_MAX][__MAX_FNREGS]; static int __fnreg_check_trigger(const struct __fnregs * handle) { if ( handle->subtype != ROAR_DL_FNREG_SUBTYPE ) return -1; if ( handle->version != ROAR_DL_FNREG_VERSION ) return -1; if ( handle->objectlen != ROAR_DL_FNREG_SIZE ) return -1; return 0; } static void __fnreg_trigger_if_match(const struct roar_dl_fnreg * callback, const struct __fnregs * reg, int fn, enum roar_dl_fnreg_action action) { if ( callback->fn != -1 && callback->fn != fn ) return; if ( callback->subtype != -1 && callback->subtype != reg->subtype ) return; if ( callback->version != -1 && callback->version != reg->version ) return; if ( callback->callback == NULL ) return; callback->callback(action, fn, reg->subtype, reg->object, reg->objectlen, reg->version, reg->options, callback->userdata, reg->lhandle); } static void __fnreg_trigger_by_reg(const struct __fnregs * reg, enum roar_dl_fnreg_action action, int fn) { size_t j; for (j = 0; j < __MAX_FNREGS; j++) { if ( __fnrefs[ROAR_DL_FN_REGFN][j].lhandle != NULL ) { if ( __fnreg_check_trigger(&(__fnrefs[ROAR_DL_FN_REGFN][j])) == -1 ) continue; __fnreg_trigger_if_match(__fnrefs[ROAR_DL_FN_REGFN][j].object, reg, fn, action); } } } static void __fnreg_trigger_by_handler(const struct __fnregs * handle, enum roar_dl_fnreg_action action) { size_t i, j; if ( __fnreg_check_trigger(handle) == -1 ) return; for (i = 0; i < ROAR_DL_FN_MAX; i++) { for (j = 0; j < __MAX_FNREGS; j++) { if ( __fnrefs[i][j].lhandle != NULL ) { __fnreg_trigger_if_match(handle->object, &(__fnrefs[i][j]), i, action); } } } } int roar_dl_register_fn(struct roar_dl_lhandle * lhandle, int fn, int subtype, const void * object, size_t objectlen, int version, int options) { struct __fnregs * c = NULL; size_t i; if ( lhandle == NULL ) lhandle = __currently_inited; if ( fn == -1 ) fn = __currently_inited_fn; if ( lhandle == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( fn < 0 || fn >= ROAR_DL_FN_MAX ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } if ( object == NULL || objectlen == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } for (i = 0; i < __MAX_FNREGS; i++) { if ( __fnrefs[fn][i].lhandle != NULL ) continue; c = &(__fnrefs[fn][i]); break; } if ( c == NULL ) { roar_err_set(ROAR_ERROR_NOSPC); return -1; } c->lhandle = lhandle; c->subtype = subtype; c->object = object; c->objectlen = objectlen; c->version = version; if ( fn == ROAR_DL_FN_REGFN ) { __fnreg_trigger_by_handler(c, ROAR_DL_FNREG); } else { __fnreg_trigger_by_reg(c, ROAR_DL_FNREG, fn); } return 0; } int roar_dl_unregister_fn2(struct roar_dl_lhandle * lhandle, int fn, int subtype, const void * object, size_t objectlen, int version, int options) { struct __fnregs * c = NULL; size_t i, j; if ( lhandle == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; i < ROAR_DL_FN_MAX; i++) { if ( fn != -1 && fn != i ) continue; for (j = 0; j < __MAX_FNREGS; j++) { c = &(__fnrefs[i][j]); if ( c->lhandle != lhandle ) continue; if ( subtype != -1 && subtype != c->subtype ) continue; if ( object != NULL && object != c->object ) continue; if ( objectlen != (size_t)-1 && objectlen != c->objectlen ) continue; if ( version != -1 && version != c->version ) continue; if ( options != -1 && options != c->options ) continue; if ( i == ROAR_DL_FN_REGFN ) { __fnreg_trigger_by_handler(&(__fnrefs[i][j]), ROAR_DL_FNUNREG); } else { __fnreg_trigger_by_reg(&(__fnrefs[i][j]), ROAR_DL_FNUNREG, i); } memset(&(__fnrefs[i][j]), 0, sizeof(__fnrefs[i][j])); __fnrefs[i][j].lhandle = NULL; } } return 0; } int roar_dl_unregister_fn(struct roar_dl_lhandle * lhandle) { return roar_dl_unregister_fn2(lhandle, -1, -1, NULL, (size_t)-1, -1, -1); } static inline int __load_plugin_any_get_api(struct roar_dl_librarypara * para, const char * appname, const char * appabi, const char * servicename, const char * serviceabi, int universal, struct roar_dl_service_api * api) { struct roar_dl_lhandle * lhandle = NULL; struct roar_dl_librarypara * mypara = NULL; char name[80]; int err; int ret; mypara = roar_dl_para_new(NULL, NULL, LIBROAR_DL_APPNAME, LIBROAR_DL_ABIVERSION); if ( mypara == NULL ) return -1; if ( serviceabi != NULL ) { snprintf(name, sizeof(name), "service-%s-%s", servicename, serviceabi); lhandle = roar_dl_open(name, ROAR_DL_FLAG_PLUGIN, 1, mypara); } if ( lhandle == NULL ) { snprintf(name, sizeof(name), "service-%s", servicename); lhandle = roar_dl_open(name, ROAR_DL_FLAG_PLUGIN, 1, mypara); } err = roar_error; roar_dl_para_unref(mypara); roar_error = err; if ( lhandle == NULL ) return -1; roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_INIT); ret = libroar_dl_service_get_api_real(para, appname, appabi, servicename, serviceabi, universal, api, 0); err = roar_error; roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_FREE); roar_dl_unref(lhandle); roar_error = err; return ret; } int libroar_dl_service_get_api_real(struct roar_dl_librarypara * para, const char * appname, const char * appabi, const char * servicename, const char * serviceabi, int universal, struct roar_dl_service_api * api, int retry) { const struct roar_dl_service * s; struct __fnregs * c = NULL; size_t i; int err; if ( servicename == NULL || serviceabi == NULL || api == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( para != NULL ) { if ( roar_dl_para_ref(para) == -1 ) return -1; } else { para = roar_dl_para_new(NULL, NULL, NULL, NULL); if ( para == NULL ) return -1; } memset(api, 0, sizeof(struct roar_dl_service_api)); for (i = 0; i < __MAX_FNREGS; i++) { c = &(__fnrefs[ROAR_DL_FN_SERVICE][i]); s = c->object; if ( c->lhandle == NULL ) continue; if ( c->subtype != ROAR_DL_SERVICE_SUBTYPE ) continue; if ( c->objectlen != ROAR_DL_SERVICE_SIZE ) continue; if ( c->version != ROAR_DL_SERVICE_VERSION ) continue; if ( !universal && s->appname == NULL ) continue; if ( universal == 2 && s->appname != NULL ) continue; if ( s->appname != NULL && !!strcmp(s->appname, appname) ) continue; if ( (s->appabi == NULL && appabi != NULL) || (s->appabi != NULL && appabi == NULL) || (s->appabi != NULL && appabi != NULL && !!strcmp(s->appabi, appabi) ) ) continue; if ( s->servicename == NULL || !!strcmp(s->servicename, servicename) ) continue; if ( s->serviceabi == NULL || !!strcmp(s->serviceabi, serviceabi) ) continue; if ( s->get_api == NULL ) continue; if ( roar_dl_ref(c->lhandle) != 0 ) continue; api->service = s; api->lhandle = c->lhandle; api->api = s->get_api(s, para); if ( api->api == NULL ) { err = roar_error; roar_dl_unref(c->lhandle); roar_dl_para_unref(para); api->lhandle = NULL; roar_error = err; return -1; } roar_dl_para_unref(para); return 0; } if ( retry ) { if ( __load_plugin_any_get_api(para, appname, appabi, servicename, serviceabi, universal, api) == 0 ) { roar_dl_para_unref(para); return 0; } } roar_dl_para_unref(para); roar_err_set(ROAR_ERROR_NOENT); return -1; } int libroar_dl_service_free_api_real(struct roar_dl_service_api * api) { if ( api == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } roar_dl_unref(api->lhandle); memset(api, 0, sizeof(struct roar_dl_service_api)); return 0; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/roarfloat.c�������������������������������������������������������������0000644�0001750�0001750�00000007400�12264733544�016261� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarfloat.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_LIBM #include <math.h> #endif union c4f { unsigned char c[4]; roarfloat32 f; }; roarfloat32 roar_ufloat32_build(const uint16_t mul, const uint16_t scale) { union c4f ret; ROAR_DBG("roar_ufloat32_build(mul=%u, scale=%u) = ?", (unsigned int)mul, (unsigned int)scale); ret.c[0] = (scale & 0xFF00) >> 8; ret.c[1] = (scale & 0x00FF) >> 0; ret.c[2] = (mul & 0xFF00) >> 8; ret.c[3] = (mul & 0x00FF) >> 0; return ret.f; } uint16_t roar_ufloat32_scale(const roarfloat32 f) { const union c4f p = {.f = f}; ROAR_DBG("roar_ufloat32_scale(f=?): p.c[] = {%u, %u, %u, %u}", (unsigned int)p.c[0], (unsigned int)p.c[1], (unsigned int)p.c[2], (unsigned int)p.c[3]); return (p.c[0] << 8) | p.c[1]; } uint16_t roar_ufloat32_mul(const roarfloat32 f) { const union c4f p = {.f = f}; return (p.c[2] << 8) | p.c[3]; } roarfloat32 roar_ufloat32_from_float(const float f) { uint16_t scale; if ( f < 0 ) return ROAR_UFLOAT32_NNAN; if ( f == 0 ) return ROAR_UFLOAT32_ZERO; if ( f > ROAR_UFLOAT32_MAX ) return ROAR_UFLOAT32_PINF; if ( f <= 1 ) { scale = ROAR_UFLOAT32_MAX; } else { scale = (float)ROAR_UFLOAT32_MAX/f; } ROAR_DBG("roar_ufloat32_from_float(f=%f): scale=%u", f, (unsigned int)scale); return roar_ufloat32_build(f*(float)scale, scale); } float roar_ufloat32_to_float (const roarfloat32 f) { float mul = roar_ufloat32_mul(f); float scale = roar_ufloat32_scale(f); ROAR_DBG("roar_ufloat32_to_float(f=?): mul=%f, scale=%f", mul, scale); if ( roar_float32_iszero(f) ) return 0; #ifdef INFINITY if ( roar_float32_isinf(f) ) return INFINITY; #endif #ifdef NAN if ( roar_float32_isnan(f) ) return NAN; #endif return mul/scale; } int roar_float32_iszero(const roarfloat32 f) { const union c4f p = {.f = f}; return p.c[2] == 0 && p.c[3] == 0; } int roar_float32_isinf(const roarfloat32 f) { const union c4f p = {.f = f}; if ( p.c[0] != 0 || p.c[1] != 0 ) return 0; if ( p.c[2] == 0x00 && p.c[3] == 0x01 ) { return 1; } else if ( p.c[2] == 0xFF && p.c[3] == 0xFF ) { return -1; } else { return 0; } } int roar_float32_isnan(const roarfloat32 f) { const union c4f p = {.f = f}; if ( p.c[0] != 0 || p.c[1] != 0 ) return 0; if ( p.c[2] == 0x7F && p.c[3] == 0xFF ) { return 1; } else if ( p.c[2] == 0x80 && p.c[3] == 0x00 ) { return -1; } else { return 0; } } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/roarx11.c���������������������������������������������������������������0000644�0001750�0001750�00000010313�12264733544�015562� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarx11.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" struct roar_x11_connection * roar_x11_connect(char * display) { #ifdef ROAR_HAVE_LIBX11 struct roar_libroar_config * config = roar_libroar_get_config(); struct roar_x11_connection * con; if ( display == NULL ) display = config->x11.display; if ( (con = roar_mm_malloc(sizeof(struct roar_x11_connection))) == NULL ) return NULL; if ( (con->display = XOpenDisplay(display)) == NULL ) { roar_mm_free(con); return NULL; } con->close = 1; return con; #else return NULL; #endif } struct roar_x11_connection * roar_x11_connect_display(_ROAR_X11_DISPLAY * display) { #ifdef ROAR_HAVE_LIBX11 struct roar_x11_connection * con; if ( display == NULL ) return NULL; if ( (con = roar_mm_malloc(sizeof(struct roar_x11_connection))) == NULL ) return NULL; con->close = 0; con->display = display; return con; #else return NULL; #endif } int roar_x11_disconnect(struct roar_x11_connection * con) { #ifdef ROAR_HAVE_LIBX11 int ret = 0; if ( con == NULL ) return -1; if ( con->close ) ret = XCloseDisplay(con->display); roar_mm_free(con); return ret; #else return -1; #endif } int roar_x11_flush(struct roar_x11_connection * con) { #ifdef ROAR_HAVE_LIBX11 if ( con == NULL ) return -1; return XFlush(con->display); #else return -1; #endif } int roar_x11_set_prop(struct roar_x11_connection * con, const char * key, const char * val) { #ifdef ROAR_HAVE_LIBX11 Atom a; if ( con == NULL ) return -1; a = XInternAtom(con->display, key, False); XChangeProperty(con->display, RootWindow(con->display, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) val, strlen(val)+1); return 0; #else return -1; #endif } int roar_x11_delete_prop(struct roar_x11_connection * con, const char * key) { #ifdef ROAR_HAVE_LIBX11 Atom a; if ( con == NULL ) return -1; a = XInternAtom(con->display, key, False); XDeleteProperty(con->display, RootWindow(con->display, 0), a); return 0; #else return -1; #endif } char * roar_x11_get_prop(struct roar_x11_connection * con, const char * key) { #ifdef ROAR_HAVE_LIBX11 unsigned long nitems; unsigned long nbytes_after; unsigned char * prop = NULL; char * ret = NULL; int actual_format; Atom actual_type; Atom a; a = XInternAtom(con->display, key, False); if ( XGetWindowProperty(con->display, RootWindow(con->display, 0), a, 0, 256, False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success ) { if ( prop != NULL ) XFree(prop); return NULL; } if ( prop == NULL ) return NULL; if (actual_type != XA_STRING) { XFree(prop); return NULL; } ret = roar_mm_malloc(nitems+1); memcpy(ret, prop, nitems); ret[nitems] = 0; XFree(prop); return ret; #else return NULL; #endif } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/scheduler.c�������������������������������������������������������������0000644�0001750�0001750�00000051404�12264733544�016251� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//scheduler.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define INIT_SIZE 8 #define MAX_PROTOS 16 struct protocol { const struct roar_keyval * para; ssize_t paralen; struct roar_dl_lhandle * lhandle; const struct roar_dl_proto * impl; }; struct roar_scheduler { size_t refc; int flags; enum roar_scheduler_strategy strategy; struct roar_scheduler_source ** sources; size_t sources_len; struct roar_vio_select * vios; size_t vios_len; struct roar_dl_fnreg callback; struct protocol protos[MAX_PROTOS]; }; static int __update_cpi_listen_client (struct roar_scheduler * sched, struct roar_scheduler_source * source); struct roar_scheduler * roar_scheduler_new(int flags, enum roar_scheduler_strategy strategy) { struct roar_scheduler * sched = roar_mm_malloc(sizeof(struct roar_scheduler)); if ( sched == NULL ) return NULL; if ( flags == ROAR_SCHEDULER_FLAG_DEFAULT ) flags = ROAR_SCHEDULER_FLAG_NONE; memset(sched, 0, sizeof(struct roar_scheduler)); sched->refc = 1; sched->flags = flags; sched->strategy = strategy; sched->sources = roar_mm_malloc(INIT_SIZE*sizeof(struct roar_scheduler_source *)); if ( sched->sources != NULL ) { sched->sources_len = INIT_SIZE; memset(sched->sources, 0, INIT_SIZE*sizeof(struct roar_scheduler_source *)); } sched->vios = roar_mm_malloc(sched->sources_len*sizeof(struct roar_vio_select)); if ( sched->vios != 0 ) sched->vios_len = sched->sources_len; return sched; } #define _CHKSCHED(extra) if ( sched == NULL || (extra) ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } int roar_scheduler_ref(struct roar_scheduler * sched) { _CHKSCHED(0); sched->refc++; return 0; } int roar_scheduler_unref(struct roar_scheduler * sched) { size_t i; _CHKSCHED(0); sched->refc--; if (sched->refc) return 0; for (i = 0; i < sched->sources_len; i++) if ( sched->sources[i] != NULL ) roar_scheduler_source_del(sched, sched->sources[i]); if ( sched->vios != NULL ) roar_mm_free(sched->vios); if ( sched->sources != NULL ) roar_mm_free(sched->sources); roar_mm_free(sched); return 0; } static void __delete_cpi_client(struct roar_scheduler * sched, struct roar_scheduler_source * cur, struct roar_dl_librarypara * para) { if ( cur->handle.cpi.impl->unset_proto != NULL ) cur->handle.cpi.impl->unset_proto(cur->handle.cpi.client, cur->vio, &(cur->handle.cpi.obuffer), &(cur->handle.cpi.userdata), cur->handle.cpi.protopara, cur->handle.cpi.protoparalen, para); roar_vio_close(cur->vio); cur->vio = NULL; if ( cur->handle.cpi.obuffer != NULL ) { roar_buffer_free(cur->handle.cpi.obuffer); cur->handle.cpi.obuffer = NULL; } if ( cur->handle.cpi.userdata != NULL ) { roar_mm_free(cur->handle.cpi.userdata); cur->handle.cpi.userdata = NULL; } roar_scheduler_source_del(sched, cur); } static int __flush_cpi_client(struct roar_scheduler * sched, struct roar_scheduler_source * cur, struct roar_dl_librarypara * para) { size_t len; ssize_t ret; void * buf; if ( roar_buffer_get_len(cur->handle.cpi.obuffer, &len) == -1 ) return 0; if ( roar_buffer_get_data(cur->handle.cpi.obuffer, &buf) == -1 ) return 0; if ( len != 0 ) { ret = roar_vio_write(cur->vio, buf, len); if ( ret < 1 ) return -1; } else { ret = len; } if ( ret == (ssize_t)len ) { if ( roar_buffer_next(&(cur->handle.cpi.obuffer)) == -1 ) return -1; } else { if ( roar_buffer_set_offset(cur->handle.cpi.obuffer, ret) == -1 ) return -1; } return 0; } static int __run_waits(struct roar_scheduler * sched) { struct roar_scheduler_source * cur; size_t i; int ret = -1; for (i = 0; ret == -1 && i < sched->sources_len; i++) { if ( (cur = sched->sources[i]) == NULL ) continue; switch (cur->type) { case ROAR_SCHEDULER_PLUGIN: ret = roar_dl_appsched_trigger(cur->lhandle, ROAR_DL_APPSCHED_WAIT); break; case ROAR_SCHEDULER_PLUGINCONTAINER: ret = roar_plugincontainer_appsched_trigger(cur->handle.container, ROAR_DL_APPSCHED_WAIT); break; #ifndef DEBUG default: /* noop */ break; #endif } } return ret; } // what to do?: // 0. get all VIOs. // 1. get timeout or use internal default. // 2. run roar_vio_select(). // 3. send all events based on results. // 4. send UPDATE to all plugins and containers. int roar_scheduler_iterate(struct roar_scheduler * sched) { enum roar_scheduler_strategy strategy; struct roar_vio_selecttv timeout = {8, 0}; // default: 8 sec. Just a random value. struct roar_scheduler_source * cur, * new_client; struct roar_dl_librarypara * para; struct roar_dl_lhandle * lhandle; ssize_t ret; size_t i; int have_timeout = 0; size_t todo = 0, vios = 0; int tmp; _CHKSCHED(0); strategy = sched->strategy; if ( strategy == ROAR_SCHEDULER_STRATEGY_DEFAULT ) strategy = ROAR_SCHEDULER_STRATEGY_SELECTORWAIT; if ( sched->vios == NULL || sched->vios_len < sched->sources_len ) { if ( sched->vios != NULL ) { roar_mm_free(sched->vios); sched->vios = NULL; sched->vios_len = 0; } sched->vios = roar_mm_malloc(sched->sources_len*sizeof(struct roar_vio_select)); if ( sched->vios != NULL ) sched->vios_len = sched->sources_len; } // error from roar_mm_malloc() is still set. if ( sched->vios == NULL ) return -1; memset(sched->vios, 0, sched->vios_len*sizeof(struct roar_vio_select)); for (i = 0; i < sched->vios_len; i++) sched->vios[i].eventsq = ROAR_VIO_SELECT_NO_RETEST; for (i = 0; i < sched->sources_len; i++) { if ( (cur = sched->sources[i]) == NULL ) continue; switch (cur->type) { case ROAR_SCHEDULER_VIO: ROAR_VIO_SELECT_SETVIO(&(sched->vios[i]), cur->vio, cur->handle.eventsq); todo++; vios++; break; case ROAR_SCHEDULER_TIMEOUT: timeout = cur->handle.timeout; have_timeout = 1; todo++; break; case ROAR_SCHEDULER_CPI_LISTEN: if ( cur->flags & ROAR_SCHEDULER_FLAG_STUB ) __update_cpi_listen_client(sched, cur); if ( !(cur->flags & ROAR_SCHEDULER_FLAG_STUB) ) { ROAR_VIO_SELECT_SETVIO(&(sched->vios[i]), cur->vio, ROAR_VIO_SELECT_READ); todo++; vios++; } break; case ROAR_SCHEDULER_CPI_CLIENT: if ( cur->flags & ROAR_SCHEDULER_FLAG_STUB ) __update_cpi_listen_client(sched, cur); if ( !(cur->flags & ROAR_SCHEDULER_FLAG_STUB) ) { tmp = 0; if ( cur->handle.cpi.impl->status != NULL ) { if ( cur->lhandle != NULL ) roar_dl_context_restore(cur->lhandle); para = roar_dl_getpara(cur->lhandle); if ( cur->handle.cpi.impl->status(cur->handle.cpi.client, cur->vio, &(cur->handle.cpi.obuffer), &(cur->handle.cpi.userdata), cur->handle.cpi.protopara, cur->handle.cpi.protoparalen, para) & ROAR_DL_PROTO_STATUS_RX_READY ) tmp |= ROAR_VIO_SELECT_READ; if ( para != NULL ) roar_dl_para_unref(para); if ( cur->lhandle != NULL ) roar_dl_context_store(cur->lhandle); } else { tmp |= ROAR_VIO_SELECT_READ; } if ( sched->sources[i]->handle.cpi.obuffer != NULL ) tmp |= ROAR_VIO_SELECT_WRITE; ROAR_VIO_SELECT_SETVIO(&(sched->vios[i]), sched->sources[i]->vio, tmp); todo++; vios++; } break; case ROAR_SCHEDULER_PLUGIN: case ROAR_SCHEDULER_PLUGINCONTAINER: todo++; break; #ifndef DEBUG default: /* noop */ break; #endif } } if (!todo) { roar_err_set(ROAR_ERROR_NOENT); return 0; } if ( strategy == ROAR_SCHEDULER_STRATEGY_WAITORSELECT || strategy == ROAR_SCHEDULER_STRATEGY_WAIT ) { ret = __run_waits(sched); if ( ret == 0 || strategy == ROAR_SCHEDULER_STRATEGY_WAIT ) ret = 1; } else { ret = -1; } if ( ret == -1 && !(strategy == ROAR_SCHEDULER_STRATEGY_SELECTORWAIT && vios == 0) ) { ret = roar_vio_select(sched->vios, sched->vios_len, &timeout, NULL); } if ( ret < 0 && strategy == ROAR_SCHEDULER_STRATEGY_SELECTORWAIT ) { ret = __run_waits(sched); if ( ret == 0 ) ret = 1; if ( ret == -1 && vios == 0 ) { if ( sched->flags & ROAR_SCHEDULER_FLAG_KEEP_RUNNING ) { ret = roar_vio_select(sched->vios, sched->vios_len, &timeout, NULL); } else { return 0; } } } if ( ret == -1 ) return -1; if ( ret == 0 && !have_timeout ) return 1; for (i = 0; i < sched->sources_len; i++) { if ( (cur = sched->sources[i]) == NULL ) continue; switch (cur->type) { case ROAR_SCHEDULER_VIO: if ( sched->vios[i].eventsa ) if ( cur->cb != NULL ) cur->cb(sched->sources[i], sched->sources[i]->userdata, sched->vios[i].eventsa); break; case ROAR_SCHEDULER_TIMEOUT: if ( ret == 0 ) if ( cur->cb != NULL ) cur->cb(sched->sources[i], sched->sources[i]->userdata, 0); break; case ROAR_SCHEDULER_PLUGIN: roar_dl_appsched_trigger(cur->lhandle, ROAR_DL_APPSCHED_UPDATE); break; case ROAR_SCHEDULER_PLUGINCONTAINER: roar_plugincontainer_appsched_trigger(cur->handle.container, ROAR_DL_APPSCHED_UPDATE); break; case ROAR_SCHEDULER_CPI_LISTEN: if ( !sched->vios[i].eventsa ) continue; if ( cur->flags & ROAR_SCHEDULER_FLAG_STUB ) continue; if ( cur->cb != NULL ) cur->cb(sched->sources[i], sched->sources[i]->userdata, sched->vios[i].eventsa); new_client = roar_mm_malloc(sizeof(struct roar_scheduler_source)); if ( new_client == NULL ) continue; memcpy(new_client, cur, sizeof(struct roar_scheduler_source)); new_client->type = ROAR_SCHEDULER_CPI_CLIENT; new_client->flags = ROAR_SCHEDULER_FLAG_FREE; new_client->vio = roar_mm_malloc(sizeof(struct roar_vio_calls)); if ( new_client->vio == NULL ) { roar_mm_free(new_client); continue; } if ( roar_vio_accept(new_client->vio, cur->vio) == -1 ) { roar_mm_free(new_client->vio); roar_mm_free(new_client); continue; } new_client->vio->flags |= ROAR_VIO_FLAGS_FREESELF; if ( roar_scheduler_source_add(sched, new_client) == -1 ) { roar_vio_close(new_client->vio); roar_mm_free(new_client); } roar_vio_unref(new_client->vio); if ( new_client->cb != NULL ) new_client->cb(new_client, new_client->userdata, 0); if ( cur->handle.cpi.impl->set_proto != NULL ) { lhandle = new_client->lhandle; para = roar_dl_getpara(lhandle); if ( lhandle != NULL ) roar_dl_context_restore(lhandle); new_client->handle.cpi.impl->set_proto(new_client->handle.cpi.client, new_client->vio, &(new_client->handle.cpi.obuffer), &(new_client->handle.cpi.userdata), new_client->handle.cpi.protopara, new_client->handle.cpi.protoparalen, para); if ( lhandle != NULL ) roar_dl_context_store(lhandle); if ( para != NULL ) roar_dl_para_unref(para); } break; case ROAR_SCHEDULER_CPI_CLIENT: if ( !sched->vios[i].eventsa ) continue; if ( cur->flags & ROAR_SCHEDULER_FLAG_STUB ) continue; if ( cur->cb != NULL ) cur->cb(sched->sources[i], sched->sources[i]->userdata, sched->vios[i].eventsa); lhandle = cur->lhandle; para = roar_dl_getpara(lhandle); tmp = 0; if ( sched->vios[i].eventsa & ROAR_VIO_SELECT_WRITE ) { if ( cur->handle.cpi.impl->flush != NULL ) { if ( lhandle != NULL ) roar_dl_context_restore(lhandle); cur->handle.cpi.impl->flush(cur->handle.cpi.client, cur->vio, &(cur->handle.cpi.obuffer), &(cur->handle.cpi.userdata), cur->handle.cpi.protopara, cur->handle.cpi.protoparalen, para); if ( lhandle != NULL ) roar_dl_context_store(lhandle); } else { tmp = __flush_cpi_client(sched, cur, para); } if ( tmp == 0 && cur->handle.cpi.obuffer == NULL && cur->handle.cpi.impl->flushed != NULL ) { if ( lhandle != NULL ) roar_dl_context_restore(lhandle); if ( cur->handle.cpi.impl->flushed(cur->handle.cpi.client, cur->vio, &(cur->handle.cpi.obuffer), &(cur->handle.cpi.userdata), cur->handle.cpi.protopara, cur->handle.cpi.protoparalen, para) == -1 ) tmp = -1; if ( lhandle != NULL ) roar_dl_context_store(lhandle); } } if ( sched->vios[i].eventsa & ROAR_VIO_SELECT_READ ) { if ( cur->handle.cpi.impl->handle != NULL ) { if ( lhandle != NULL ) roar_dl_context_restore(lhandle); if ( cur->handle.cpi.impl->handle(cur->handle.cpi.client, cur->vio, &(cur->handle.cpi.obuffer), &(cur->handle.cpi.userdata), cur->handle.cpi.protopara, cur->handle.cpi.protoparalen, para) == -1 ) { tmp = -1; } if ( lhandle != NULL ) roar_dl_context_store(lhandle); } } if ( tmp == -1 ) { if ( lhandle != NULL ) roar_dl_context_restore(lhandle); __delete_cpi_client(sched, cur, para); if ( lhandle != NULL ) roar_dl_context_store(lhandle); } if ( para != NULL ) roar_dl_para_unref(para); break; #ifndef DEBUG default: /* noop */ break; #endif } } return 1; } int roar_scheduler_run(struct roar_scheduler * sched) { int ret; _CHKSCHED(0); while ((ret = roar_scheduler_iterate(sched)) > 0); return ret; } static int __cpi_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle) { const struct roar_dl_proto * impl = object; struct roar_scheduler * sched = userdata; struct roar_dl_librarypara * para; size_t i; (void)fn, (void)subtype, (void)version, (void)options; if ( sched == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( objectlen != ROAR_DL_PROTO_SIZE ) { ROAR_WARN("__cpi_callback(*): Library %p tries to register protocol with bad object length.", lhandle); roar_err_set(ROAR_ERROR_BADLIB); return -1; } switch (action) { case ROAR_DL_FNREG: for (i = 0; i < MAX_PROTOS; i++) { if ( sched->protos[i].impl == NULL ) { memset(&(sched->protos[i]), 0, sizeof(sched->protos[i])); sched->protos[i].para = NULL; sched->protos[i].paralen = -1; sched->protos[i].lhandle = lhandle; sched->protos[i].impl = impl; return 0; } } break; case ROAR_DL_FNUNREG: for (i = 0; i < sched->sources_len; i++) { if ( sched->sources[i] == NULL ) continue; if ( sched->sources[i]->type != ROAR_SCHEDULER_CPI_LISTEN && sched->sources[i]->type != ROAR_SCHEDULER_CPI_CLIENT ) continue; if ( sched->sources[i]->handle.cpi.proto != impl->proto ) continue; para = roar_dl_getpara(lhandle); if ( lhandle != NULL ) roar_dl_context_restore(lhandle); __delete_cpi_client(sched, sched->sources[i], para); if ( lhandle != NULL ) roar_dl_context_store(lhandle); if ( para != NULL ) roar_dl_para_unref(para); } for (i = 0; i < MAX_PROTOS; i++) { if ( sched->protos[i].impl != NULL && sched->protos[i].lhandle == lhandle ) { memset(&(sched->protos[i]), 0, sizeof(sched->protos[i])); sched->protos[i].impl = NULL; } } return 0; break; } roar_err_set(ROAR_ERROR_NOSPC); return -1; } static int __update_cpi_service (struct roar_scheduler * sched, struct roar_scheduler_source * source, int del) { if ( del ) { return roar_dl_unregister_fn2(ROAR_DL_HANDLE_LIBROAR, ROAR_DL_FN_REGFN, ROAR_DL_FNREG_SUBTYPE, &(sched->callback), sizeof(sched->callback), ROAR_DL_FNREG_VERSION, ROAR_DL_FNREG_OPT_NONE); } sched->callback.fn = ROAR_DL_FN_PROTO; sched->callback.subtype = ROAR_DL_PROTO_SUBTYPE; sched->callback.version = ROAR_DL_PROTO_VERSION; sched->callback.callback = __cpi_callback; sched->callback.userdata = sched; ROAR_DL_RFNREG(ROAR_DL_HANDLE_LIBROAR, sched->callback); return -1; } static int __update_cpi_listen_client (struct roar_scheduler * sched, struct roar_scheduler_source * source) { size_t i; ROAR_DBG("__update_cpi_listen_client(sched=%p, source=%p): proto=%i, impl=%p", sched, source, source->handle.cpi.proto, source->handle.cpi.impl); if ( source->handle.cpi.proto < 1 && source->handle.cpi.impl != NULL ) source->handle.cpi.proto = source->handle.cpi.impl->proto; if ( source->handle.cpi.proto > 0 && source->handle.cpi.impl == NULL ) { for (i = 0; i < MAX_PROTOS; i++) { if ( sched->protos[i].impl == NULL ) continue; ROAR_DBG("__update_cpi_listen_client(sched=%p, source=%p): proto=%i<->%i", sched, source, sched->protos[i].impl->proto, source->handle.cpi.proto); if ( sched->protos[i].impl->proto != source->handle.cpi.proto ) continue; source->handle.cpi.impl = sched->protos[i].impl; if ( source->lhandle == NULL && sched->protos[i].lhandle != NULL ) if ( roar_dl_ref(sched->protos[i].lhandle) == 0 ) source->lhandle = sched->protos[i].lhandle; break; } } if ( source->handle.cpi.proto > 0 ) { source->flags |= ROAR_SCHEDULER_FLAG_STUB; if ( source->handle.cpi.impl == NULL ) return 0; source->flags -= ROAR_SCHEDULER_FLAG_STUB; return 0; } roar_err_set(ROAR_ERROR_INVAL); return -1; } int roar_scheduler_source_add(struct roar_scheduler * sched, struct roar_scheduler_source * source) { size_t i; struct roar_scheduler_source ** next = NULL; int err; _CHKSCHED(source == NULL); ROAR_DBG("roar_scheduler_source_add(sched=%p, source=%p): proto=%i, impl=%p", sched, source, source->handle.cpi.proto, source->handle.cpi.impl); for (i = 0; i < sched->sources_len; i++) { if ( sched->sources[i] != NULL ) continue; next = &(sched->sources[i]); break; } if ( next == NULL ) { // TODO: re-allocate some space here. roar_err_set(ROAR_ERROR_NOSPC); return -1; } if ( source->flags == ROAR_SCHEDULER_FLAG_DEFAULT ) source->flags = ROAR_SCHEDULER_FLAG_NONE; switch (source->type) { case ROAR_SCHEDULER_CPI_LISTEN: case ROAR_SCHEDULER_CPI_CLIENT: if ( __update_cpi_listen_client(sched, source) == -1 ) return -1; break; case ROAR_SCHEDULER_CPI_SERVICE: if ( __update_cpi_service(sched, source, 0) == -1 ) return -1; break; #ifndef DEBUG default: /* noop */ break; #endif } if ( source->lhandle != NULL ) if ( roar_dl_ref(source->lhandle) == -1 ) return -1; if ( source->vio != NULL ) { if ( roar_vio_ref(source->vio) == -1 ) { err = roar_error; if ( source->lhandle != NULL ) roar_dl_unref(source->lhandle); roar_err_set(err); return -1; } } if ( source->type == ROAR_SCHEDULER_PLUGINCONTAINER ) { if ( roar_plugincontainer_ref(source->handle.container) == -1 ) { err = roar_error; if ( source->lhandle != NULL ) roar_dl_unref(source->lhandle); if ( source->vio != NULL ) roar_vio_unref(source->vio); roar_err_set(err); return -1; } } *next = source; return 0; } int roar_scheduler_source_del(struct roar_scheduler * sched, struct roar_scheduler_source * source) { size_t i; struct roar_scheduler_source ** next = NULL; _CHKSCHED(source == NULL); for (i = 0; i < sched->sources_len; i++) { if ( sched->sources[i] != source ) continue; next = &(sched->sources[i]); break; } if ( next == NULL ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } switch (source->type) { case ROAR_SCHEDULER_PLUGINCONTAINER: roar_plugincontainer_ref(source->handle.container); break; case ROAR_SCHEDULER_CPI_SERVICE: if ( __update_cpi_service(sched, source, 1) == -1 ) return -1; break; #ifndef DEBUG default: /* noop */ break; #endif } if ( source->lhandle != NULL ) roar_dl_unref(source->lhandle); if ( source->vio != NULL ) roar_vio_unref(source->vio); if ( source->flags & ROAR_SCHEDULER_FLAG_FREE ) roar_mm_free(source); *next = NULL; return 0; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/serverinfo.c������������������������������������������������������������0000644�0001750�0001750�00000023052�12264733544�016453� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//serverinfo.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" // include for uname() used by roar_library_info() #ifdef ROAR_HAVE_UNAME #include <sys/utsname.h> #endif struct ie { int type; size_t len; const char * buf; }; struct roar_server_info * roar_server_info(struct roar_connection * con) { struct roar_server_info * ret; struct roar_message mes; uint16_t * d16; char * data = NULL; memset(&mes, 0, sizeof(mes)); mes.cmd = ROAR_CMD_SERVER_INFO; mes.datalen = 2*2; d16 = (uint16_t*)mes.data; d16[0] = ROAR_HOST2NET16(0); // version d16[1] = ROAR_HOST2NET16(ROAR_IT_SERVER); if ( roar_req(con, &mes, &data) != 0 ) return NULL; if ( mes.cmd != ROAR_CMD_OK ) return NULL; ret = roar_server_info_from_mes(&mes, data); if ( data != NULL ) roar_mm_free(data); return ret; } #ifdef ROAR_HAVE_GETHOSTID #define _HOSTID_BUFLEN 64 #else #define _HOSTID_BUFLEN 0 #endif struct roar_server_info * roar_library_info(void) { struct roar_server_info * ret = roar_mm_malloc(sizeof(struct roar_server_info) + _HOSTID_BUFLEN); #ifdef ROAR_HAVE_UNAME static struct utsname utsname; static int utsname_inited = 0; #endif #ifdef ROAR_HAVE_GETHOSTID long hostid; char * hostidbuf = ((void*)ret) + sizeof(*ret); #endif if ( ret == NULL ) return NULL; memset(ret, 0, sizeof(struct roar_server_info)); #if 0 + const char * version; X const char * location; X const char * description; X const char * contact; X const char * serial; X const char * address; X const char * uiurl; const char * hostid; + const char * license; + const char * build; + struct { + const char * sysname; + const char * release; + const char * nodename; + const char * machine; + } un; #endif if ( ROAR_VERSION_DISTRIBUTION_STRING[0] == 0 ) { ret->version = "libroar/" ROAR_VERSION_STRING " <" ROAR_DEV_VENDOR_STRING ">"; } else { ret->version = "libroar/" ROAR_VERSION_STRING " <" ROAR_DEV_VENDOR_STRING "> (" ROAR_VERSION_DISTRIBUTION_STRING ")"; } #ifdef ROAR_HAVE_GETHOSTID hostid = gethostid(); roar_random_salt_nonce(&hostid, sizeof(hostid)); snprintf(hostidbuf, _HOSTID_BUFLEN, sizeof(long) == 8 ? "0x%.16lx" : "0x%.8lx", hostid); ret->hostid = hostidbuf; #endif ret->license = ROAR_LICENSE_GPLv3_0; ret->build = ROAR_BUILD_STAMP; #ifdef ROAR_HAVE_UNAME if ( !utsname_inited ) if ( uname(&utsname) == 0 ) { utsname_inited = 1; roar_random_salt_nonce(&utsname, sizeof(utsname)); } if ( utsname_inited ) { ret->un.sysname = utsname.sysname; ret->un.release = utsname.release; ret->un.nodename = utsname.nodename; ret->un.machine = utsname.machine; } #endif #ifdef ROAR_HAVE_GETVERSIONEX ret->un.sysname = "Windows"; #endif return ret; } int roar_server_info_free(struct roar_server_info * info) { if ( info == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } roar_mm_free(info); return 0; } #define _add(t, m) do { if ( info->m != NULL && (sl = strlen(info->m)) != 0 ) { iebuf[idx].type = (t); iebuf[idx].len = sl; iebuf[idx].buf = (info->m); idx++; needlen += 4 + sl; } } while (0) int roar_server_info_to_mes(struct roar_message * mes, struct roar_server_info * info, void ** data) { size_t needlen = 4; size_t sl; int idx = 0; struct ie iebuf[sizeof(struct roar_server_info)/sizeof(char*)]; uint16_t * d16, * dptr; char * textpart; int i; char * mesdata; if ( mes == NULL || info == NULL ) return -1; _add(ROAR_ITST_VERSION, version); _add(ROAR_ITST_LOCATION, location); _add(ROAR_ITST_DESCRIPTION, description); _add(ROAR_ITST_CONTACT, contact); _add(ROAR_ITST_SERIAL, serial); _add(ROAR_ITST_ADDRESS, address); _add(ROAR_ITST_UIURL, uiurl); _add(ROAR_ITST_LICENSE, license); _add(ROAR_ITST_HOSTID, hostid); _add(ROAR_ITST_BUILD, build); _add(ROAR_ITST_UN_SYSNAME, un.sysname); _add(ROAR_ITST_UN_RELEASE, un.release); _add(ROAR_ITST_UN_NODENAME, un.nodename); _add(ROAR_ITST_UN_MACHINE, un.machine); if ( needlen > LIBROAR_BUFFER_MSGDATA ) { if ( data == NULL ) return -1; mesdata = roar_mm_malloc(needlen); if ( mesdata == NULL ) return -1; *data = mesdata; } else { mesdata = mes->data; } memset(mes, 0, sizeof(struct roar_message)); mes->datalen = needlen; d16 = (uint16_t*)mesdata; mesdata[0] = 0; // version mesdata[1] = 0; // reserved d16[1] = ROAR_HOST2NET16(idx); dptr = &(d16[2]); for (i = 0; i < idx; i++) { dptr[0] = ROAR_HOST2NET16(iebuf[i].type & 0xFF); dptr[1] = ROAR_HOST2NET16(iebuf[i].len); dptr += 2; } textpart = mesdata + (4 + 4*idx); for (i = 0; i < idx; i++) { memcpy(textpart, iebuf[i].buf, iebuf[i].len); textpart += iebuf[i].len; } return 0; } struct roar_server_info * roar_server_info_from_mes(struct roar_message * mes, void * data) { struct ie iebuf[sizeof(struct roar_server_info)/sizeof(char*)]; struct ie * ieptr; struct roar_server_info * ret = NULL; uint16_t * d16, * dptr; size_t idx; size_t i; size_t needlen = 4; char * textpart; char * textbuf; const char ** tptr; char * mesdata; ROAR_DBG("roar_server_info(mes=%p{.datalen=%llu) = ?", mes, (long long unsigned int)mes->datalen); if ( mes == NULL ) return NULL; if ( data == NULL ) { mesdata = mes->data; } else { mesdata = data; } memset(iebuf, 0, sizeof(iebuf)); ROAR_DBG("roar_server_info(mes=%p) = ?", mes); // some basic texts like version: if ( mes->datalen < needlen ) return NULL; ROAR_DBG("roar_server_info(mes=%p) = ?", mes); if ( mesdata[0] != 0 ) /* version */ return NULL; ROAR_DBG("roar_server_info(mes=%p) = ?", mes); if ( mesdata[1] != 0 ) /* reserved */ return NULL; ROAR_DBG("roar_server_info(mes=%p) = ?", mes); d16 = (uint16_t*)mesdata; idx = ROAR_NET2HOST16(d16[1]); ROAR_DBG("roar_server_info(mes=%p): idx=%i", mes, idx); // return error if our index buffer is too short. if ( idx > (sizeof(iebuf)/sizeof(*iebuf)) ) return NULL; ROAR_DBG("roar_server_info(mes=%p) = ?", mes); ROAR_DBG("roar_server_info(mes=%p): needlen=%llu", mes, (long long unsigned int)needlen); needlen += 4*idx; // recheck if we have a complet index. if ( mes->datalen < needlen ) return NULL; ROAR_DBG("roar_server_info(mes=%p) = ?", mes); d16 = (uint16_t*)mesdata; dptr = &(d16[2]); textpart = mesdata + (4 + 4*idx); ROAR_DBG("roar_server_info(mes=%p): needlen=%llu", mes, (long long unsigned int)needlen); for (i = 0; i < idx; i++) { iebuf[i].type = ROAR_NET2HOST16(dptr[0]) & 0xFF; iebuf[i].len = ROAR_NET2HOST16(dptr[1]); iebuf[i].buf = textpart; needlen += iebuf[i].len; textpart += iebuf[i].len; dptr += 2; ROAR_DBG("roar_server_info(mes=%p): iebuf[i]={.len=%llu,...}", mes, (long long unsigned int)iebuf[i].len); } ROAR_DBG("roar_server_info(mes=%p): needlen=%llu", mes, (long long unsigned int)needlen); // recheck if we have all the data... if ( mes->datalen < needlen ) return NULL; ROAR_DBG("roar_server_info(mes=%p) = ?", mes); // alloc the needed space. this can be reduced in future to the actual needed value. ret = roar_mm_malloc(2*sizeof(struct roar_server_info) + mes->datalen); if ( ret == NULL ) return NULL; ROAR_DBG("roar_server_info(mes=%p) = ?", mes); // for the size see the alloc call above. memset(ret, 0, 2*sizeof(struct roar_server_info) + mes->datalen); textbuf = (char*)ret + sizeof(struct roar_server_info); for (i = 0; i < idx; i++) { ieptr = &(iebuf[i]); // ignore empty fields if ( ieptr->len == 0 ) continue; if ( ieptr->len == 1 && ieptr->buf[0] == 0 ) continue; #define _ck(TYPE,member) case TYPE: tptr = &(ret->member); break; switch (ieptr->type) { _ck(ROAR_ITST_VERSION, version); _ck(ROAR_ITST_LOCATION, location); _ck(ROAR_ITST_DESCRIPTION, description); _ck(ROAR_ITST_CONTACT, contact); _ck(ROAR_ITST_SERIAL, serial); _ck(ROAR_ITST_ADDRESS, address); _ck(ROAR_ITST_UIURL, uiurl); _ck(ROAR_ITST_HOSTID, hostid); _ck(ROAR_ITST_LICENSE, license); _ck(ROAR_ITST_BUILD, build); _ck(ROAR_ITST_UN_SYSNAME, un.sysname); _ck(ROAR_ITST_UN_RELEASE, un.release); _ck(ROAR_ITST_UN_NODENAME, un.nodename); _ck(ROAR_ITST_UN_MACHINE, un.machine); default: continue; break; } #undef _ck *tptr = textbuf; memcpy(textbuf, ieptr->buf, ieptr->len); textbuf += ieptr->len; *textbuf = 0; // set \0 textbuf++; } ROAR_DBG("roar_server_info(mes=%p) = %p", mes, ret); return ret; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/simple.c����������������������������������������������������������������0000644�0001750�0001750�00000012635�12264733544�015567� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//simple.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static int roar_simple_stream_obj (struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, const char * server, int dir, const char * name, int mixer); int roar_simple_connect (struct roar_connection * con, const char * server, const char * name) { return roar_simple_connect2(con, server, name, 0, 0); } int roar_simple_connect2(struct roar_connection * con, const char * server, const char * name, int flags, uint_least32_t timeout) { ROAR_DBG("roar_simple_connect(*): trying to connect..."); if ( roar_connect(con, server, flags, timeout) == -1 ) { ROAR_DBG("roar_simple_connect(*): roar_connect() faild: %s", roar_errorstring); return -1; } if ( roar_identify(con, name) == -1 ) { ROAR_DBG("roar_simple_connect(*): roar_identify() faild: %s", roar_errorstring); return -1; } if ( roar_auth(con) == -1 ) { ROAR_DBG("roar_simple_connect(*): roar_auth() faild: %s", roar_errorstring); return -1; } return 0; } static int roar_simple_stream_obj (struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, const char * server, int dir, const char * name, int mixer) { struct roar_connection con; int ret; int safe_error; roar_debug_warn_sysio("roar_simple_stream_obj", NULL, NULL); if ( roar_simple_connect(&con, server, name) == -1 ) { ROAR_DBG("roar_simple_stream_obj(*): roar_simple_connect() faild!"); ROAR_ERR("roar_simple_stream_obj(*): Can not connect to server"); return -1; } if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) { safe_error = roar_error; roar_disconnect(&con); roar_err_set(safe_error); return -1; } if ( roar_stream_connect(&con, s, dir, mixer) == -1 ) { safe_error = roar_error; roar_disconnect(&con); roar_err_set(safe_error); return -1; } if ( roar_stream_exec(&con, s) == -1 ) { safe_error = roar_error; roar_disconnect(&con); roar_err_set(safe_error); return -1; } roar_libroar_nowarn(); if ( (ret = roar_get_connection_fh(&con)) == -1 ) { safe_error = roar_error; roar_libroar_warn(); roar_disconnect(&con); roar_err_set(safe_error); return -1; } roar_libroar_warn(); if ( dir == ROAR_DIR_PLAY ) { (void)ROAR_SHUTDOWN(ret, SHUT_RD); } else if ( dir == ROAR_DIR_MONITOR || dir == ROAR_DIR_RECORD ) { (void)ROAR_SHUTDOWN(ret, SHUT_WR); } return ret; } int roar_simple_new_stream_attachexeced_obj (struct roar_connection * con, struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, int dir, int mixer) { int fh; if ( (fh = roar_simple_stream_obj(s, rate, channels, bits, codec, roar_get_connection_server(con), dir, "libroar temp stream", mixer)) == -1 ) return -1; if ( roar_stream_attach_simple(con, s, roar_get_clientid(con)) == -1 ) { #ifdef ROAR_HAVE_IO_POSIX close(fh); #endif /* no else as we return -1 anyway */ return -1; } s->fh = fh; return fh; } int roar_simple_play_file(const char * file, const char * server, const char * name) { roar_vs_t * vss; int err; vss = roar_vs_new_from_file(server, name, file, &err); if ( vss == NULL ) { roar_err_set(err); return -1; } if ( roar_vs_run(vss, &err) == -1 ) { roar_vs_close(vss, ROAR_VS_TRUE, NULL); roar_err_set(err); return -1; } roar_vs_sync(vss, ROAR_VS_WAIT, NULL); roar_vs_close(vss, ROAR_VS_FALSE, NULL); return 0; } int roar_simple_connect_virtual(struct roar_connection * con, struct roar_stream * s, int parent, int dir) { struct roar_stream parent_stream; if ( con == NULL || s == NULL || parent < 0 ) return -1; if ( dir == -1 ) { if ( roar_get_stream(con, &parent_stream, parent) == -1 ) return -1; if ( (dir = roar_stream_get_dir(&parent_stream)) == -1 ) return -1; } if ( roar_stream_set_rel_id(s, parent) == -1 ) return -1; if ( roar_stream_connect(con, s, dir, -1) == -1 ) return -1; if ( roar_stream_set_flags(con, s, ROAR_FLAG_VIRTUAL, ROAR_SET_FLAG) == -1 ) { roar_kick(con, ROAR_OT_STREAM, roar_stream_get_id(s)); return -1; } return 0; } //ll ���������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/slp.c�������������������������������������������������������������������0000644�0001750�0001750�00000013613�12264733545�015072� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//slp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #if defined(ROAR_HAVE_LIBSLP) && defined(ROAR_HAVE_TIME) #define _CAN_OPERATE #endif SLPBoolean roar_slp_url_callback(SLPHandle hslp, const char * srvurl, unsigned short lifetime, SLPError errcode, void * cookie) { #ifdef _CAN_OPERATE struct roar_slp_cookie * self = cookie; (void)hslp; ROAR_DBG("roar_slp_url_callback(*) = ?"); if (errcode == SLP_OK || errcode == SLP_LAST_CALL) { self->callbackerr = SLP_OK; if ( srvurl == NULL ) /* hu? */ return SLP_TRUE; if ( self->matchcount == ROAR_SLP_MAX_MATCHES ) return SLP_FALSE; strncpy(self->match[self->matchcount].url, srvurl, ROAR_SLP_MAX_URL_LEN); self->match[self->matchcount].url[ROAR_SLP_MAX_URL_LEN-1] = 0; self->match[self->matchcount].tod = time(NULL); self->match[self->matchcount].tod += lifetime; self->matchcount++; } else { self->callbackerr = errcode; } /* return SLP_TRUE because we want to be called again */ /* if more services were found */ return SLP_TRUE; #else return SLP_FALSE; #endif } int roar_slp_search (struct roar_slp_cookie * cookie, char * type) { #ifdef _CAN_OPERATE SLPError err; SLPHandle hslp; ROAR_DBG("roar_slp_search(cookie=%p, type='%s') = ?", cookie, type); if ( cookie->search != NULL ) /* currently only non-search filter mode supported */ return -1; err = SLPOpen("en", SLP_FALSE, &hslp); if (err != SLP_OK) { return -1; } ROAR_DBG("roar_slp_search(*) = ?"); err = SLPFindSrvs(hslp, type, 0, /* use configured scopes */ 0, /* no attr filter */ roar_slp_url_callback, cookie); ROAR_DBG("roar_slp_search(*) = ?"); /* err may contain an error code that occurred as the slp library */ /* _prepared_ to make the call. */ if (err != SLP_OK) { return -1; } /* callbackerr may contain an error code (that was assigned through */ /* the callback cookie) that occurred as slp packets were sent on */ /* the wire */ if (cookie->callbackerr != SLP_OK) { return -1; } ROAR_DBG("roar_slp_search(*) = ?"); /* Now that we're done using slp, close the slp handle */ //SLPClose(hslp); ROAR_DBG("roar_slp_search(*) = ?"); return 0; #else return -1; #endif } int roar_slp_cookie_init (struct roar_slp_cookie * cookie, struct roar_slp_search * search) { if ( cookie == NULL ) return -1; memset(cookie, 0, sizeof(struct roar_slp_cookie)); cookie->search = search; return 0; } char * roar_slp_find_roard (int nocache) { static char addr[80]; if ( roar_slp_find_roard_r(addr, sizeof(addr), nocache) == -1 ) return NULL; return addr; } int roar_slp_find_roard_r (char * addr, size_t len, int nocache) { #ifdef _CAN_OPERATE static struct roar_slp_match cache = {"", 0}; struct roar_slp_cookie cookie; int offset = 0; char * url; ROAR_DBG("roar_slp_find_roard_r(addr=%p, len=%i) = ?", addr, len); if ( addr == NULL || len == 0 ) return -1; *addr = 0; // just in case... if ( nocache || cache.tod < time(NULL) ) { #ifdef DEBUG if ( nocache ) { ROAR_DBG("roar_slp_find_roard_r(*): forced ignoring of cache, doing a new lookup."); } #endif ROAR_DBG("roar_slp_find_roard_r(*): cache too old, searching for a new server..."); ROAR_DBG("roar_slp_find_roard_r(*) = ?"); if ( roar_slp_cookie_init(&cookie, NULL) == -1 ) return -1; ROAR_DBG("roar_slp_find_roard_r(*) = ?"); if ( roar_slp_search(&cookie, ROAR_SLP_URL_TYPE) == -1 ) return -1; ROAR_DBG("roar_slp_find_roard_r(*) = ?"); if ( cookie.matchcount == 0 ) return -1; ROAR_DBG("roar_slp_find_roard_r(*) = ?"); url = cookie.match[0].url; ROAR_DBG("roar_slp_find_roard_r(*): found new server, caching it"); memcpy(&cache, &(cookie.match[0]), sizeof(cache)); } else { ROAR_DBG("roar_slp_find_roard_r(*): cache within TTL, no need to search for server, using cache."); url = cache.url; } if ( !strncmp(url, ROAR_SLP_URL_TYPE "://", ROAR_SLP_URL_TYPE_LEN + 3) ) offset = 28; ROAR_DBG("roar_slp_find_roard_r(*): url='%s'", cookie.match[0].url); strncpy(addr, &(url[offset]), len); addr[len-1] = 0; // also just in case. ROAR_DBG("roar_slp_find_roard_r(*): addr='%s'", addr); return 0; #else return -1; #endif } //ll ���������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/socket.c����������������������������������������������������������������0000644�0001750�0001750�00000100436�12264733545�015564� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//socket.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #define _LIBROAR_NOATTR_TO_STATIC /* ignore warnings for TO_STATIC functions */ #include "libroar.h" #if defined(ROAR_SUPPORT_PROXY) && !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) #include <pwd.h> #endif #define MODE_LISTEN ROAR_SOCKET_MODE_LISTEN #define MODE_CONNECT ROAR_SOCKET_MODE_CONNECT static int roar_socket_open_file (int mode, const char * host, int port); #ifdef ROAR_SUPPORT_PROXY static int roar_socket_open_proxy (int mode, int type, const char * host, int port, const char * proxy_type); static int roar_socket_open_socks4 (int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts); static int roar_socket_open_socks4a(int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts); static int roar_socket_open_socks4d(int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts); static int roar_socket_open_socks4x(int mode, int fh, char host[4], int port, const char * app, size_t app_len, const char * user); static int roar_socket_open_http (int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts); #ifdef ROAR_HAVE_BIN_SSH static int roar_socket_open_ssh (int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts); #endif #endif #ifdef ROAR_TARGET_WIN32 void roar_socket_win32_init (void) { static int inited = 0; WSADATA wsadata; if ( !inited ) { WSAStartup(MAKEWORD(1,1) , &wsadata); inited++; } } #else #define roar_socket_win32_init() #endif #ifdef ROAR_HAVE_LIBDNET static int roar_socket_decnet_set_timeout (int fh, time_t sec, int_least32_t usec) { struct timeval timeout = {sec, usec}; return setsockopt(fh, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); } #endif static int roar_socket_set_tos(int fh) { #if defined(ROAR_HAVE_BSDSOCKETS) && !defined(ROAR_TARGET_WIN32) int opt = IPTOS_LOWDELAY; int ret; roar_err_clear_errno(); ret = setsockopt(fh, IPPROTO_IP, IP_TOS, &opt, sizeof(int)); if ( ret < 0 ) roar_err_from_errno(); return ret; #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } #if 0 static int roar_socket_new_decnet_seqpacket (void) { #ifdef ROAR_HAVE_LIBDNET int fh; fh = socket(AF_DECnet, SOCK_SEQPACKET, DNPROTO_NSP); roar_socket_decnet_set_timeout(fh, 300, 0); return fh; #else return -1; #endif } #endif #if 0 static int roar_socket_new_ipxspx (void) { return -1; } #endif int roar_socket_new (int type) { #ifdef ROAR_HAVE_BSDSOCKETS int sys_domain = -1, sys_type = -1, sys_protocol = 0; int fh; #if defined(ROAR_HAVE_IPV4) && defined(TCP_NODELAY) && !defined(ROAR_TARGET_WIN32) int t = 1; #endif switch (type) { case ROAR_SOCKET_TYPE_NONE: case ROAR_SOCKET_TYPE_GENSTR: roar_err_set(ROAR_ERROR_INVAL); return -1; break; case ROAR_SOCKET_TYPE_FILE: case ROAR_SOCKET_TYPE_FORK: roar_err_set(ROAR_ERROR_PERM); return -1; break; #ifdef ROAR_HAVE_IPV4 case ROAR_SOCKET_TYPE_TCP: sys_domain = AF_INET; sys_type = SOCK_STREAM; break; case ROAR_SOCKET_TYPE_UDP: sys_domain = AF_INET; sys_type = SOCK_DGRAM; break; #endif #ifdef ROAR_HAVE_UNIX case ROAR_SOCKET_TYPE_UNIX: sys_domain = AF_UNIX; sys_type = SOCK_STREAM; break; #endif #ifdef ROAR_HAVE_LIBDNET case ROAR_SOCKET_TYPE_DECNET: sys_domain = AF_DECnet; sys_type = SOCK_STREAM; sys_protocol = DNPROTO_NSP; break; #endif #ifdef ROAR_HAVE_IPV6 case ROAR_SOCKET_TYPE_TCP6: sys_domain = AF_INET6; sys_type = SOCK_STREAM; break; case ROAR_SOCKET_TYPE_UDP6: sys_domain = AF_INET6; sys_type = SOCK_DGRAM; break; #endif #ifdef ROAR_HAVE_IPX case ROAR_SOCKET_TYPE_IPX: sys_domain = AF_IPX; sys_type = SOCK_DGRAM; sys_protocol = AF_IPX; break; #endif case ROAR_SOCKET_TYPE_IPXSPX: case ROAR_SOCKET_TYPE_LAT_SERVICE: case ROAR_SOCKET_TYPE_LAT_REVERSE_PORT: default: roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; break; } roar_socket_win32_init(); roar_err_clear_all(); fh = socket(sys_domain, sys_type, sys_protocol); if ( fh == -1 ) { roar_err_update(); return -1; } // do the extra work we need to do for some socket types: switch (type) { #ifdef ROAR_HAVE_IPV4 case ROAR_SOCKET_TYPE_TCP: #if defined(TCP_NODELAY) && !defined(ROAR_TARGET_WIN32) setsockopt(fh, IPPROTO_TCP, TCP_NODELAY, &t, sizeof(int)); #endif case ROAR_SOCKET_TYPE_UDP: #endif #ifdef ROAR_HAVE_IPV6 case ROAR_SOCKET_TYPE_TCP6: case ROAR_SOCKET_TYPE_UDP6: #endif #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) roar_socket_set_tos(fh); break; #endif #ifdef ROAR_HAVE_LIBDNET case ROAR_SOCKET_TYPE_DECNET: roar_socket_decnet_set_timeout(fh, 300, 0); break; #endif } return fh; #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } int roar_socket_nonblock(int fh, int state) { #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) && defined(ROAR_HAVE_FCNTL) int flags; if ( (flags = fcntl(fh, F_GETFL, 0)) == -1 ) { roar_err_from_errno(); ROAR_ERR("roar_socket_nonblock(fh=%i, state=%i): Can not read flags: %s", fh, state, strerror(errno)); ROAR_DBG("roar_socket_nonblock(fh=%i, state=%i) = -1", fh, state); return -1; } if ( !(flags & O_NONBLOCK) && state == ROAR_SOCKET_BLOCK ) return 0; flags |= O_NONBLOCK; if ( state == ROAR_SOCKET_BLOCK ) flags -= O_NONBLOCK; if ( fcntl(fh, F_SETFL, flags) == -1 ) { roar_err_from_errno(); ROAR_ERR("roar_socket_nonblock(fh=%i, state=%i): Can not set flags: %s", fh, state, strerror(errno)); ROAR_DBG("roar_socket_nonblock(fh=%i, state=%i) = -1", fh, state); return -1; } ROAR_DBG("roar_socket_nonblock(fh=%i, state=%i) = 0", fh, state); return 0; #else ROAR_WARN("roar_socket_nonblock(*): no nonblocking IO support on win32, use a real OS"); return -1; #endif } int roar_socket_dup_udp_local_end (int fh) { #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) && defined(ROAR_HAVE_FCNTL) int n = -1; int flags = -1; struct sockaddr_in socket_addr; socklen_t len = sizeof(struct sockaddr_in); if ( (flags = fcntl(fh, F_GETFL, 0)) == -1 ) { ROAR_WARN("roar_socket_dup_udp_local_end(fh=%i): Can not read flags: %s", fh, strerror(errno)); } if ( getsockname(fh, (struct sockaddr *)&socket_addr, &len) == -1 ) { roar_err_from_errno(); return -1; } if ( socket_addr.sin_family != AF_INET ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } n = roar_socket_new(ROAR_SOCKET_TYPE_UDP); if ( n == -1 ) return -1; // if ( mode_func(fh, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) == -1 ) { if ( bind(n, (struct sockaddr *)&socket_addr, len) == -1 ) { roar_err_from_errno(); close(n); return -1; } if ( flags != -1 ) { if ( fcntl(fh, F_SETFL, flags) == -1 ) { ROAR_WARN("roar_socket_dup_udp_local_end(fh=%i): Can not set flags: %s", fh, strerror(errno)); return -1; } } return n; #else ROAR_WARN("roar_socket_dup_udp_local_end(*): this function is not supported on win32, use a real OS"); return -1; #endif } #define _SCMR_CONTROLLEN (sizeof(struct cmsghdr) + sizeof(int)) int roar_socket_send_fh (int sock, int fh, char * mes, size_t len) { #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_OS_SUNOS) && !defined(ROAR_TARGET_OPENVMS) struct iovec iov[1]; struct msghdr msg; char cmptr_buf[_SCMR_CONTROLLEN]; struct cmsghdr * cmptr = (struct cmsghdr *) cmptr_buf; char localmes[1] = {0}; ROAR_DBG("roar_socket_send_fh(sock=%i, fh=%i, mes=%p, len=%u) = ?", sock, fh, mes, len); if ( sock < 0 || fh < 0 ) return -1; if ( len == 0 ) { len = 1; mes = localmes; } memset(&msg, 0, sizeof(msg)); memset(cmptr, 0, _SCMR_CONTROLLEN); iov[0].iov_base = mes; iov[0].iov_len = len; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; cmptr->cmsg_len = _SCMR_CONTROLLEN; msg.msg_control = (caddr_t) cmptr; msg.msg_controllen = _SCMR_CONTROLLEN; *(int *)CMSG_DATA(cmptr) = fh; return sendmsg(sock, &msg, 0); #else ROAR_ERR("roar_socket_send_fh(*): There is no UNIX Domain Socket support in win32, download a real OS."); return -1; #endif } int roar_socket_recv_fh (int sock, char * mes, size_t * len) { #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_OS_SUNOS) && !defined(ROAR_TARGET_OPENVMS) struct iovec iov[1]; struct msghdr msg; char cmptr_buf[_SCMR_CONTROLLEN]; struct cmsghdr * cmptr = (struct cmsghdr *) cmptr_buf; char localmes[1]; size_t locallen[1] = {1}; ROAR_DBG("roar_socket_recv_fh(sock=%i, mes=%p, len=%p) = ?", sock, mes, len); if ( sock < 0 ) { ROAR_DBG("roar_socket_recv_fh(sock=%i, mes=%p, len=%p) = -1 // invalid socket", sock, mes, len); return -1; } if ( len == NULL ) { len = locallen; mes = localmes; } iov[0].iov_base = mes; iov[0].iov_len = *len; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = (caddr_t) cmptr; msg.msg_controllen = _SCMR_CONTROLLEN; if ( (*len = recvmsg(sock, &msg, 0)) == -1 ) { ROAR_DBG("roar_socket_recv_fh(sock=%i, mes=%p, len=%p) = -1 // can not read from socket", sock, mes, len); return -1; } if ( msg.msg_controllen < _SCMR_CONTROLLEN || cmptr->cmsg_len != _SCMR_CONTROLLEN ) { ROAR_DBG("roar_socket_recv_fh(sock=%i, mes=%p, len=%p) = -1 // control len is wrong", sock, mes, len); return -1; } ROAR_DBG("roar_socket_recv_fh(sock=%i, mes=%p, len=%p) = %i", sock, mes, len, *(int *)CMSG_DATA(cmptr)); return *(int *)CMSG_DATA(cmptr); #else ROAR_ERR("roar_socket_recv_fh(*): There is no UNIX Domain Socket support in win32, download a real OS."); return -1; #endif } int roar_socket_listen (int type, const char * host, int port) { return roar_socket_open(MODE_LISTEN, type, host, port); } int roar_socket_connect (int type, const char * host, int port) { const char * proxy_type = roar_env_get("ROAR_PROXY"); ROAR_DBG("roar_socket_connect(host='%s', port=%i) = ?", host, port); if ( proxy_type == NULL || strcmp(proxy_type, "") == 0 ) { return roar_socket_open(MODE_CONNECT, type, host, port); } else { #ifdef ROAR_SUPPORT_PROXY return roar_socket_open_proxy(MODE_CONNECT, type, host, port, proxy_type); #else ROAR_ERR("roar_socket_connect(host='%s', port=%i): no support for proxy code (proxy_type=%s)", host, port, proxy_type); return -1; #endif } } #ifdef ROAR_HAVE_LIBDNET static int roar_socket_listen_decnet (const char * object, int num) { int fh = roar_socket_new(ROAR_SOCKET_TYPE_DECNET); struct sockaddr_dn bind_sockaddr; if ( fh == -1 ) return -1; if ( object != NULL && !*object ) object = NULL; if ( (object != NULL && num) || (object != NULL && !*object && !num) || (object == NULL && !num) ) { ROAR_WARN("roar_socket_listen_decnet(object='%s', num=%i): illegal address!", object, num); close(fh); roar_err_set(ROAR_ERROR_INVAL); return -1; } memset((void*)&bind_sockaddr, 0, sizeof(struct sockaddr_dn)); bind_sockaddr.sdn_family = AF_DECnet; bind_sockaddr.sdn_flags = 0; bind_sockaddr.sdn_objnum = num; if ( num ) { bind_sockaddr.sdn_objnamel = 0; } else { bind_sockaddr.sdn_objnamel = ROAR_HOST2LE16(strlen(object)); if ( bind_sockaddr.sdn_objnamel > DN_MAXOBJL ) bind_sockaddr.sdn_objnamel = DN_MAXOBJL; strncpy((char*)bind_sockaddr.sdn_objname, object, DN_MAXOBJL); } if ( bind(fh, (struct sockaddr *) &bind_sockaddr, sizeof(bind_sockaddr)) == -1 ) { roar_err_from_errno(); close(fh); return -1; } if ( listen(fh, 8) == -1 ) { roar_err_from_errno(); close(fh); return -1; } return fh; } #endif const char * roar_socket_get_local_nodename(void) { #ifdef ROAR_HAVE_LIBDNET static char node[16] = {0}; struct dn_naddr *binaddr; struct nodeent *dp; if ( !node[0] ) { // TODO: This does this function not use getnodename()? // Those strange workarounds for the error codes are because those functions currently // don't set errno. This way we will use errno as soon as it starts to set it. roar_err_update(); if ( (binaddr=getnodeadd()) == NULL) { roar_err_update(); if ( roar_error == ROAR_ERROR_NONE ) roar_err_set(ROAR_ERROR_NOENT); return NULL; } roar_err_update(); if ( (dp=getnodebyaddr((char*)binaddr->a_addr, binaddr->a_len, AF_DECnet)) == NULL ) { roar_err_update(); if ( roar_error == ROAR_ERROR_NONE ) roar_err_set(ROAR_ERROR_NOENT); return NULL; } strncpy(node, dp->n_name, 15); node[15] = 0; } return node; #else roar_err_set(ROAR_ERROR_AFNOTSUP); return NULL; #endif } int roar_socket_open (int mode, int type, const char * host, int port) { // int type = ROAR_SOCKET_TYPE_INET; int fh; #ifdef ROAR_HAVE_IPX #define _NEED_OBJ #endif #if defined(ROAR_HAVE_IPX) || defined(ROAR_HAVE_GETADDRINFO) int ret; #endif #ifdef ROAR_HAVE_IPX unsigned int ipx_port; #endif #ifdef ROAR_HAVE_UNIX int abstract = 0; #endif #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) || defined(ROAR_HAVE_UNIX) || defined(ROAR_HAVE_IPX) union { struct sockaddr sa; #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) struct sockaddr_in in; #endif #ifdef ROAR_HAVE_UNIX struct sockaddr_un un; #endif #ifdef ROAR_HAVE_IPV6 struct sockaddr_in6 in6; #endif #ifdef ROAR_HAVE_IPX struct sockaddr_ipx ipx; #endif } socket_addr; socklen_t addrlen; #endif #if (defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6)) && !defined(ROAR_HAVE_GETADDRINFO) struct hostent * he = NULL; #endif //unsigned int host_div = 0; #ifdef ROAR_TARGET_WIN32 int PASCAL (*mode_func)(SOCKET,const struct sockaddr*,int) = connect; // default is to connect #else int (*mode_func)(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) = connect; // default is to connect #endif #ifdef ROAR_HAVE_LIBDNET #define _NEED_OBJ char * dnet_node_buf; #endif #ifdef _NEED_OBJ char obj[80]; char * del; #endif #ifdef ROAR_HAVE_GETADDRINFO int af_guessed = 0; struct addrinfo hints, *res = NULL; char port_as_string[32]; #endif #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) int is_numerical = 1; const char * numptr; #endif ROAR_DBG("roar_socket_open(mode=%i, type=%i, host='%s', port=%i) = ?", mode, type, host, port); if ( host == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } roar_err_set(ROAR_ERROR_UNKNOWN); if ( mode == MODE_LISTEN ) mode_func = bind; if ( type == ROAR_SOCKET_TYPE_UNKNOWN ) { #ifdef ROAR_HAVE_GETADDRINFO af_guessed = 1; #endif type = ROAR_SOCKET_TYPE_INET; if ( *host == '/' ) { type = ROAR_SOCKET_TYPE_UNIX; } else if ( strcmp(host, "+fork") == 0 ) { type = ROAR_SOCKET_TYPE_FORK; } else if ( strcmp(host, "+abstract") == 0 ) { type = ROAR_SOCKET_TYPE_UNIX; #ifdef ROAR_HAVE_UNIX abstract = 1; #endif } else if ( strstr(host, "::") != NULL ) { type = ROAR_SOCKET_TYPE_DECNET; } else if ( host[strlen(host)-1] == ')' ) { type = ROAR_SOCKET_TYPE_IPX; } } ROAR_DBG("roar_socket_open(mode=%i, type=%i, host='%s', port=%i) = ?", mode, type, host, port); ROAR_DBG("roar_socket_open(*): type=%s, host='%s', port=%i", type == ROAR_SOCKET_TYPE_UNIX ? "UNIX" : "???", host, port); if ( type == ROAR_SOCKET_TYPE_DECNET ) { #ifdef ROAR_HAVE_LIBDNET ROAR_DBG("roar_socket_open(*): nodename for DECnet: host(%p)=%s", host, host); dnet_node_buf = roar_mm_strdup(host); // roar_error is still set. if ( dnet_node_buf == NULL ) return -1; host = dnet_node_buf; del = strstr(host, "::"); ROAR_DBG("roar_socket_open(*): nodename for DECnet: del(%p)=%s", del, del); if ( del == NULL ) { ROAR_WARN("roar_socket_open(*): invalid nodename for DECnet: %s", host); roar_mm_free(dnet_node_buf); roar_err_set(ROAR_ERROR_INVAL); return -1; } *del = 0; if ( *(del+2) == '#' ) { // assume we have node::#num port = atoi(del+2); } if ( port ) { snprintf(obj, 7, "%i", port); // no need for snprintf() as dec(port) is smaller than obj[] } else { *obj = 0; strncat(obj, del+2, 79); } ROAR_DBG("roar_socket_open(*): obj='%s', port=%i", obj, port); if ( mode == MODE_LISTEN ) { fh = roar_socket_listen_decnet(obj, port); roar_mm_free(dnet_node_buf); return fh; } else { // There is nothing wrong in this case to use dnet_conn() so we do. ROAR_DBG("roar_socket_open(*): CALL dnet_conn('%s', '%s', SOCK_STREAM, 0 ,0 ,0 , 0)", dnet_node_buf, obj); fh = dnet_conn(dnet_node_buf, obj, SOCK_STREAM, 0, 0, 0, 0); ROAR_DBG("roar_socket_open(*): RET %i", fh); roar_mm_free(dnet_node_buf); return fh; } #else roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; // no decnet support #endif } #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) memset(&socket_addr, 0, sizeof(socket_addr)); #endif if ( type == ROAR_SOCKET_TYPE_INET || type == ROAR_SOCKET_TYPE_INET6 ) { #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) ROAR_DBG("roar_socket_open(*): type=INET|INET6, host='%s', port=%i", host, port); roar_socket_win32_init(); // we need to do this early as gethostbyname() requires this. ROAR_DBG("roar_socket_open(*): type=INET|INET6, host='%s', port=%i", host, port); if ( !!strcmp(host, "0.0.0.0") ) { for (numptr = host; is_numerical && *numptr != 0; numptr++) if ( ! ((*numptr >= '0' && *numptr <= '9') || *numptr == '.') ) is_numerical = 0; if ( is_numerical && roar_libroar_iswarn(NULL) ) { ROAR_WARN("roar_socket_open(*): Hostname \"%s\" is numerical. Do not use IP addresses directly. Use Hostnames.", host); } } #ifdef ROAR_HAVE_GETADDRINFO memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; if ( af_guessed ) { hints.ai_family = AF_UNSPEC; } else { hints.ai_family = type == ROAR_SOCKET_TYPE_INET ? AF_INET : AF_INET6; } snprintf(port_as_string, sizeof(port_as_string), "%i", port); ret = getaddrinfo(host, port_as_string, &hints, &res); if ( ret == EAI_SYSTEM ) { roar_err_from_errno(); return -1; } else if ( ret != 0 ) { roar_err_convert(&roar_error, ROAR_ERROR_TYPE_ROARAUDIO, ret, ROAR_ERROR_TYPE_EAI); return -1; } if ( af_guessed ) { type = res->ai_family == AF_INET ? ROAR_SOCKET_TYPE_INET : ROAR_SOCKET_TYPE_INET6; } if ( type == ROAR_SOCKET_TYPE_INET ) { fh = roar_socket_new(ROAR_SOCKET_TYPE_TCP); } else { fh = roar_socket_new(ROAR_SOCKET_TYPE_TCP6); } memcpy(&(socket_addr.sa), res->ai_addr, res->ai_addrlen); addrlen = res->ai_addrlen; if ( res != NULL ) freeaddrinfo(res); #else if ( (he = gethostbyname(host)) == NULL ) { ROAR_ERR("roar_socket_open(*): Can\'t resolve host name '%s'", host); roar_err_from_errno(); return -1; } ROAR_DBG("roar_socket_open(*): he=%p", he); memcpy((struct in_addr *)&(socket_addr.in.sin_addr), he->h_addr, sizeof(struct in_addr)); /* set the connect information */ socket_addr.in.sin_family = AF_INET; socket_addr.in.sin_port = ROAR_HOST2NET16(port); fh = roar_socket_new(ROAR_SOCKET_TYPE_TCP); addrlen = sizeof(struct sockaddr_in); #endif ROAR_DBG("roar_socket_open(*): fh=%i", fh); if ( fh == -1 ) { ROAR_ERR("roar_socket_open(*): Can\'t create TCP socket: %s", strerror(errno)); return -1; } ROAR_DBG("roar_socket_open(*) = ?"); ROAR_DBG("roar_socket_open(*): fh=%i", fh); if ( mode_func(fh, (struct sockaddr *)&socket_addr.sa, addrlen) == -1 ) { ROAR_DBG("roar_socket_open(*): Can not connect/bind: %s", strerror(errno)); roar_err_from_errno(); close(fh); return -1; } ROAR_DBG("roar_socket_open(*): fh=%i", fh); // hey! we have a socket... ROAR_DBG("roar_socket_open(*) = ? // we have a socket :)"); #else ROAR_DBG("roar_socket_open(*) = -1 // no IPv4 or IPv6 support"); roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; #endif } else if ( type == ROAR_SOCKET_TYPE_UNIX ) { #ifdef ROAR_HAVE_UNIX socket_addr.un.sun_family = AF_UNIX; if ( abstract ) { memset(socket_addr.un.sun_path, 0, sizeof(socket_addr.un.sun_path)); snprintf(socket_addr.un.sun_path+1, sizeof(socket_addr.un.sun_path)-1, "RoarAudio/UNIX/Abstract/%i", abstract); } else { strncpy(socket_addr.un.sun_path, host, sizeof(socket_addr.un.sun_path) - 1); } fh = roar_socket_new(ROAR_SOCKET_TYPE_UNIX); if ( mode_func(fh, (struct sockaddr *)&socket_addr.un, sizeof(struct sockaddr_un)) == -1 ) { ROAR_DBG("roar_socket_open(*): Can not connect/bind: %s", strerror(errno)); roar_err_from_errno(); close(fh); return -1; } #else ROAR_ERR("roar_socket_open(*): There is no UNIX Domain Socket support in win32, download a real OS."); roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; #endif } else if ( type == ROAR_SOCKET_TYPE_IPX ) { #ifdef ROAR_HAVE_IPX socket_addr.ipx.sipx_family = AF_IPX; obj[0] = 0; if ( (ret = sscanf(host, "%8x.%12s(%x)", &socket_addr.ipx.sipx_network, obj, &ipx_port)) < 2 ) { return -1; socket_addr.ipx.sipx_port = ipx_port; } else if ( ret == 2 ) { socket_addr.ipx.sipx_port = port; // Network Byte Order? } memset(socket_addr.ipx.sipx_node, 0, IPX_NODE_LEN); ret = strlen(obj); if ( ret % 2 ) // needs to be even at the moment return -1; fh = roar_socket_new(ROAR_SOCKET_TYPE_IPX); close(fh); roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; #else roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; #endif } else if ( type == ROAR_SOCKET_TYPE_FORK ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } else if ( type == ROAR_SOCKET_TYPE_FILE ) { return roar_socket_open_file(mode, host, port); } else { roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; } if ( mode == MODE_LISTEN ) { #if defined(ROAR_HAVE_BSDSOCKETS) || defined(ROAR_TARGET_WIN32) if ( listen(fh, ROAR_SOCKET_QUEUE_LEN) == -1 ) { roar_err_from_errno(); close(fh); return -1; } #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } return fh; } static int roar_socket_open_file (int mode, const char * host, int port) { #ifdef ROAR_HAVE_IO_POSIX int fh; if ( mode == MODE_LISTEN ) return -1; if ( (fh = open(host, O_RDONLY, 0644)) == -1 ) { ROAR_ERR("roar_socket_open_file(*): Can not open file %s: %s", host, strerror(errno)); } return fh; #else return -1; #endif } // --- [ PROXY CODE ] --- #ifndef ROAR_HAVE_IO_POSIX #ifdef ROAR_SUPPORT_PROXY #undef ROAR_SUPPORT_PROXY #endif #endif // generic proxy code: #ifdef ROAR_SUPPORT_PROXY static int roar_socket_open_proxy (int mode, int type, const char * host, int port, const char * proxy_type) { int proxy_port = -1; char proxy_host[ROAR_SOCKET_MAX_HOSTNAMELEN]; const char * proxy_addr = NULL; int i; int fh = -1; const char * user = NULL, * pw = NULL, * opts = NULL; char * sep; int no_fh = 0; char proxy_addr_buf[1024]; static struct passwd * passwd; int (* code)(int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts) = NULL; if ( passwd == NULL ) { passwd = getpwuid(getuid()); } // TODO: fix this in a good way #ifndef ROAR_TARGET_MICROCONTROLLER if ( passwd != NULL ) user = passwd->pw_name; #endif if ( user == NULL ) user = roar_env_get("USER"); // TODO: change this so we support listen() proxys (ssh -R) if ( mode != MODE_CONNECT ) return -1; if ( !strncmp(proxy_type, "socks", 5) ) { proxy_addr = roar_env_get("socks_proxy"); proxy_port = 9050; // TOR's default port } else if ( !strcmp(proxy_type, "http") || !strcmp(proxy_type, "https") ) { proxy_port = 8080; if ( (proxy_addr = roar_env_get("http_proxy")) == NULL ) proxy_addr = roar_env_get("https_proxy"); if ( proxy_addr == NULL ) return -1; if ( !strncmp(proxy_addr, "http://", 7) ) proxy_addr += 7; } else if ( !strncmp(proxy_type, "ssh", 3) ) { proxy_port = 22; proxy_addr = roar_env_get("ssh_proxy"); no_fh = 1; } proxy_addr_buf[1023] = 0; strncpy(proxy_addr_buf, proxy_addr, 1023); proxy_addr = proxy_addr_buf; if ( (sep = strstr(proxy_type, "/")) != NULL ) opts = sep+1; if ( proxy_addr == NULL ) return -1; if ( (sep = strstr(proxy_addr, "@")) != NULL ) { *sep = 0; user = proxy_addr; proxy_addr = sep+1; if ( (sep = strstr(user, ":")) != NULL ) { *sep = 0; pw = sep+1; } } ROAR_DBG("roar_socket_open_proxy(*): proxy_type='%s', opts='%s', user='%s', pw=(not shown), proxy_addr='%s'", proxy_type, opts, user, proxy_addr); for (i = 0; proxy_addr[i] != 0 && proxy_addr[i] != ':' && i < (ROAR_SOCKET_MAX_HOSTNAMELEN - 1); i++) proxy_host[i] = proxy_addr[i]; proxy_host[i] = 0; if ( i == 0 ) // no hostname found return -1; if ( proxy_addr[i] == ':' ) proxy_port = atoi(&proxy_addr[i+1]); if ( ! no_fh ) { if ( (fh = roar_socket_open(mode, type, proxy_host, proxy_port)) == -1) { return -1; } } if ( !strcmp(proxy_type, "socks4a") ) { // for TOR, the only supported type at the moment code = roar_socket_open_socks4a; } else if ( !strcmp(proxy_type, "socks4d") ) { // DECnet code = roar_socket_open_socks4d; } else if ( !strcmp(proxy_type, "socks4") ) { // good old SOCKS4 code = roar_socket_open_socks4; } else if ( !strcmp(proxy_type, "http") ) { // HTTP CONNECT code = roar_socket_open_http; } else if ( !strncmp(proxy_type, "ssh", 3) ) { // SSH... #ifdef ROAR_HAVE_BIN_SSH code = roar_socket_open_ssh; #else ROAR_ERR("roar_socket_open_proxy(*): No SSH support compiled in"); #endif } else { return -1; // unknown type } if ( code != NULL ) { if ( no_fh ) { fh = code(mode, fh, host, port, user, pw, opts); } else { if ( code(mode, fh, host, port, user, pw, opts) == -1 ) { close(fh); return -1; } } return fh; } close(fh); return -1; } // protocoll dependet proxy code: static int roar_socket_open_socks4 (int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts) { #ifndef ROAR_TARGET_MICROCONTROLLER struct hostent * he; if ( (he = gethostbyname(host)) == NULL ) { ROAR_ERR("roar_socket_open_socks4(*): Can\'t resolve host name '%s'", host); return -1; } return roar_socket_open_socks4x(mode, fh, he->h_addr, port, NULL, 0, user); #else return -1; #endif } static int roar_socket_open_socks4a(int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts) { return roar_socket_open_socks4x(mode, fh, "\0\0\0\1", port, host, strlen(host)+1, user); } static int roar_socket_open_socks4d(int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts) { size_t len = strlen(host)+1; char * dp; if ( port == 0 ) { if ( (dp = strstr(host, "::")) == NULL ) return -1; len--; *dp = 0; memmove(dp+1, dp+2, len - (dp-host) - 1); } return roar_socket_open_socks4x(mode, fh, "\0\2\0\0", port, host, len, user); } static int roar_socket_open_socks4x(int mode, int fh, char host[4], int port, const char * app, size_t app_len, const char * user) { char buf[9]; int len; buf[0] = 0x04; buf[1] = mode == MODE_CONNECT ? 0x01 : 0x02; *((uint16_t*)&buf[2]) = htons(port); memcpy(buf+4, host, 4); if ( user == NULL ) { buf[8] = 0x00; len = 9; } else { len = 8; } if ( write(fh, buf, len) != len ) return -1; if ( user != NULL ) { len = strlen(user) + 1; if ( write(fh, user, len) != len ) return -1; } if ( app_len > 0 ) if ( write(fh, app, app_len) != (ssize_t)app_len ) return -1; if ( read(fh, buf, 8) != 8 ) return -1; if ( buf[1] != 0x5a ) return -1; return 0; } static int roar_socket_open_http (int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts) { char buf[1024]; int len; if ( port == 0 || host == NULL ) return -1; if ( *host == '/' ) // AF_UNIX return -1; if ( (len = snprintf(buf, sizeof(buf), "CONNECT %s:%i HTTP/1.0\r\nUser-Agent: libroar\r\n\r\n", host, port)) == -1 ) return -1; if ( write(fh, buf, len) != len ) return -1; while ( (len = read(fh, buf, sizeof(buf))) ) { if ( len == sizeof(buf) ) { // overlong lion return -1; } else if ( len == 2 && buf[0] == '\r' && buf[1] == '\n' ) { break; } else if ( len == 1 && (buf[0] == '\r' || buf[0] == '\n') ) { // bad proxy or devel trying to debug ;) break; } else if ( len >= 4 && buf[len-4] == '\r' && buf[len-3] == '\n' && buf[len-2] == '\r' && buf[len-1] == '\n' ) { break; } } return 0; } #ifdef ROAR_HAVE_BIN_SSH static int roar_socket_open_ssh (int mode, int fh, const char * host, int port, const char * user, const char * pw, const char * opts) { const char * proxy_addr = roar_env_get("ssh_proxy"); char * sep; char * bin_ssh; char cmd[1024] = "", rcmd[1024] = ""; int proxy_port = 22; int use_socat = 0; int r; int socks[2]; if ( host == NULL ) return -1; if ( *host == '/' ) use_socat = 1; if ( mode == MODE_LISTEN ) return -1; if ( proxy_addr == NULL ) return -1; if ( opts != NULL ) { if ( !strcmp(opts, "socat") ) { use_socat = 1; } else if ( !strcmp(opts, "netcat") ) { use_socat = 0; } else { return -1; } } ROAR_DBG("roar_socket_open_ssh(*): proxy_addr='%s'", proxy_addr); if ( (sep = strstr(proxy_addr, "@")) != NULL ) proxy_addr = sep+1; if ( (sep = strstr(proxy_addr, ":")) != NULL ) { *sep = 0; proxy_port = atoi(sep+1); } if ( !strcmp(host, "+fork") ) { strncpy(rcmd, "roard --no-listen --client-fh 0", 32); } else { if ( use_socat ) { if ( *host == '/' ) { snprintf(rcmd, sizeof(rcmd)-1, "socat stdio unix-connect:\"%s\"", host); } else { snprintf(rcmd, sizeof(rcmd)-1, "socat stdio tcp:\"%s\":%i", host, port); } } else { snprintf(rcmd, sizeof(rcmd)-1, "$(which netcat nc 2> /dev/null | grep -v \" \" | head -n 1) \"%s\" %i", host, port); } rcmd[sizeof(rcmd)-1] = 0; } ROAR_DBG("roar_socket_open_ssh(*): proxy_port=%i, user='%s', proxy_addr='%s'", proxy_port, user, proxy_addr); ROAR_DBG("roar_socket_open_ssh(*): rcmd: %s", rcmd); bin_ssh = roar_libroar_get_path("bin-ssh", 0, NULL, NULL); if ( bin_ssh == NULL ) return -1; snprintf(cmd, sizeof(cmd)-1, "%s -p %i -l '%s' '%s' '%s'", bin_ssh, proxy_port, user, proxy_addr, rcmd); cmd[sizeof(cmd)-1] = 0; roar_mm_free(bin_ssh); // TODO: get this more portable! #ifdef AF_UNIX if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) { return -1; } #else return -1; #endif r = roar_fork(NULL); if ( r == -1 ) { // error! ROAR_ERR("roar_socket_open_ssh(*): Can not fork: %s", strerror(errno)); close(socks[0]); close(socks[1]); return -1; } else if ( r == 0 ) { // we are the child roar_watchdog_stop(); close(socks[0]); close(ROAR_STDIN ); // we do not want roard to have any standard input close(ROAR_STDOUT); // STDOUT is also not needed, so we close it, // but STDERR we keep open for error messages. dup2(socks[1], 0); dup2(socks[1], 1); execlp("sh", "sh", "-c", cmd, (_LIBROAR_GOOD_CAST char*)NULL); // we are still alive? ROAR_ERR("roar_socket_open_ssh(*): alive after exec(), that's bad!"); ROAR_U_EXIT(1); } else { // we are the parent close(socks[1]); return socks[0]; } return -1; } #endif #endif // ROAR_SUPPORT_PROXY //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/sshaskpass.c������������������������������������������������������������0000644�0001750�0001750�00000005221�12264733545�016453� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//sshaskpass.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef _ASKPASS #undef _ASKPASS #endif #ifdef ROAR_HAVE_BIN_SSH_ASKPASS #define _ASKPASS ROAR_HAVE_BIN_SSH_ASKPASS #elif defined(ROAR_HAVE_BIN_GTK_LED_ASKPASS) #define _ASKPASS ROAR_HAVE_BIN_GTK_LED_ASKPASS #elif defined(ROAR_HAVE_BIN_X11_SSH_ASKPASS) #define _ASKPASS ROAR_HAVE_BIN_X11_SSH_ASKPASS #elif defined(ROAR_HAVE_BIN_GNOME_SSH_ASKPASS) #define _ASKPASS ROAR_HAVE_BIN_GNOME_SSH_ASKPASS #endif int roar_sshaskpass_getpass (char ** pw, char * desc) { #if defined(_ASKPASS) && defined(ROAR_SUPPORT_PASSWORD_API) && defined(ROAR_HAVE_POPEN) && defined(ROAR_HAVE_PCLOSE) FILE * cpipe; char buf[1024]; int pos; int i; if ( pw == NULL ) return -1; if ( (cpipe = popen(_ASKPASS, "r")) == NULL ) { return -1; } if ( fgets(buf, 1024, cpipe) == NULL ) { fclose(cpipe); return -1; } pclose(cpipe); pos = strlen(buf); ROAR_DBG("roar_sshaskpass_getpass(pw=%p, desc='%s'): pos=%i", pw, desc, pos); for (i = pos - 1; i >= 0 && (buf[i] == '\r' || buf[i] == '\n'); i--, pos--) { buf[i] = 0; } ROAR_DBG("roar_sshaskpass_getpass(pw=%p, desc='%s'): pos=%i", pw, desc, pos); if ( pos == 0 ) return -1; *pw = roar_mm_strdup(buf); return 0; #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/stack.c�����������������������������������������������������������������0000644�0001750�0001750�00000007244�12264733546�015405� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stack.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static void __free(void * v) { roar_mm_free(v); } int roar_stack_new(struct roar_stack * stack) { if ( stack == NULL ) return -1; memset(stack, 0, sizeof(struct roar_stack)); stack->flags = ROAR_STACK_FLAG_FREE_DATA; stack->free = __free; return 0; } struct roar_stack * roar_stack_newalloc(void) { struct roar_stack * stack = roar_mm_malloc(sizeof(struct roar_stack)); if ( stack == NULL ) return NULL; if ( roar_stack_new(stack) == -1 ) { roar_mm_free(stack); return NULL; } if ( roar_stack_set_flag(stack, ROAR_STACK_FLAG_FREE_SELF, 0) == -1 ) { roar_mm_free(stack); return NULL; } return stack; } int roar_stack_free(struct roar_stack * stack) { int i; if ( stack == NULL ) return -1; if ( (stack->flags & ROAR_STACK_FLAG_FREE_DATA) && stack->free != NULL ) { for (i = 0; i < stack->next; i++) stack->free(stack->slot[i]); } if ( stack->flags & ROAR_STACK_FLAG_FREE_SELF ) { roar_mm_free(stack); } else { memset(stack, 0, sizeof(struct roar_stack)); // just to be sure... } return 0; } int roar_stack_set_free(struct roar_stack * stack, void (*func)(void*)) { if ( stack == NULL ) return -1; stack->free = func; return 0; } int roar_stack_set_flag(struct roar_stack * stack, int flag, int reset) { if ( stack == NULL ) return -1; stack->flags |= flag; if ( reset ) stack->flags -= flag; return 0; } int roar_stack_push (struct roar_stack * stack, void * ptr) { if ( stack == NULL ) return -1; if ( stack->next == ROAR_STACK_SIZE ) /* stack is full */ return -1; stack->slot[stack->next++] = ptr; return 0; } int roar_stack_pop (struct roar_stack * stack, void ** ptr) { if ( stack == NULL ) /* it is valid to have ptr = NULL, */ return -1; /* to just pop a value without want to take it */ if ( ptr != NULL ) /* just to be sure */ *ptr = NULL; if ( stack->next == 0 ) /* nothing in stack */ return -1; stack->next--; if ( ptr != NULL ) *ptr = stack->slot[stack->next]; return 0; } int roar_stack_get_cur (struct roar_stack * stack, void ** ptr) { if ( stack == NULL || ptr == NULL ) return -1; *ptr = NULL; /* just to be sure */ if ( stack->next == 0 ) /* nothing in the stack */ return -1; *ptr = stack->slot[stack->next - 1]; return 0; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/stream.c����������������������������������������������������������������0000644�0001750�0001750�00000102127�12264733546�015567� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stream.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_stream_connect(struct roar_connection * con, struct roar_stream * s, int dir, int mixer) { struct roar_libroar_config * config = roar_libroar_get_config(); struct roar_stream ms; struct roar_message m; s->dir = dir; memset(&m, 0, sizeof(m)); memcpy(&ms, s, sizeof(ms)); m.cmd = ROAR_CMD_NEW_STREAM; m.stream = mixer; m.pos = 0; if ( config != NULL ) { if ( config->info.rate ) ms.info.rate = config->info.rate; if ( config->info.bits ) ms.info.bits = config->info.bits; if ( config->info.channels ) ms.info.channels = config->info.channels; if ( config->info.codec ) ms.info.codec = config->info.codec; } roar_stream_s2m(&ms, &m); if ( roar_req3(con, &m, NULL) != 0 ) return -1; if ( m.cmd == ROAR_CMD_OK ) { s->id = m.stream; ROAR_DBG("roar_stream_connect(*) = 0"); return 0; } ROAR_ERR("roar_stream_connect(*): Connecting new stream faild!"); ROAR_DBG("roar_stream_connect(*) = -1"); return -1; } int roar_stream_new (struct roar_stream * s, unsigned int rate, unsigned int channels, unsigned int bits, unsigned int codec) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( bits > ROAR_BITS_MAX ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } s->fh = -1; s->id = -1; s->pos = 0; s->pos_rel_id = -1; s->dir = ROAR_DIR_DEFAULT; s->info.rate = rate; s->info.channels = channels; s->info.bits = bits; s->info.codec = codec; return 0; } int roar_stream_new_by_info (struct roar_stream * s, const struct roar_audio_info * info) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( info->bits > ROAR_BITS_MAX ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } s->fh = -1; s->id = -1; s->pos = 0; s->pos_rel_id = -1; s->dir = ROAR_DIR_DEFAULT; s->info = *info; return 0; } int roar_stream_set_rel_id(struct roar_stream * s, int id) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } s->pos_rel_id = id; return 0; } int roar_stream_get_rel_id(struct roar_stream * s) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return s->pos_rel_id; } int roar_stream_new_by_id(struct roar_stream * s, int id) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( roar_stream_new_empty(s) == -1 ) return -1; return roar_stream_set_id(s, id); } int roar_stream_new_empty(struct roar_stream * s) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return roar_stream_new(s, 0, 0, 0, 0); } int roar_stream_set_id (struct roar_stream * s, int id) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } s->id = id; return 0; } int roar_stream_get_id (struct roar_stream * s) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return s->id; } int roar_stream_set_fh (struct roar_stream * s, int fh) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } s->fh = fh; return 0; } int roar_stream_get_fh (struct roar_stream * s) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return s->fh; } int roar_stream_set_dir (struct roar_stream * s, int dir) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } s->dir = dir; return 0; } int roar_stream_get_dir (struct roar_stream * s) { if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return s->dir; } int roar_stream_exec (struct roar_connection * con, struct roar_stream * s) { struct roar_message m; memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_EXEC_STREAM; m.stream = s->id; m.datalen = 0; m.pos = 0; if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd == ROAR_CMD_OK ) return 0; return -1; } int roar_stream_connect_to (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port) { struct roar_message m; if ( roar_stream_connect_to_ask(con, s, type, host, port) == -1 ) return -1; if ( roar_recv_message(con, &m, NULL) == -1 ) return -1; if ( m.cmd == ROAR_CMD_OK ) return 0; return -1; } int roar_stream_connect_to_ask (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port) { struct roar_message m; int len = 0; if ( host == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } ROAR_DBG("roar_stream_connect_to_ask(*): Ask the server to connect to: %s:%i", host, port); memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_CON_STREAM; m.stream = s->id; m.pos = 0; m.data[0] = 0; m.data[1] = type; ((uint16_t*)&(m.data))[1] = ROAR_HOST2NET16(port); len = strlen(host); if ( len > 76 ) { roar_err_set(ROAR_ERROR_NAMETOOLONG); return -1; } strncpy(&(m.data[4]), host, len); m.datalen = len + 4; if ( roar_send_message(con, &m, NULL) == -1 ) return -1; return 0; } int roar_stream_passfh (struct roar_connection * con, struct roar_stream * s, int fh) { struct roar_message m; int confh; if ( con == NULL || s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( fh < 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_PASSFH; m.stream = s->id; m.pos = 0; m.datalen = 0; ROAR_DBG("roar_stream_passfh(con=%p{...}, s={.id=%i,...}, fh=%i) = ?", con, s->id, fh); roar_libroar_nowarn(); if ( (confh = roar_get_connection_fh(con)) == -1 ) { roar_libroar_warn(); return -1; } roar_libroar_warn(); if ( roar_send_message(con, &m, NULL) == -1 ) { ROAR_DBG("roar_stream_passfh(con=%p{...}, s={.id=%i,...}, fh=%i) = -1 // can not send message", con, s->id, fh); return -1; } ROAR_DBG("roar_stream_passfh(*): msg send"); if ( roar_socket_send_fh(confh, fh, NULL, 0) == -1 ) return -1; ROAR_DBG("roar_stream_passfh(*): fh send"); if ( roar_recv_message(con, &m, NULL) == -1 ) return -1; ROAR_DBG("roar_stream_passfh(*): mes recved"); if ( m.cmd == ROAR_CMD_OK ) return 0; return -1; } int roar_stream_attach_simple (struct roar_connection * con, struct roar_stream * s, int client) { struct roar_message m; uint16_t * info = (uint16_t *) m.data; int i; if ( con == NULL || s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( client < 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_ATTACH; m.stream = s->id; m.pos = 0; m.datalen = 6; info[0] = 0; info[1] = ROAR_ATTACH_SIMPLE; info[2] = client; for (i = 0; i < m.datalen/2; i++) { info[i] = ROAR_HOST2NET16(info[i]); } if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_stream_get_info (struct roar_connection * con, struct roar_stream * s, struct roar_stream_info * info) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; int i; if ( con == NULL || s == NULL || info == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_GET_STREAM_PARA; m.stream = s->id; m.datalen = 4; m.pos = 0; data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_INFO; // stream for (i = 0; i < m.datalen/2; i++) { data[i] = ROAR_HOST2NET16(data[i]); } if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; for (i = 0; i < m.datalen/2; i++) { data[i] = ROAR_NET2HOST16(data[i]); } if ( m.datalen < 7*2 ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } if ( data[0] != 0 || data[1] != 1 ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } memset(info, 0, sizeof(struct roar_stream_info)); info->mixer = -1; info->role = ROAR_ROLE_UNKNOWN; info->block_size = data[2]; info->pre_underruns = data[3]; info->post_underruns = data[4]; info->codec = data[5]; info->flags = data[6]; info->delay = data[7]*1000; if ( m.datalen < 9*2 ) { info->state = ROAR_STREAMSTATE_UNKNOWN; return 0; } else { info->state = data[8]; } if ( m.datalen < 10*2 ) { return 0; } else { info->flags |= ((uint32_t)data[9]) << 16; } if ( m.datalen < 11*2 ) { return 0; } else { info->mixer = data[10]; } if ( m.datalen < 12*2 ) { return 0; } else { info->role = data[11]; } return 0; } int roar_stream_get_name (struct roar_connection * con, struct roar_stream * s, char * name, size_t len) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; if ( con == NULL || s == NULL || name == NULL || len == 0 ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } name[0] = 0; // just in case... memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_GET_STREAM_PARA; m.stream = s->id; m.datalen = 4; m.pos = 0; data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_NAME; // stream data[0] = ROAR_HOST2NET16(data[0]); data[1] = ROAR_HOST2NET16(data[1]); ROAR_DBG("roar_stream_get_name(*) = ?"); if ( roar_req(con, &m, NULL) == -1 ) return -1; ROAR_DBG("roar_stream_get_name(*) = ?"); if ( m.cmd != ROAR_CMD_OK ) return -1; ROAR_DBG("roar_stream_get_name(*) = ?"); if ( m.datalen < 4 ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } data[0] = ROAR_NET2HOST16(data[0]); data[1] = ROAR_NET2HOST16(data[1]); ROAR_DBG("roar_stream_get_name(*) = ?"); if ( data[0] != 0 ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } if ( data[1] != (uint16_t)ROAR_STREAM_PARA_NAME ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } m.datalen -= 4; len--; if ( len > m.datalen ) len = m.datalen; strncpy(name, ((char*)m.data)+4, len); name[len] = 0; ROAR_DBG("roar_stream_get_name(*) = 0"); return 0; } int roar_stream_get_chanmap (struct roar_connection * con, struct roar_stream * s, char * map, size_t * len) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p, map=%p, len=%p) = ?", con, s, map, len); if ( con == NULL || s == NULL || map == NULL || len == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( *len == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_GET_STREAM_PARA; m.stream = s->id; m.datalen = 2*2; data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_CHANMAP; data[0] = ROAR_HOST2NET16(data[0]); data[1] = ROAR_HOST2NET16(data[1]); if ( roar_req(con, &m, NULL) == -1 ) return -1; ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len); if ( m.cmd != ROAR_CMD_OK ) return -1; ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len); if ( m.datalen < 4 ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } data[0] = ROAR_NET2HOST16(data[0]); data[1] = ROAR_NET2HOST16(data[1]); ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len); if ( data[0] != 0 ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } if ( data[1] != ROAR_STREAM_PARA_CHANMAP ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len); m.datalen -= 4; if ( m.datalen > *len ) { roar_err_set(ROAR_ERROR_NOMEM); return -1; } ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len); memcpy(map, &(m.data[4]), m.datalen); *len = m.datalen; ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = 0", con, s, s->id, map, len); return 0; } int roar_stream_set_chanmap (struct roar_connection * con, struct roar_stream * s, char * map, size_t len) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; if ( con == NULL || s == NULL || map == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( len == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return 0; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_SET_STREAM_PARA; m.stream = s->id; m.datalen = 2*2 + len; if ( m.datalen > sizeof(m.data) ) return -1; data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_CHANMAP; data[0] = ROAR_HOST2NET16(data[0]); data[1] = ROAR_HOST2NET16(data[1]); memcpy(&(m.data[4]), map, len); if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_stream_set_flags (struct roar_connection * con, struct roar_stream * s, uint32_t flags, int action) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; int i; if ( con == NULL || s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_SET_STREAM_PARA; m.stream = s->id; m.pos = 0; if ( flags & 0xFFFF0000 ) { m.datalen = 2*5; } else { m.datalen = 2*4; } data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_FLAGS; // flags data[2] = action; data[3] = flags & 0x0000FFFF; if ( flags & 0xFFFF0000 ) { data[4] = (flags & 0xFFFF0000) >> 16; } for (i = 0; i < m.datalen/2; i++) { data[i] = ROAR_HOST2NET16(data[i]); } if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_stream_set_role (struct roar_connection * con, struct roar_stream * s, int role) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; int i; if ( con == NULL || s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_SET_STREAM_PARA; m.stream = s->id; m.datalen = 6; m.pos = 0; data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_ROLE; // flags data[2] = role; for (i = 0; i < m.datalen/2; i++) { data[i] = ROAR_HOST2NET16(data[i]); } if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return 0; } int roar_stream_get_rpg (struct roar_connection * con, struct roar_stream * s, struct roar_stream_rpg * rpg) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; size_t i; memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_GET_STREAM_PARA; m.stream = s->id; m.datalen = 2*2; m.pos = 0; data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_RPG; // flags for (i = 0; i < m.datalen/2; i++) { data[i] = ROAR_HOST2NET16(data[i]); } if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; for (i = 0; i < m.datalen/2; i++) { data[i] = ROAR_NET2HOST16(data[i]); } if ( m.datalen != 10 ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } if ( data[0] != 0 ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } if ( data[1] != ROAR_STREAM_PARA_RPG ) { roar_err_set(ROAR_ERROR_BADRQC); return -1; } memset(rpg, 0, sizeof(struct roar_stream_rpg)); rpg->mode = data[2]; rpg->mul = data[3]; rpg->div = data[4]; if ( rpg->mode == 0xFFFF ) rpg->mode = -1; return 0; } int roar_stream_set_rpg (struct roar_connection * con, struct roar_stream * s, const struct roar_stream_rpg * rpg) { struct roar_message m; uint16_t * data = (uint16_t *) m.data; size_t i; memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_SET_STREAM_PARA; m.stream = s->id; m.datalen = (2+3)*2; m.pos = 0; data[0] = 0; // Version and reserved data[1] = ROAR_STREAM_PARA_RPG; // flags data[2] = rpg->mode; data[3] = rpg->mul; data[4] = rpg->div; for (i = 0; i < m.datalen/2; i++) { data[i] = ROAR_HOST2NET16(data[i]); } if ( roar_req(con, &m, NULL) == -1 ) return -1; if ( m.cmd != ROAR_CMD_OK ) return -1; return 0; } #ifdef DEBUG static inline void _roar_debug_audio_info_print (struct roar_audio_info * info) { ROAR_DBG("_roar_debug_audio_info_print(*): Rate : %i", info->rate); ROAR_DBG("_roar_debug_audio_info_print(*): Channels: %i", info->channels); ROAR_DBG("_roar_debug_audio_info_print(*): Bits : %i", info->bits); ROAR_DBG("_roar_debug_audio_info_print(*): Codec : %i", info->codec); } #endif #define _ROAR_STREAM_MESSAGE_LEN ((5+1)*4) int roar_stream_s2m (struct roar_stream * s, struct roar_message * m) { uint32_t * data; int i; if ( s == NULL || m == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } m->datalen = _ROAR_STREAM_MESSAGE_LEN; data = (uint32_t*) m->data; data[0] = s->dir; data[1] = s->pos_rel_id; data[2] = s->info.rate; data[3] = s->info.bits; data[4] = s->info.channels; data[5] = s->info.codec; for (i = 0; i < _ROAR_STREAM_MESSAGE_LEN/4; i++) data[i] = ROAR_HOST2NET32(data[i]); #ifdef DEBUG ROAR_DBG("roar_stream_s2m(*): s->info:"); _roar_debug_audio_info_print(&(s->info)); #endif m->pos = s->pos; m->pos64 = s->pos; return 0; } int roar_stream_m2s (struct roar_stream * s, struct roar_message * m) { uint32_t * data; int i; if ( s == NULL || m == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( m->datalen != _ROAR_STREAM_MESSAGE_LEN ) { roar_err_set(ROAR_ERROR_MSGSIZE); return -1; } if ( m->flags & ROAR_MF_LSPOS ) { s->pos = m->pos64; } else { s->pos = m->pos; } data = (uint32_t*) m->data; for (i = 0; i < _ROAR_STREAM_MESSAGE_LEN/4; i++) data[i] = ROAR_NET2HOST32(data[i]); s->id = m->stream; s->dir = data[0]; s->pos_rel_id = data[1]; s->info.rate = data[2]; s->info.bits = data[3]; s->info.channels = data[4]; s->info.codec = data[5]; #ifdef DEBUG ROAR_DBG("roar_stream_m2s(*): s->info:"); _roar_debug_audio_info_print(&(s->info)); #endif return 0; } // stream direction funcs: static const struct { const int dir; const char * name; } _libroar_dir[] = { {ROAR_DIR_PLAY, "play" }, {ROAR_DIR_RECORD, "record" }, {ROAR_DIR_MONITOR, "monitor" }, {ROAR_DIR_FILTER, "filter" }, {ROAR_DIR_OUTPUT, "output" }, {ROAR_DIR_MIXING, "mixing" }, {ROAR_DIR_META, "meta" }, {ROAR_DIR_BIDIR, "bidir" }, {ROAR_DIR_THRU, "thru" }, {ROAR_DIR_BRIDGE, "bridge" }, {ROAR_DIR_MIDI_IN, "midi_in" }, {ROAR_DIR_MIDI_OUT, "midi_out" }, {ROAR_DIR_LIGHT_IN, "light_in" }, {ROAR_DIR_LIGHT_OUT, "light_out" }, {ROAR_DIR_RAW_IN, "raw_in" }, {ROAR_DIR_RAW_OUT, "raw_out" }, {ROAR_DIR_COMPLEX_IN, "complex_in" }, {ROAR_DIR_COMPLEX_OUT, "complex_out"}, {ROAR_DIR_RDTCS_IN, "rdtcs_in" }, {ROAR_DIR_RDTCS_OUT, "rdtcs_out" }, {ROAR_DIR_RECPLAY, "recplay" }, {-1, "unknown" } }; const char * roar_dir2str (const int dir) { int i; for (i = 0; _libroar_dir[i].dir != -1; i++) if ( _libroar_dir[i].dir == dir ) return _libroar_dir[i].name; return _libroar_dir[i].name; } int roar_str2dir (const char * name) { int i; for (i = 0; _libroar_dir[i].dir != -1; i++) if ( !strcmp(_libroar_dir[i].name, name) ) return _libroar_dir[i].dir; return _libroar_dir[i].dir; } // codec funcs: /* #define roar_codec2str(x) ((x) == ROAR_CODEC_PCM_S_LE ? "pcm_s_le" : (x) == ROAR_CODEC_PCM_S_BE ? "pcm_s_be" : \ (x) == ROAR_CODEC_PCM_S_PDP ? "pcm_s_pdp" : (x) == ROAR_CODEC_MIDI_FILE ? "midi_file" : \ "unknown" ) */ static const struct { const uint32_t codec; const char * name; const char * mime; } _libroar_codec[] = { // PCM: {ROAR_CODEC_PCM_S_LE, "pcm_s_le", NULL}, {ROAR_CODEC_PCM_S_BE, "pcm_s_be", NULL}, {ROAR_CODEC_PCM_S_PDP, "pcm_s_pdp", NULL}, {ROAR_CODEC_PCM_U_LE, "pcm_u_le", NULL}, {ROAR_CODEC_PCM_U_BE, "pcm_u_be", NULL}, {ROAR_CODEC_PCM_U_PDP, "pcm_u_pdp", NULL}, {ROAR_CODEC_DEFAULT, "default", NULL}, // alias {ROAR_CODEC_DEFAULT, "pcm", NULL}, // alias {ROAR_CODEC_DEFAULT, "raw", NULL}, // alias {ROAR_CODEC_PCM_S, "pcm_s", NULL}, // alias {ROAR_CODEC_PCM_U, "pcm_u", NULL}, // alias // MIDI: {ROAR_CODEC_MIDI_FILE, "midi_file", NULL}, {ROAR_CODEC_MIDI, "midi", NULL}, {ROAR_CODEC_ROARMIDI, "roarmidi", NULL}, // XIPH: {ROAR_CODEC_OGG_VORBIS, "ogg_vorbis", "application/ogg"}, {ROAR_CODEC_OGG_VORBIS, "vorbis", "application/ogg"}, // alias {ROAR_CODEC_FLAC, "flac", "audio/x-flac"}, {ROAR_CODEC_OGG_SPEEX, "ogg_speex", "audio/ogg; codecs=speex"}, {ROAR_CODEC_OGG_SPEEX, "speex", "audio/ogg; codecs=speex"}, // alias {ROAR_CODEC_OGG_FLAC, "ogg_flac", "audio/ogg; codecs=flac"}, {ROAR_CODEC_OGG_GENERAL, "ogg_general", "application/ogg"}, {ROAR_CODEC_OGG_CELT, "ogg_celt", "audio/ogg; codecs=celt"}, {ROAR_CODEC_OGG, "ogg", "application/ogg"}, {ROAR_CODEC_OGG_OPUS, "ogg_opus", NULL}, {ROAR_CODEC_ROAR_OPUS, "roar_opus", NULL}, {ROAR_CODEC_ROAR_CELT, "roar_celt", NULL}, {ROAR_CODEC_ROAR_SPEEX, "roar_speex", NULL}, // RAUM: {ROAR_CODEC_RAUM, "raum", NULL}, {ROAR_CODEC_RAUM_VORBIS, "raum_vorbis", NULL}, {ROAR_CODEC_RAUM_FLAC, "raum_flac", NULL}, // RIFF/WAVE like: {ROAR_CODEC_RIFF_WAVE, "riff_wave", "audio/x-wav"}, {ROAR_CODEC_RIFF_WAVE, "wave", "audio/x-wav"}, // alias {ROAR_CODEC_RIFF_WAVE, "wav", "audio/x-wav"}, // alias {ROAR_CODEC_RIFX, "rifx", NULL}, {ROAR_CODEC_AU, "au", "audio/basic"}, {ROAR_CODEC_AIFF, "aiff", "audio/aiff"}, //Log codecs: {ROAR_CODEC_ALAW, "alaw", NULL}, {ROAR_CODEC_AUTLAW_LE, "autlaw_le", NULL}, {ROAR_CODEC_AUTLAW_BE, "autlaw_be", NULL}, {ROAR_CODEC_AUTLAW, "autlaw", NULL}, // alias {ROAR_CODEC_MULAW, "mulaw", NULL}, {ROAR_CODEC_MULAW, "ulaw", NULL}, // alias {ROAR_CODEC_MUUTLAW_LE, "muutlaw_le", NULL}, {ROAR_CODEC_MUUTLAW_BE, "muutlaw_be", NULL}, {ROAR_CODEC_MUUTLAW, "muutlaw", NULL}, // alias //GSM: {ROAR_CODEC_GSM, "gsm", NULL}, {ROAR_CODEC_GSM49, "gsm49", NULL}, //SPC-700 Bit Rate Reduction of //Super Nintendo Entertainment System (SNES) {ROAR_CODEC_BRR, "brr", NULL}, // Meta Codecs: {ROAR_CODEC_META_VCLT, "meta_vclt", NULL}, {ROAR_CODEC_META_RALT, "meta_ralt", NULL}, {ROAR_CODEC_META_RALB, "meta_ralb", NULL}, {ROAR_CODEC_META_RALB_LE, "meta_ralb_le", NULL}, {ROAR_CODEC_META_RALB_BE, "meta_ralb_be", NULL}, {ROAR_CODEC_META_RALB_PDP, "meta_ralb_pdp", NULL}, // light control: {ROAR_CODEC_DMX512, "dmx512", NULL}, {ROAR_CODEC_ROARDMX, "roardmx", NULL}, // Radio Data and Transmitter Control System: {ROAR_CODEC_RDS, "rds", NULL}, // User specific: {ROAR_CODEC_USER0, "user0", NULL}, {ROAR_CODEC_USER1, "user1", NULL}, {ROAR_CODEC_USER2, "user2", NULL}, {ROAR_CODEC_USER3, "user3", NULL}, {ROAR_CODEC_USER4, "user4", NULL}, {ROAR_CODEC_USER5, "user5", NULL}, {ROAR_CODEC_USER6, "user6", NULL}, {ROAR_CODEC_USER7, "user7", NULL}, {ROAR_CODEC_USER8, "user8", NULL}, {ROAR_CODEC_USER9, "user9", NULL}, {ROAR_CODEC_USER10, "user10", NULL}, {ROAR_CODEC_USER11, "user11", NULL}, {ROAR_CODEC_USER12, "user12", NULL}, {ROAR_CODEC_USER13, "user13", NULL}, {ROAR_CODEC_USER14, "user14", NULL}, {ROAR_CODEC_USER15, "user15", NULL}, {-1, NULL, NULL} }; int32_t roar_str2codec(const char * codec) { size_t i; int guess; if ( codec == NULL || *codec == 0 ) return ROAR_CODEC_DEFAULT; if ( (guess = atoi(codec)) > 0 ) return guess; for (i = 0; _libroar_codec[i].codec != (uint32_t)-1; i++) if ( strcasecmp(_libroar_codec[i].name, codec) == 0 ) return _libroar_codec[i].codec; roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_codec2str (const uint32_t codec) { int i; for (i = 0; _libroar_codec[i].codec != (uint32_t)-1; i++) if ( _libroar_codec[i].codec == codec ) return _libroar_codec[i].name; return "unknown"; } int32_t roar_mime2codec (const char * mime) { size_t i; if ( mime == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( *mime == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } for (i = 0; _libroar_codec[i].codec != (uint32_t)-1; i++) if ( _libroar_codec[i].mime != NULL ) if ( strcasecmp(_libroar_codec[i].mime, mime) == 0 ) return _libroar_codec[i].codec; roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_codec2mime (const uint32_t codec) { size_t i; for (i = 0; _libroar_codec[i].codec != (uint32_t)-1; i++) if ( _libroar_codec[i].codec == codec ) return _libroar_codec[i].mime; roar_err_set(ROAR_ERROR_NOENT); return NULL; } int32_t roar_str2rate(const char * rate) { struct roar_audio_info info; int ret; if ( roar_profile2info(&info, rate) != -1 ) { return info.rate; } ret = atoi(rate); if ( ret == 0 && rate[0] != '0' ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } return ret; } int32_t roar_str2bits(const char * bits) { struct roar_audio_info info; int ret; if ( roar_profile2info(&info, bits) != -1 ) { return info.bits; } ret = atoi(bits); if ( ret == 0 && bits[0] != '0' ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } return ret; } int32_t roar_str2channels(const char * channels) { struct roar_audio_info info; int ret; if ( !strcasecmp(channels, "mono") ) { return 1; } else if ( !strcasecmp(channels, "stereo") ) { return 2; } if ( roar_profile2info(&info, channels) != -1 ) { return info.channels; } ret = atoi(channels); if ( ret == 0 && channels[0] != '0' ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } return ret; } const char * roar_streamstate2str(int streamstate) { switch (streamstate) { case ROAR_STREAMSTATE_UNUSED: return "unused"; break; case ROAR_STREAMSTATE_INITING: return "initing"; break; case ROAR_STREAMSTATE_NEW: return "new"; break; case ROAR_STREAMSTATE_OLD: return "old"; break; case ROAR_STREAMSTATE_CLOSING: return "closing"; break; } return "unknown"; } static const struct { int role; const char * name; } _libroar_role[] = { {ROAR_ROLE_UNKNOWN, "unknown" }, {ROAR_ROLE_NONE, "none" }, {ROAR_ROLE_MUSIC, "music" }, {ROAR_ROLE_VIDEO, "video" }, {ROAR_ROLE_GAME, "game" }, {ROAR_ROLE_EVENT, "event" }, {ROAR_ROLE_BEEP, "beep" }, {ROAR_ROLE_PHONE, "phone" }, {ROAR_ROLE_BACKGROUND_MUSIC, "background music"}, {ROAR_ROLE_BACKGROUND_MUSIC, "background_music"}, // alias {ROAR_ROLE_VOICE, "voice" }, {ROAR_ROLE_INSTRUMENT, "instrument" }, {ROAR_ROLE_RHYTHM, "rhythm" }, {ROAR_ROLE_CLICK, "click", }, {ROAR_ROLE_MIXED, "mixed", }, {-1, NULL} }; int roar_str2role (const char * role) { int i; roar_err_clear(); for (i = 0; _libroar_role[i].name != NULL; i++) if ( !strcasecmp(_libroar_role[i].name, role) ) return _libroar_role[i].role; roar_err_set(ROAR_ERROR_NOENT); return ROAR_ROLE_UNKNOWN; } const char * roar_role2str (const int role) { int i; for (i = 0; _libroar_role[i].name != NULL; i++) if ( _libroar_role[i].role == role ) return _libroar_role[i].name; return "unknown"; } const char * roar_rpgmode2str(const int rpgmode) { switch (rpgmode) { case ROAR_RPGMODE_DEFAULT: return "default"; break; case ROAR_RPGMODE_NONE: return "none"; break; case ROAR_RPGMODE_USER: return "user"; break; case ROAR_RPGMODE_ALBUM: return "album"; break; case ROAR_RPGMODE_TRACK: return "track"; break; case ROAR_RPGMODE_ALBUMTRACK: return "albumtrack"; break; case ROAR_RPGMODE_TRACKALBUM: return "trackalbum"; break; default: roar_err_set(ROAR_ERROR_NOENT); return NULL; break; } } ssize_t roar_info2samplesize (struct roar_audio_info * info) { if ( info == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } switch (info->codec) { case ROAR_CODEC_PCM_S_LE: case ROAR_CODEC_PCM_S_BE: case ROAR_CODEC_PCM_S_PDP: case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_BE: case ROAR_CODEC_PCM_U_PDP: return info->bits; break; case ROAR_CODEC_ALAW: case ROAR_CODEC_MULAW: return 8; break; case ROAR_CODEC_DMX512: return 8; break; case ROAR_CODEC_RDS: return 26; break; default: roar_err_set(ROAR_ERROR_INVAL); return -1; break; } } ssize_t roar_info2framesize (struct roar_audio_info * info) { ssize_t ret = roar_info2samplesize(info); if ( ret == -1 ) return -1; ret *= info->channels; return ret; } ssize_t roar_info2bitspersec(struct roar_audio_info * info) { ssize_t ret = roar_info2samplesize(info); if ( ret == -1 ) return -1; ret *= info->channels * info->rate; return ret; } static const struct { const char * name; struct roar_audio_info info; } _libroar_aiprofiles[] = { {"default", {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_CODEC_DEFAULT}}, {"default-server", {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_ROARD_BITS, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_CODEC_DEFAULT}}, {"wav", {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_CODEC_RIFF_WAVE}}, {"au", {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_CODEC_AU}}, {"cd", {.rate = 44100, .bits = 16, .channels = 2, .codec = ROAR_CODEC_DEFAULT}}, {"cdr", {.rate = 44100, .bits = 16, .channels = 2, .codec = ROAR_CODEC_PCM_S_BE}}, {"dat", {.rate = 48000, .bits = 16, .channels = 2, .codec = ROAR_CODEC_PCM_S_LE}}, {"isdn-eu", {.rate = 8000, .bits = 8, .channels = 1, .codec = ROAR_CODEC_ALAW}}, {"isdn-na", {.rate = 8000, .bits = 8, .channels = 1, .codec = ROAR_CODEC_MULAW}}, {"speex-nb", {.rate = 8000, .bits = 16, .channels = 2, .codec = ROAR_CODEC_ROAR_SPEEX}}, {"speex-wb", {.rate = 16000, .bits = 16, .channels = 2, .codec = ROAR_CODEC_ROAR_SPEEX}}, {"speex-uwb", {.rate = 32000, .bits = 16, .channels = 2, .codec = ROAR_CODEC_ROAR_SPEEX}}, {"ogg-vorbis",{.rate = 44100, .bits = 16, .channels = 2, .codec = ROAR_CODEC_OGG_VORBIS}}, {"gsm", {.rate = 8000, .bits = 16, .channels = 1, .codec = ROAR_CODEC_GSM}}, {"brr", {.rate = 8000, .bits = 32, .channels = 1, .codec = ROAR_CODEC_BRR}}, {"brr6k", {.rate = 6000, .bits = 32, .channels = 1, .codec = ROAR_CODEC_BRR}}, {"rds", {.rate = 0, .bits = 0, .channels = 0, .codec = ROAR_CODEC_RDS}}, {"midi", {.rate = 0, .bits = 8, .channels = 16, .codec = ROAR_CODEC_MIDI}}, {"dmx512", {.rate = 0, .bits = 8, .channels = 0, .codec = ROAR_CODEC_DMX512}}, {NULL, {.rate = 0, .bits = 0, .channels = 0, .codec = 0}} }; int roar_profile2info (struct roar_audio_info * info, const char * profile) { int i; if ( info == NULL || profile == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; _libroar_aiprofiles[i].name != NULL; i++) { if ( !strcasecmp(_libroar_aiprofiles[i].name, profile) ) { memcpy(info, &(_libroar_aiprofiles[i].info), sizeof(struct roar_audio_info)); return 0; } } roar_err_set(ROAR_ERROR_NOENT); return -1; } ssize_t roar_profiles_list (const char ** list, size_t len, size_t offset) { size_t i; ssize_t idx = 0; if ( list == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( len == 0 ) return 0; if ( offset >= (sizeof(_libroar_aiprofiles)/sizeof(*_libroar_aiprofiles)) ) return 0; for (i = offset; idx < len && _libroar_aiprofiles[i].name != NULL; i++) { list[idx++] = _libroar_aiprofiles[i].name; } return idx; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/time.c������������������������������������������������������������������0000644�0001750�0001750�00000011674�12264733546�015240� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//time.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_H_SYS_TIME #include <sys/time.h> #endif #ifdef ROAR_HAVE_H_TIME #include <time.h> #endif int roar_time_to_msg(struct roar_message * mes, struct roar_time * time) { uint64_t * data; if ( mes == NULL || time == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(mes, 0, sizeof(struct roar_message)); data = (uint64_t*)mes->data; data[0] = ROAR_HOST2NET64(0); data[1] = ROAR_HOST2NET64(time->t_sec); data[2] = ROAR_HOST2NET64(time->t_ssec); data[3] = ROAR_HOST2NET64(time->c_freq); data[4] = ROAR_HOST2NET64(time->c_drift); mes->datalen = 5*8; if ( time->c_drift == 0 ) { mes->datalen -= 8; if ( time->c_freq == 0 ) { mes->datalen -= 8; if ( time->t_ssec == 0 ) { mes->datalen -= 8; } } } return 0; } int roar_time_from_msg(struct roar_time * time, struct roar_message * mes) { uint64_t * data; if ( mes == NULL || time == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } data = (uint64_t*)mes->data; if ( mes->datalen < 8 ) { roar_err_set(ROAR_ERROR_BADMSG); return -1; } if ( mes->datalen % 8 ) { roar_err_set(ROAR_ERROR_BADMSG); return -1; } if ( ROAR_NET2HOST64(data[0]) != 0 ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } memset(time, 0, sizeof(struct roar_time)); if ( mes->datalen >= 16 ) { time->t_sec = ROAR_NET2HOST64(data[1]); if ( mes->datalen >= 24 ) { time->t_ssec = ROAR_NET2HOST64(data[2]); if ( mes->datalen >= 32 ) { time->c_freq = ROAR_NET2HOST64(data[3]); if ( mes->datalen >= 40 ) { time->c_drift = ROAR_NET2HOST64(data[4]); } } } } return 0; } int roar_get_time (struct roar_connection * con, struct roar_time * time) { struct roar_message mes; if ( con == NULL || time == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(&mes, 0, sizeof(mes)); mes.cmd = ROAR_CMD_GETTIMEOFDAY; mes.stream = -1; mes.datalen = 8; /* 64 bit */ // mes.data is already cleared. if ( roar_req(con, &mes, NULL) == -1 ) return -1; if ( mes.cmd != ROAR_CMD_OK ) { return -1; } if ( roar_time_from_msg(time, &mes) == -1 ) return -1; return 0; } int roar_clock_gettime(struct roar_time * rt, int clock) { #ifdef ROAR_HAVE_GETTIMEOFDAY struct timeval tv; #elif defined(ROAR_HAVE_TIME) time_t now; #endif ROAR_DBG("roar_clock_gettime(rt=%p, clock=%i) = ?", rt, clock); if ( rt == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(rt, 0, sizeof(struct roar_time)); if ( clock == ROAR_CLOCK_DEFAULT ) clock = ROAR_CLOCK_REALTIME; switch (clock) { case ROAR_CLOCK_REALTIME: ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = ?", rt, clock); #ifdef ROAR_HAVE_GETTIMEOFDAY if ( gettimeofday(&tv, NULL) == -1 ) { roar_err_from_errno(); ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = -1 //error=%i", rt, clock, roar_error); return -1; } rt->t_sec = tv.tv_sec; rt->t_ssec = (uint64_t)tv.tv_usec * (uint64_t)18446744073709ULL; rt->c_freq = 1000000LLU*1000000000LLU; #elif defined(ROAR_HAVE_TIME) now = time(NULL); rt->t_sec = now; rt->c_freq = 1000000000LLU; #else ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = -1 // error=NOTSUP", rt, clock); roar_err_set(ROAR_ERROR_NOTSUP); return -1; #endif ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = 0", rt, clock); return 0; break; } ROAR_DBG("roar_clock_gettime(rt=%p, clock=%i) = -1 // error=NOTSUP", rt, clock); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } //ll ��������������������������������������������������������������������roaraudio-1.0beta11/libroar/trap.c������������������������������������������������������������������0000644�0001750�0001750�00000010205�12264733546�015235� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//*.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static struct _group { unsigned int id; const char * name; } _libroar_trap_groups[] = { {ROAR_TRAP_GROUP_LIBROAR, "libroar"}, {ROAR_TRAP_GROUP_ROARD, "roard"}, {ROAR_TRAP_GROUP_APP, "app"}, {ROAR_TRAP_GROUP_LIB, "lib"}, {ROAR_TRAP_GROUP_NETWORK, "network"}, {ROAR_TRAP_GROUP_PROTO, "proto"}, {-1, NULL} }; unsigned int roar_trap_register_group(const char * name) { static unsigned int state = ROAR_TRAP_GROUP_USER_MIN; unsigned int ret; size_t i; for (i = 0; i < (sizeof(_libroar_trap_groups)/sizeof(*_libroar_trap_groups)) && _libroar_trap_groups[i].id != (unsigned int)-1; i++); if ( i == (sizeof(_libroar_trap_groups)/sizeof(*_libroar_trap_groups)) ) return -1; ret = state++; _libroar_trap_groups[i].id = ret; _libroar_trap_groups[i].name = name; return ret; } const char * roar_trap_get_groupname(const unsigned int group) { size_t i; for (i = 0; i < (sizeof(_libroar_trap_groups)/sizeof(*_libroar_trap_groups)) && _libroar_trap_groups[i].id != (unsigned int)-1; i++) { if ( _libroar_trap_groups[i].id == group ) return _libroar_trap_groups[i].name; } return NULL; } unsigned int roar_trap_get_groupid(const char * name) { size_t i; for (i = 0; i < (sizeof(_libroar_trap_groups)/sizeof(*_libroar_trap_groups)) && _libroar_trap_groups[i].id != (unsigned int)-1; i++) { if ( !strcasecmp(_libroar_trap_groups[i].name, name) ) return _libroar_trap_groups[i].id; } return -1; } void roar_strap_impl(const unsigned int group, const char * name, unsigned int line, const char * file, const char * prefix) { #ifdef ROAR_SUPPORT_TRAP struct roar_libroar_config * config = roar_libroar_get_config(); enum roar_trap_policy policy = config->trap_policy; // need to search for the correct policy for this specific trap. switch (policy) { case ROAR_TRAP_IGNORE: return; break; case ROAR_TRAP_WARN: ROAR_DBG("roar_strap_impl(group=%u(\"%s\"), name='%s', line=%u, file='%s') = (void)", group, roar_trap_get_groupname(group), name, line, file); roar_debug_msg(ROAR_DEBUG_TYPE_WARNING, line, file, prefix, "Trap %s of group %s.", name, roar_trap_get_groupname(group)); break; case ROAR_TRAP_ABORT: abort(); break; #ifdef SIGKILL case ROAR_TRAP_KILL: raise(SIGKILL); break; #endif #ifdef SIGSTOP case ROAR_TRAP_STOP: raise(SIGSTOP); break; #endif case ROAR_TRAP_DIE: roar_debug_msg(ROAR_DEBUG_TYPE_WARNING, line, file, prefix, "Trap %s of group %s, terminating program.", name, roar_trap_get_groupname(group)); #ifdef SIGKILL raise(SIGKILL); #else abort(); #endif break; } #else (void)group, (void)name, (void)line, (void)file, (void)prefix; return; #endif } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/uuid.c������������������������������������������������������������������0000644�0001750�0001750�00000012322�12264733546�015237� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//uuid.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_uuid_eq(const roar_uuid_t a, const roar_uuid_t b) { if ( a == NULL || b == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( memcmp(a, b, sizeof(roar_uuid_t)) == 0 ) return 1; return 0; } int roar_uuid2str(char * str, const roar_uuid_t uuid, ssize_t len) { if ( str == NULL || uuid == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( len < 1 ) { roar_err_set(ROAR_ERROR_NOSPC); return -1; } snprintf(str, len, "%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x", uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] ); return 0; } int roar_str2uuid(roar_uuid_t uuid, const char * str) { unsigned int inbuf[16]; int i; if ( sscanf(str, "%2x%2x%2x%2x-%2x%2x-%2x%2x-%2x%2x-%2x%2x%2x%2x%2x%2x", &(inbuf[0]), &(inbuf[1]), &(inbuf[2]), &(inbuf[3]), &(inbuf[4]), &(inbuf[5]), &(inbuf[6]), &(inbuf[7]), &(inbuf[8]), &(inbuf[9]), &(inbuf[10]), &(inbuf[11]), &(inbuf[12]), &(inbuf[13]), &(inbuf[14]), &(inbuf[15])) != 16 ) { roar_err_set(ROAR_ERROR_ILLSEQ); return -1; } for (i = 0; i < 16; i++) uuid[i] = inbuf[i]; return 0; } const roar_uuid_t * roar_uuid_get_ns_real(const char * ns) { static const roar_uuid_t nulluuid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, dns = {0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}, url = {0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}, oid = {0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}, x500 = {0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}; static const void * null_ptr = NULL; if ( ns == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return (const roar_uuid_t *)&null_ptr; } if ( !strcasecmp(ns, "null") ) { return &nulluuid; } else if ( !strcasecmp(ns, "dns") ) { return &dns; } else if ( !strcasecmp(ns, "url") ) { return &url; } else if ( !strcasecmp(ns, "iso oid") || !strcasecmp(ns, "oid") ) { return &oid; } else if ( !strcasecmp(ns, "X.500 DN") || !strcasecmp(ns, "X500 DN") || !strcasecmp(ns, "x500") ) { return &x500; } roar_err_set(ROAR_ERROR_NOENT); return (const roar_uuid_t *)&null_ptr; } int roar_uuid_gen(roar_uuid_t uuid, enum roar_uuid_type type, const roar_uuid_t ns, const void * argp, ssize_t arglen) { unsigned char digest[20]; if ( uuid == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } switch (type) { case ROAR_UUID_TYPE_NULL: memset(uuid, 0, sizeof(roar_uuid_t)); return 0; break; case ROAR_UUID_TYPE_RANDOM: roar_random_gen_nonce(uuid, sizeof(roar_uuid_t)); uuid[6] = (uuid[8] & 0x0F) | 0x40; // Version uuid[8] = (uuid[8] & 0x3F) | 0x80; // Variant return 0; break; case ROAR_UUID_TYPE_MD5: case ROAR_UUID_TYPE_SHA1: if ( ns == NULL || argp == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( arglen < 1 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( roar_hash_salted_buffer(digest, ns, sizeof(roar_uuid_t), type == ROAR_UUID_TYPE_MD5 ? ROAR_HT_MD5 : ROAR_HT_SHA1, argp, arglen) == -1 ) return -1; memcpy(uuid, digest, sizeof(roar_uuid_t)); uuid[6] = (uuid[8] & 0x0F) | (type << 4); // Version uuid[8] = (uuid[8] & 0x3F) | 0x80; // Variant return 0; break; case ROAR_UUID_TYPE_DCE_SECURITY: case ROAR_UUID_TYPE_TIME: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } roar_err_set(ROAR_ERROR_BADRQC); return -1; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio.c�������������������������������������������������������������������0000644�0001750�0001750�00000050267�12264733547�015101� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #define _LIBROAR_NOATTR_TO_STATIC /* ignore warnings for TO_STATIC functions */ #include "libroar.h" #ifdef ROAR_HAVE_H_SYS_IOCTL #include <sys/ioctl.h> #endif #ifdef ROAR_HAVE_IO_POSIX #define _CAN_OPERATE #endif int roar_vio_clear_calls (struct roar_vio_calls * calls) { if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset((void*)calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; return 0; } static int roar_vio_get_fh (struct roar_vio_calls * vio) { if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return ((int)(ROAR_INSTINT)vio->inst) - 1; } ssize_t roar_vio_read (struct roar_vio_calls * vio, void *buf, size_t count) { ssize_t ret; ROAR_DBG("roar_vio_read(vio=%p, buf=%p, count=%u) = ?", vio, buf, (unsigned int)count); if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( vio->read == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } roar_err_clear_all(); ret = vio->read(vio, buf, count); roar_err_update(); return ret; } ssize_t roar_vio_write(struct roar_vio_calls * vio, void *buf, size_t count) { ssize_t ret; // This function MUST NOT call ROAR_{DBG,WARN,ERR,INFO}() because that would result // in an infinit loop. if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( vio->write == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } roar_err_clear_all(); ret = vio->write(vio, buf, count); roar_err_update(); return ret; } roar_off_t roar_vio_lseek(struct roar_vio_calls * vio, roar_off_t offset, int whence) { roar_off_t ret; ROAR_DBG("roar_vio_lseek(vio=%p, offset=%li, whence=%i) = ?", vio, (long int)offset, whence); if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( vio->lseek == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } roar_err_clear_all(); ret = vio->lseek(vio, offset, whence); roar_err_update(); return ret; } int roar_vio_nonblock(struct roar_vio_calls * vio, int state) { ROAR_DBG("roar_vio_nonblock(vio=%p, state=%i) = ?", vio, state); if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return roar_vio_ctl(vio, ROAR_VIO_CTL_NONBLOCK, &state); } int roar_vio_sync (struct roar_vio_calls * vio) { int ret; // This function MUST NOT call ROAR_{DBG,WARN,ERR,INFO}() because that would result // in an infinit loop. if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( vio->sync == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } roar_err_clear_all(); ret = vio->sync(vio); roar_err_update(); return ret; } int roar_vio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { int ret; ROAR_DBG("roar_vio_ctl(vio=%p, cmd=%i(0x%.8x), data=%p) = ?", vio, cmd, cmd, data); if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } ROAR_DBG("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p): vio->ctl=%p", vio, cmd, data, vio->ctl); switch (cmd) { case ROAR_VIO_CTL_CONFLICTING_ID_0: case ROAR_VIO_CTL_CONFLICTING_ID_1: ROAR_ERR("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p): Your progam uses a VIO ctl call with a conflicting ID.", vio, cmd, data); ROAR_ERR("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p): Please recompile your program to fix this. (No additional steps are required beside that.)", vio, cmd, data); ROAR_DBG("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p) = -1", vio, cmd, data); roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } if ( vio->ctl == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } roar_err_clear_all(); ret = vio->ctl(vio, cmd, data); roar_err_update(); return ret; } int roar_vio_ref (struct roar_vio_calls * vio) { if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } vio->refc++; return 0; } int roar_vio_unref (struct roar_vio_calls * vio) { int ret; int err; ROAR_DBG("roar_vio_unref(vio=%p) = ?", vio); if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( vio->refc == 1 && vio->close == NULL ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } vio->refc--; if ( vio->refc ) return 0; roar_err_clear_all(); ret = vio->close(vio); roar_err_update(); err = roar_error; if ( vio->flags & ROAR_VIO_FLAGS_FREESELF ) { roar_vio_clear_calls(vio); roar_mm_free(vio); } else { roar_vio_clear_calls(vio); } roar_error = err; return ret; } // special commands: int roar_vio_accept (struct roar_vio_calls * calls, struct roar_vio_calls * dst) { if (dst == NULL || calls == NULL) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return roar_vio_ctl(dst, ROAR_VIO_CTL_ACCEPT, calls); } int roar_vio_shutdown(struct roar_vio_calls * vio, int how) { if (vio == NULL) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( ( (how | ROAR_VIO_SHUTDOWN_READ|ROAR_VIO_SHUTDOWN_WRITE|ROAR_VIO_SHUTDOWN_LISTEN) - (ROAR_VIO_SHUTDOWN_READ|ROAR_VIO_SHUTDOWN_WRITE|ROAR_VIO_SHUTDOWN_LISTEN) ) != 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } return roar_vio_ctl(vio, ROAR_VIO_CTL_SHUTDOWN, &how); } // converters: int roar_vio_open_fh (struct roar_vio_calls * calls, int fh) { if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset((void*)calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->read = roar_vio_basic_read; calls->write = roar_vio_basic_write; calls->lseek = roar_vio_basic_lseek; calls->sync = roar_vio_basic_sync; calls->ctl = roar_vio_basic_ctl; calls->close = roar_vio_basic_close; calls->inst = (void*)(ROAR_INSTINT)(fh + 1); return 0; } int roar_vio_open_fh_socket(struct roar_vio_calls * calls, int fh) { if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( roar_vio_open_fh(calls, fh) == -1 ) return -1; #ifdef ROAR_TARGET_WIN32 calls->read = roar_vio_winsock_read; calls->write = roar_vio_winsock_write; calls->sync = roar_vio_winsock_sync; calls->ctl = roar_vio_winsock_ctl; calls->close = roar_vio_winsock_close; #else calls->sync = roar_vio_null_sync; #endif return 0; } int roar_vio_open_socket (struct roar_vio_calls * calls, const char * host, int port) { int fh; if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( (fh = roar_socket_connect(ROAR_SOCKET_TYPE_UNKNOWN, host, port)) == -1 ) return -1; return roar_vio_open_fh_socket(calls, fh); } int roar_vio_open_socket_listen(struct roar_vio_calls * calls, int type, const char * host, int port) { int fh; if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( (fh = roar_socket_listen(type, host, port)) == -1 ) return -1; return roar_vio_open_fh_socket(calls, fh); } // VIOs: // basic ssize_t roar_vio_basic_read (struct roar_vio_calls * vio, void *buf, size_t count) { #ifdef _CAN_OPERATE return read(roar_vio_get_fh(vio), buf, count); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } ssize_t roar_vio_basic_write(struct roar_vio_calls * vio, void *buf, size_t count) { #ifdef _CAN_OPERATE return write(roar_vio_get_fh(vio), buf, count); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } roar_off_t roar_vio_basic_lseek(struct roar_vio_calls * vio, roar_off_t offset, int whence) { #ifdef _CAN_OPERATE return lseek(roar_vio_get_fh(vio), offset, whence); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } int roar_vio_basic_sync (struct roar_vio_calls * vio) { #ifdef ROAR_FDATASYNC return ROAR_FDATASYNC(roar_vio_get_fh(vio)); #else return 0; #endif } int roar_vio_basic_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { #ifdef ROAR_HAVE_H_SYS_IOCTL struct roar_vio_sysio_ioctl * sysioctl; #endif #if defined(ROAR_HAVE_GETSOCKOPT) || defined(ROAR_HAVE_SETSOCKOPT) struct roar_vio_sysio_sockopt * syssockopt; #endif int tmp; int s_r = 0, s_w = 0; #if defined(ROAR_HAVE_GETSOCKNAME) || defined(ROAR_HAVE_GETPEERNAME) union { struct sockaddr sa; #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) struct sockaddr_in in; #endif #ifdef ROAR_HAVE_UNIX struct sockaddr_un un; #endif #ifdef ROAR_HAVE_LIBDNET struct sockaddr_dn dn; #endif #ifdef ROAR_HAVE_IPV6 struct sockaddr_in6 in6; #endif #ifdef ROAR_HAVE_IPX struct sockaddr_ipx ipx; #endif } sockaddr; socklen_t socklen; struct roar_sockname * rsockname; #endif if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( cmd == -1 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } ROAR_DBG("roar_vio_basic_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } *(char**)data = "basic"; return 0; break; case ROAR_VIO_CTL_GET_FH: case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_WRITE_FH: case ROAR_VIO_CTL_GET_SELECT_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: case ROAR_VIO_CTL_GET_SELECT_WRITE_FH: ROAR_DBG("roar_vio_basic_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_*FH(0x%.8x), data=%p) = 0 // fh=%i", vio, cmd, data, roar_vio_get_fh(vio)); *(int*)data = roar_vio_get_fh(vio); return 0; break; case ROAR_VIO_CTL_SET_NOSYNC: vio->sync = NULL; return 0; break; case ROAR_VIO_CTL_ACCEPT: #ifdef ROAR_HAVE_ACCEPT tmp = ROAR_ACCEPT(roar_vio_get_fh(vio), NULL, 0); if ( tmp == -1 ) return -1; // most proably a socket. if ( roar_vio_open_fh_socket(data, tmp) == -1 ) { #ifdef ROAR_TARGET_WIN32 closesocket(tmp); #else close(tmp); #endif return -1; } return 0; #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif break; case ROAR_VIO_CTL_SHUTDOWN: tmp = *(int*)data; if ( tmp & ROAR_VIO_SHUTDOWN_READ ) { s_r = 1; tmp -= ROAR_VIO_SHUTDOWN_READ; } if ( tmp & ROAR_VIO_SHUTDOWN_WRITE ) { s_w = 1; tmp -= ROAR_VIO_SHUTDOWN_WRITE; } if ( tmp != 0 ) { /* we currently only support R and W shutdowns */ roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( s_r && s_w ) { tmp = SHUT_RDWR; } else if ( s_r ) { tmp = SHUT_RD; } else if ( s_w ) { tmp = SHUT_WR; } else { return 0; // nothing to do. } return ROAR_SHUTDOWN(roar_vio_get_fh(vio), tmp); break; #if defined(ROAR_HAVE_GETSOCKNAME) || defined(ROAR_HAVE_GETPEERNAME) case ROAR_VIO_CTL_GET_SOCKNAME: case ROAR_VIO_CTL_GET_PEERNAME: if ( data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } rsockname = data; socklen = sizeof(sockaddr); memset(&sockaddr, 0, socklen); // to make sure nothing will break. // getsockname() and getpeername() // seem to be broken on lost of systems. if ( cmd == ROAR_VIO_CTL_GET_SOCKNAME ) { ROAR_DBG("roar_vio_basic_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_SOCKNAME, data=%p) = ?", vio, data); #ifdef ROAR_HAVE_GETSOCKNAME tmp = getsockname(roar_vio_get_fh(vio), &(sockaddr.sa), &socklen); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } else if ( cmd == ROAR_VIO_CTL_GET_PEERNAME ) { ROAR_DBG("roar_vio_basic_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_PEERNAME, data=%p) = ?", vio, data); #ifdef ROAR_HAVE_GETPEERNAME tmp = getpeername(roar_vio_get_fh(vio), &(sockaddr.sa), &socklen); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } else { // memory corruption: roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); roar_err_set(ROAR_ERROR_CHERNOBYL); return -1; } ROAR_DBG("roar_vio_basic_ctl(vio=%p, cmd=0x%.8x, data=%p): tmp=%i", vio, cmd, data, tmp); if ( tmp == -1 ) return -1; memset(rsockname, 0, sizeof(struct roar_sockname)); switch (sockaddr.sa.sa_family) { #if defined(AF_UNIX) && defined(ROAR_HAVE_UNIX) case AF_UNIX: rsockname->type = ROAR_SOCKET_TYPE_UNIX; if ( sockaddr.un.sun_path[0] == 0 ) { rsockname->addr = roar_mm_malloc(sizeof(sockaddr.un.sun_path)); if ( rsockname->addr == NULL ) return -1; memcpy(rsockname->addr, sockaddr.un.sun_path, sizeof(sockaddr.un.sun_path)); } else { rsockname->addr = roar_mm_strdup(sockaddr.un.sun_path); } break; #endif #if defined(AF_DECnet) && defined(ROAR_HAVE_LIBDNET) case AF_DECnet: rsockname->type = ROAR_SOCKET_TYPE_DECNET; if ( sockaddr.dn.sdn_add.a_len != 2 ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } rsockname->addr = roar_mm_malloc(28); if ( rsockname->addr == NULL ) return -1; snprintf(rsockname->addr, 28, "%i.%i::", sockaddr.dn.sdn_add.a_addr[1] >> 2, sockaddr.dn.sdn_add.a_addr[0] + ((sockaddr.dn.sdn_add.a_addr[1] & 0x03) << 8)); rsockname->port = sockaddr.dn.sdn_objnum; if ( sockaddr.dn.sdn_objnum == 0 ) { tmp = strlen(rsockname->addr); memcpy(rsockname->addr + tmp, sockaddr.dn.sdn_objname, sockaddr.dn.sdn_objnamel); rsockname->addr[tmp + sockaddr.dn.sdn_objnamel] = 0; } break; #endif #if defined(AF_INET) && (defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6)) case AF_INET: rsockname->type = ROAR_SOCKET_TYPE_INET; rsockname->port = ntohs(sockaddr.in.sin_port); rsockname->addr = roar_mm_strdup(inet_ntoa(sockaddr.in.sin_addr)); break; #endif #if defined(AF_INET6) && defined(ROAR_HAVE_IPV6) case AF_INET6: rsockname->type = ROAR_SOCKET_TYPE_INET6; rsockname->port = ntohs(sockaddr.in6.sin6_port); break; #endif default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; } return 0; #endif break; #ifdef ROAR_HAVE_H_SYS_IOCTL case ROAR_VIO_CTL_SYSIO_IOCTL: sysioctl = data; return ioctl(roar_vio_get_fh(vio), sysioctl->cmd, sysioctl->argp); break; #endif #ifdef ROAR_HAVE_GETSOCKOPT case ROAR_VIO_CTL_GET_SYSIO_SOCKOPT: syssockopt = data; return getsockopt(roar_vio_get_fh(vio), syssockopt->level, syssockopt->optname, syssockopt->optval, &(syssockopt->optlen)); break; #endif #ifdef ROAR_HAVE_SETSOCKOPT case ROAR_VIO_CTL_SET_SYSIO_SOCKOPT: syssockopt = data; return setsockopt(roar_vio_get_fh(vio), syssockopt->level, syssockopt->optname, syssockopt->optval, syssockopt->optlen); break; #endif case ROAR_VIO_CTL_NONBLOCK: if ( roar_socket_nonblock(roar_vio_get_fh(vio), *(int*)data) == -1 ) return -1; if ( *(int*)data == ROAR_SOCKET_NONBLOCK ) return 0; roar_vio_sync(vio); return 0; break; } roar_err_set(ROAR_ERROR_BADRQC); return -1; } int roar_vio_basic_close (struct roar_vio_calls * vio) { #ifdef _CAN_OPERATE if ( roar_vio_get_fh(vio) != -1 ) return close(roar_vio_get_fh(vio)); return 0; #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } // null ssize_t roar_vio_null_rw (struct roar_vio_calls * vio, void *buf, size_t count) { (void)count; if ( vio == NULL || buf == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return 0; } int roar_vio_null_sync (struct roar_vio_calls * vio) { (void)vio; return 0; } // pass int roar_vio_open_pass (struct roar_vio_calls * calls, struct roar_vio_calls * dst) { if ( calls == NULL || dst == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset((void*)calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->read = roar_vio_pass_read; calls->write = roar_vio_pass_write; calls->lseek = roar_vio_pass_lseek; calls->sync = roar_vio_pass_sync; calls->ctl = roar_vio_pass_ctl; calls->close = roar_vio_pass_close; calls->inst = dst; return 0; } ssize_t roar_vio_pass_read (struct roar_vio_calls * vio, void *buf, size_t count) { return roar_vio_read((struct roar_vio_calls *) vio->inst, buf, count); } ssize_t roar_vio_pass_write(struct roar_vio_calls * vio, void *buf, size_t count) { return roar_vio_write((struct roar_vio_calls *) vio->inst, buf, count); } roar_off_t roar_vio_pass_lseek(struct roar_vio_calls * vio, roar_off_t offset, int whence) { return roar_vio_lseek((struct roar_vio_calls *) vio->inst, offset, whence); } int roar_vio_pass_sync (struct roar_vio_calls * vio) { return roar_vio_sync((struct roar_vio_calls *) vio->inst); } int roar_vio_pass_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if (vio == NULL) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if (cmd == -1) { roar_err_set(ROAR_ERROR_INVAL); return -1; } ROAR_DBG("roar_vio_pass_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } // dirty trick to get real name... if ( vio->read == roar_vio_re_read ) { *(char**)data = "re"; } else { *(char**)data = "pass"; } return 0; break; case ROAR_VIO_CTL_GET_NEXT: *(struct roar_vio_calls **)data = vio->inst; return 0; break; case ROAR_VIO_CTL_SET_NEXT: vio->inst = *(struct roar_vio_calls **)data; return 0; break; } return roar_vio_ctl((struct roar_vio_calls *) vio->inst, cmd, data); } int roar_vio_pass_close (struct roar_vio_calls * vio) { return roar_vio_close((struct roar_vio_calls *) vio->inst); } // re int roar_vio_open_re (struct roar_vio_calls * calls, struct roar_vio_calls * dst) { if ( roar_vio_open_pass(calls, dst) == -1 ) return -1; calls->read = roar_vio_re_read; calls->write = roar_vio_re_write; calls->lseek = roar_vio_re_lseek; return 0; } ssize_t roar_vio_re_read (struct roar_vio_calls * vio, void *buf, size_t count) { size_t len = 0; ssize_t r = -1; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( vio->inst == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } roar_err_clear_all(); while ( (r = roar_vio_read((struct roar_vio_calls *) vio->inst, buf, count)) > 0 ) { len += r; buf += r; count -= r; if ( count == 0 ) break; } if ( len == 0 && r == -1 ) return -1; return len; } ssize_t roar_vio_re_write(struct roar_vio_calls * vio, void *buf, size_t count) { size_t len = 0; ssize_t r = -1; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( vio->inst == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } roar_err_clear_all(); while ( (r = roar_vio_write((struct roar_vio_calls *) vio->inst, buf, count)) > 0 ) { len += r; buf += r; count -= r; if ( count == 0 ) break; } if ( len == 0 && r == -1 ) return -1; return len; } // TODO: we should do a some more intelgent thing here. roar_off_t roar_vio_re_lseek(struct roar_vio_calls * vio, roar_off_t offset, int whence) { return roar_vio_lseek((struct roar_vio_calls *) vio->inst, offset, whence); } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_bio.c���������������������������������������������������������������0000644�0001750�0001750�00000003315�12264733547�015722� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_bio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_bio (struct roar_vio_calls * calls, void * bio) { (void)calls, (void)bio; roar_err_set(ROAR_ERROR_NOSYS); return -1; } void * roar_vio_to_bio (struct roar_vio_calls * calls) { (void)calls; roar_err_set(ROAR_ERROR_NOSYS); return NULL; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_buffer.c������������������������������������������������������������0000644�0001750�0001750�00000021533�12264733547�016424� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_buffer.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_buffer (struct roar_vio_calls * calls, struct roar_vio_calls * dst, ssize_t minsize, int use_re) { struct roar_vio_buffer * self;; if ( calls == NULL || dst == NULL ) return -1; if ( (self = roar_mm_malloc(sizeof(struct roar_vio_buffer))) == NULL ) return -1; memset(self, 0, sizeof(struct roar_vio_buffer)); self->backend = dst; self->min_bufsize = minsize; self->use_re = use_re; if ( use_re ) { if ( roar_vio_open_re(&(self->re_vio), dst) == -1 ) { roar_mm_free(self); return -1; } } memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->inst = self; calls->close = roar_vio_buffer_close; calls->write = roar_vio_buffer_write; calls->ctl = roar_vio_buffer_ctl; calls->sync = roar_vio_buffer_sync; calls->lseek = roar_vio_buffer_lseek; return 0; } int roar_vio_buffer_close (struct roar_vio_calls * vio) { struct roar_vio_buffer * self = vio->inst; int ret; if ( self->buf_old != NULL ) roar_buffer_free(self->buf_old); if ( self->buf_cur != NULL ) roar_buffer_free(self->buf_cur); if ( self->use_re ) { ret = roar_vio_close(&(self->re_vio)); } else { ret = roar_vio_close(self->backend); } roar_mm_free(self); return ret; } ssize_t roar_vio_buffer_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_buffer * self = vio->inst; size_t havelen; size_t buflen; ssize_t ret; if ( count == 0 ) return 0; if ( buf == NULL ) return -1; if ( self->offset.is_old ) { havelen = (self->len_old + self->len_cur) - self->offset.offset; } else { havelen = self->len_cur - self->offset.offset; } if ( havelen == 0 ) { if ( self->use_re ) { ret = roar_vio_read(&(self->re_vio), buf, count); } else { ret = roar_vio_read(self->backend, buf, count); } // TODO... return ret; } else if ( count == havelen ) { if (self->offset.is_old) { buflen = count; if ( roar_buffer_shift_out(&(self->buf_old), buf, &buflen) == -1 ) return -1; if ( self->buf_old != NULL ) // strange error return buflen; buf += buflen; count -= buflen; self->len_old = 0; self->offset.is_old = 0; self->offset.offset = 0; } return -1; } else if ( count < havelen ) { } else if ( count > havelen ) { } return -1; } int roar_vio_buffer_sync (struct roar_vio_calls * vio) { struct roar_vio_buffer * self = vio->inst; struct roar_vio_calls * backend; roar_off_t dst = 0; if ( self->use_re ) { backend = &(self->re_vio); } else { backend = self->backend; } // bring backend in sync state, if this fails we do not need to continue... if ( self->use_re ) { if ( roar_vio_sync(backend) == -1 ) return -1; } else { if ( roar_vio_sync(backend) == -1 ) return -1; } if ( self->buf_old == NULL && self->buf_cur == NULL ) return 0; // we are in sync in case no buffers are currently used. if (self->buf_old != NULL && self->buf_cur == NULL ) { // we just finished the segment roar_buffer_free(self->buf_old); return 0; } // calc seek pos: if ( self->offset.is_old ) { dst = (self->len_cur + self->len_old) - self->offset.offset; } else { dst = self->len_cur - self->offset.offset; } dst = -dst; // do the seek: if ( roar_vio_lseek(backend, dst, SEEK_CUR) == (roar_off_t)-1 ) return -1; // free all internal buffers: if ( self->buf_old != NULL ) roar_buffer_free(self->buf_old); if ( self->buf_cur != NULL ) roar_buffer_free(self->buf_cur); self->offset.is_old = 0; self->offset.offset = 0; // funally bring the backend in sync state again, to be sure all changes are done. if ( self->use_re ) { if ( roar_vio_sync(backend) == -1 ) return -1; } else { if ( roar_vio_sync(backend) == -1 ) return -1; } return 0; } roar_off_t roar_vio_buffer_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { struct roar_vio_buffer * self = vio->inst; size_t newoff; roar_off_t ret; roar_off_t invoff; // in-memory seeking is only supported for SEEK_CUR: if ( whence == SEEK_CUR ) { if ( offset == 0 ) { return 0; } else if ( offset > 0 ) { newoff = self->offset.offset + offset; if ( self->offset.is_old ) { if ( newoff == self->len_old ) { self->offset.is_old = 0; self->offset.offset = 0; self->abspos += offset; return self->abspos; } else if ( newoff < self->len_old ) { self->offset.offset = newoff; self->abspos += offset; return self->abspos; } else if ( newoff > self->len_old ) { if ( newoff < (self->len_old + self->len_cur ) ) { self->offset.is_old = 0; self->offset.offset = offset + self->offset.offset - self->len_old; self->abspos += offset; return self->abspos; } } } else { if ( newoff == self->len_cur ) { roar_buffer_free(self->buf_old); self->buf_old = self->buf_cur; self->buf_cur = NULL; self->offset.offset = 0; self->abspos += offset; return self->abspos; } else if ( newoff < self->len_cur ) { self->offset.offset = newoff; self->abspos += offset; return self->abspos; } } } else { invoff = -offset; if ( invoff <= self->offset.offset ) { self->offset.offset = 0; self->abspos -= invoff; return self->abspos; } if ( !self->offset.is_old ) { if ( invoff > self->offset.offset ) { if ( invoff <= (self->len_old + self->offset.offset) ) { self->offset.is_old = 1; self->offset.offset = (self->len_old + self->offset.offset) - invoff; self->abspos -= invoff; return self->abspos; } } } } } // we need to do a physical seek; // get in sync with current position, flush all buffers,... if ( roar_vio_buffer_sync(vio) == -1 ) return -1; // do the seek: if ( self->use_re ) { ret = roar_vio_lseek(&(self->re_vio), offset, whence); } else { ret = roar_vio_lseek(self->backend, offset, whence); } if (ret != (roar_off_t)-1) self->abspos = ret; return ret; } int roar_vio_buffer_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_vio_buffer * self; if (vio == NULL || cmd == -1) return -1; ROAR_DBG("roar_vio_buffer_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); self = vio->inst; switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "buffer"; return 0; break; case ROAR_VIO_CTL_GET_NEXT: if ( self->use_re ) { *(struct roar_vio_calls **)data = &(self->re_vio); } else { *(struct roar_vio_calls **)data = self->backend; } return 0; break; case ROAR_VIO_CTL_SET_NEXT: if ( self->use_re ) { return roar_vio_ctl(&(self->re_vio), ROAR_VIO_CTL_SET_NEXT, data); } else { self->backend = *(struct roar_vio_calls **)data; } return 0; break; case ROAR_VIO_CTL_NONBLOCK: if ( self->use_re ) { return roar_vio_ctl(&(self->re_vio), ROAR_VIO_CTL_NONBLOCK, data); } else { return roar_vio_ctl(self->backend, ROAR_VIO_CTL_NONBLOCK, data); } break; } return roar_vio_ctl((struct roar_vio_calls *) vio->inst, cmd, data); } ssize_t roar_vio_buffer_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_buffer * self = vio->inst; if ( self->use_re ) { return roar_vio_write(&(self->re_vio), buf, count); } else { return roar_vio_write(self->backend, buf, count); } } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_buffer_store.c������������������������������������������������������0000644�0001750�0001750�00000011017�12264733547�017634� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_buffer_store.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_buffer_store (struct roar_vio_calls * calls, struct roar_vio_buffer_store ** inst) { struct roar_vio_buffer_store * self; if ( calls == NULL ) return -1; self = roar_mm_malloc(sizeof(struct roar_vio_buffer_store)); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roar_vio_buffer_store)); memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; if ( inst != NULL ) *inst = self; calls->inst = self; calls->close = roar_vio_buffer_store_close; calls->sync = roar_vio_buffer_store_sync; calls->ctl = roar_vio_buffer_store_ctl; calls->write = roar_vio_buffer_store_write; calls->read = roar_vio_buffer_store_read; calls->lseek = roar_vio_buffer_store_lseek; return 0; } int roar_vio_buffer_store_close (struct roar_vio_calls * vio) { struct roar_vio_buffer_store * self = vio->inst; int ret = 0; if ( self->in != NULL ) if ( roar_buffer_free(self->in) != 0 ) ret = -1; if ( self->out != NULL ) if ( roar_buffer_free(self->out) != 0 ) ret = -1; return ret; } ssize_t roar_vio_buffer_store_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_buffer_store * self = vio->inst; ROAR_DBG("roar_vio_buffer_store_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); if ( count == 0 ) return 0; if ( buf == NULL ) return -1; if ( self->out == NULL ) return 0; ROAR_DBG("roar_vio_buffer_store_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); if ( roar_buffer_shift_out(&(self->out), buf, &count) == -1 ) return -1; ROAR_DBG("roar_vio_buffer_store_read(*) = %llu", (long long unsigned int)count); return count; } ssize_t roar_vio_buffer_store_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_buffer_store * self = vio->inst; struct roar_buffer * nbuf; void * data; if ( count == 0 ) return 0; if ( buf == NULL ) return -1; if ( roar_buffer_new_data(&nbuf, count, &data) == -1 ) return -1; memcpy(data, buf, count); if ( self->in == NULL ) { self->in = nbuf; } else { if ( roar_buffer_moveinto(self->in, &nbuf) == -1 ) { roar_buffer_free(nbuf); return -1; } } return count; } roar_off_t roar_vio_buffer_store_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { // TODO: implement support to seek forward as wide as the buffer allows us to seek. return (roar_off_t)-1; } int roar_vio_buffer_store_sync (struct roar_vio_calls * vio) { return 0; // we are always sync. } int roar_vio_buffer_store_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if (vio == NULL || cmd == -1) return -1; ROAR_DBG("roar_vio_buffer_store_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "buffer_store"; return 0; break; case ROAR_VIO_CTL_NONBLOCK: return 0; // if we are in nonblock or not is the same for us. break; } return -1; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_cmd.c���������������������������������������������������������������0000644�0001750�0001750�00000040256�12264733547�015721� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_cmd.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_cmd(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * reader, char * writer, int options) { #ifndef ROAR_WITHOUT_VIO_CMD struct roar_vio_cmd_state * state; if ( calls == NULL || dst == NULL ) return -1; if ( reader == NULL && writer == NULL ) return -1; if ( (state = roar_mm_malloc(sizeof(struct roar_vio_cmd_state))) == NULL ) return -1; ROAR_DBG("roar_vio_open_cmd(*): pre reqs are OK"); // clear all memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; memset(state, 0, sizeof(struct roar_vio_cmd_state)); // init reader and writer: state->reader.pid = -1; state->reader.in = -1; state->reader.out = -1; if ( reader != NULL ) state->reader.cmd = roar_mm_strdup(reader); state->writer.pid = -1; state->writer.in = -1; state->writer.out = -1; if ( writer != NULL ) state->writer.cmd = roar_mm_strdup(writer); // init state state->next = dst; state->options = options; state->state = ROAR_VIO_CMD_STATE_OPEN; // init calls calls->close = roar_vio_cmd_close; calls->read = roar_vio_cmd_read; calls->write = roar_vio_cmd_write; calls->sync = roar_vio_cmd_sync; calls->ctl = roar_vio_cmd_ctl; calls->inst = (void*) state; ROAR_DBG("roar_vio_open_cmd(*): var setup OK"); if ( !(options & ROAR_VIO_CMD_OPTS_ON_DEMAND) ) { if ( reader != NULL ) if ( roar_vio_cmd_fork(&(state->reader)) == -1 ) return roar_vio_cmd_close(calls); if ( writer != NULL ) if ( roar_vio_cmd_fork(&(state->writer)) == -1 ) return roar_vio_cmd_close(calls); } return 0; #else return -1; #endif } #ifndef ROAR_WITHOUT_VIO_CMD int roar_vio_cmd_close(struct roar_vio_calls * vio) { struct roar_vio_cmd_state * state = (struct roar_vio_cmd_state *)vio->inst; state->state = ROAR_VIO_CMD_STATE_CLOSING; if ( state->writer.opened ) { if ( state->writer.out != -1 ) { close(state->writer.out); state->writer.out = -1; } } roar_vio_cmd_sync(vio); if ( state->reader.opened ) roar_vio_cmd_wait(&(state->reader)); if ( state->writer.opened ) roar_vio_cmd_wait(&(state->writer)); if ( state->reader.cmd != NULL ) roar_mm_free(state->reader.cmd); if ( state->writer.cmd != NULL ) roar_mm_free(state->writer.cmd); roar_vio_close(state->next); // state->state = ROAR_VIO_CMD_STATE_CLOSED; roar_mm_free(state); return 0; } int roar_vio_cmd_fork(struct roar_vio_cmd_child * child) { int in[2], out[2]; char * bin_sh; if ( child == NULL ) return -1; if ( child->opened ) return 0; if ( child->cmd == NULL ) return -1; // open some pipes... if ( pipe(in) != 0 ) return -1; if ( pipe(out) != 0 ) { close(in[0]); close(in[1]); return -1; } child->pid = roar_fork(NULL); switch (child->pid) { case -1: close(in[0]); close(in[1]); close(out[0]); close(out[1]); return -1; break; case 0: roar_watchdog_stop(); close(in[0]); close(out[1]); close(ROAR_STDIN); close(ROAR_STDOUT); if ( dup2(out[0], ROAR_STDIN) == -1 ) ROAR_U_EXIT(1); if ( dup2(in[1], ROAR_STDOUT) == -1 ) ROAR_U_EXIT(1); bin_sh = roar_libroar_get_path("bin-sh", 0, NULL, NULL); if ( bin_sh == NULL ) ROAR_U_EXIT(1); execlp(bin_sh, bin_sh, "-c", child->cmd, (_LIBROAR_GOOD_CAST char*)NULL); roar_mm_free(bin_sh); ROAR_U_EXIT(1); break; } close(in[1]); close(out[0]); child->opened = 1; child->in = in[0]; child->out = out[1]; return 0; } int roar_vio_cmd_wait(struct roar_vio_cmd_child * child) { int status; if ( child == NULL ) return -1; if ( !child->opened ) return 0; if ( child->out != -1 ) close(child->out); if ( child->in != -1 ) close(child->in); waitpid(child->pid, &status, 0); return 0; } int roar_vio_open_2popen(struct roar_vio_calls * calls, char * command, int options) { #ifndef ROAR_WITHOUT_VIO_CMD struct roar_vio_2popen_state * state; if ( calls == NULL || command == NULL || options < 0 ) return -1; if ( (state = roar_mm_malloc(sizeof(struct roar_vio_2popen_state))) == NULL ) return -1; ROAR_DBG("roar_vio_open_2popen(*): pre reqs are OK"); // clear all memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; memset(state, 0, sizeof(struct roar_vio_2popen_state)); // init reader and writer: state->child.pid = -1; state->child.in = -1; state->child.out = -1; state->child.cmd = roar_mm_strdup(command); // init state state->options = options; state->state = ROAR_VIO_CMD_STATE_OPEN; // init calls calls->close = roar_vio_2popen_close; /* calls->read = roar_vio_2popen_read; calls->write = roar_vio_2popen_write; calls->sync = roar_vio_2popen_sync; calls->ctl = roar_vio_2popen_ctl; */ calls->inst = (void*) state; ROAR_DBG("roar_vio_open_2popen(*): var setup OK"); if ( !(options & ROAR_VIO_CMD_OPTS_ON_DEMAND) ) { if ( roar_vio_cmd_fork(&(state->child)) == -1 ) return roar_vio_2popen_close(calls); } return 0; #else return -1; #endif } #ifndef ROAR_WITHOUT_VIO_CMD int roar_vio_2popen_close(struct roar_vio_calls * vio) { struct roar_vio_2popen_state * state = (struct roar_vio_2popen_state *)vio->inst; state->state = ROAR_VIO_CMD_STATE_CLOSING; if ( state->child.opened ) roar_vio_cmd_wait(&(state->child)); if ( state->child.cmd != NULL ) roar_mm_free(state->child.cmd); roar_mm_free(state); return 0; } #endif // VIOs: ssize_t roar_vio_cmd_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_cmd_state * state = (struct roar_vio_cmd_state *)vio->inst; fd_set rfhs[1], wfhs[1]; struct timeval tv; size_t done = 0; int max_fh; int ret; char tbuf[ROAR_VIO_CMD_BUFSIZE]; char * tp = NULL; ssize_t tlen = 0; int nonblock = state->options & ROAR_VIO_CMD_OPTS_NONBLOCK; int in, out; ROAR_DBG("roar_vio_cmd_read(*) = ?"); if ( !state->reader.opened ) { if ( buf == NULL && count == 0 ) /* sync: no need to do anything if no reader is forked :) */ return 0; if ( !(state->options & ROAR_VIO_CMD_OPTS_ON_DEMAND) ) /* we are not on demand and no reader exists? -> err */ return -1; if ( roar_vio_cmd_fork(&(state->reader)) == -1 ) return -1; } in = state->reader.in; out = state->reader.out; while (done < count) { if ( nonblock ) { tv.tv_sec = 0; tv.tv_usec = 1; } else { tv.tv_sec = 3600; tv.tv_usec = 0; } FD_ZERO(rfhs); FD_ZERO(wfhs); FD_SET(in, rfhs); if ( out != -1 ) { FD_SET(out, wfhs); } #ifdef DEBUG if ( FD_ISSET(in, rfhs) ) { ROAR_DBG("roar_vio_cmd_read(*): reader set in fh group"); } #endif max_fh = in > out ? in : out; ROAR_DBG("roar_vio_cmd_read(*): max_fh=%i", max_fh); if ( (ret = select(max_fh + 1, rfhs, wfhs, NULL, &tv)) == -1 ) { #ifdef EINTR if ( errno == EINTR ) { ROAR_DBG("roar_vio_cmd_read(*): Ooops. Something went wrong. (will try to continue)"); continue; } #endif #ifdef ERESTARTNOHAND if ( errno == ERESTARTNOHAND ) { ROAR_WARN("roar_vio_cmd_read(*): We hit a kernel bug. Haha! (will try to continue)"); continue; } #endif return -1; } ROAR_DBG("roar_vio_cmd_read(*): select(*) = %i", ret); ROAR_DBG("roar_vio_cmd_read(*): reader=%i, writer=%i", in, out); if ( ret > 0 ) { if ( FD_ISSET(in, rfhs) ) { ROAR_DBG("roar_vio_cmd_read(*): event on reader"); if ( (ret = read(in, buf+done, count-done)) == -1 ) break; if ( ret == 0 ) break; done += ret; } if ( out != -1 && FD_ISSET(out, wfhs) ) { ROAR_DBG("roar_vio_cmd_read(*): event on writer"); if ( !tlen ) { tp = tbuf; tlen = 0; if ( (tlen = roar_vio_read(state->next, tp, ROAR_VIO_CMD_BUFSIZE)) == -1 ) { tlen = 0; continue; } } if ( tlen ) { if ( (ret = write(out, tp, tlen)) > 0 ) { tlen -= ret; tp += ret; } } else { close(out); state->reader.out = out = -1; } } } if ( nonblock ) break; } if ( tlen ) { /* we have some data to write to the child... */ // TODO: try to write it out... return -1; } return done; } ssize_t roar_vio_cmd_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_cmd_state * state = (struct roar_vio_cmd_state *)vio->inst; fd_set rfhs[1], wfhs[1]; struct timeval tv; size_t done = 0; int max_fh; int ret; char tbuf[ROAR_VIO_CMD_BUFSIZE]; int nonblock = state->options & ROAR_VIO_CMD_OPTS_NONBLOCK; int in, out; if ( !state->writer.opened ) { if ( buf == NULL && count == 0 ) /* sync: no need to do anything if no writer is forked :) */ return 0; if ( !(state->options & ROAR_VIO_CMD_OPTS_ON_DEMAND) ) /* we are not on demand and no writer exists? -> err */ return -1; if ( roar_vio_cmd_fork(&(state->writer)) == -1 ) return -1; } in = state->writer.in; out = state->writer.out; if ( buf == NULL ) { // we are requested to sync if ( in != -1 ) { ret = 1; done = 0; while (ret > 0) { if ( state->state == ROAR_VIO_CMD_STATE_CLOSING ) { tv.tv_sec = 3600; tv.tv_usec = 0; } else { tv.tv_sec = 0; tv.tv_usec = done ? 1 : 50000; // 50ms } done++; FD_ZERO(rfhs); FD_SET(in, rfhs); if ( select(in+1, rfhs, NULL, NULL, &tv) < 1 ) break; ret = read(in, tbuf, ROAR_VIO_CMD_BUFSIZE); if ( roar_vio_write(state->next, tbuf, ret) != ret ) return -1; } } return 0; } while (done < count) { if ( nonblock ) { tv.tv_sec = 0; tv.tv_usec = 1; } else { tv.tv_sec = 3600; tv.tv_usec = 0; } FD_ZERO(rfhs); FD_ZERO(wfhs); FD_SET(out, wfhs); if ( in != -1 ) { FD_SET(in, rfhs); } max_fh = in > out ? in : out; if ( (ret = select(max_fh + 1, rfhs, wfhs, NULL, &tv)) == -1 ) return -1; if ( ret > 0 ) { if ( FD_ISSET(out, wfhs) ) { if ( (ret = write(out, buf+done, count-done)) == -1 ) break; if ( ret == 0 ) break; done += ret; } if ( in != -1 && FD_ISSET(in, rfhs) ) { if ( (ret = read(in, tbuf, ROAR_VIO_CMD_BUFSIZE)) == -1 ) { /* error case: can not read on reader -> EOF */ close(in); state->writer.in = in = -1; break; } if ( roar_vio_write(state->next, tbuf, ret) != ret ) return -1; } } if ( nonblock ) break; } return done; } int roar_vio_cmd_sync (struct roar_vio_calls * vio) { struct roar_vio_cmd_state * state = (struct roar_vio_cmd_state *)vio->inst; int newblock = ROAR_SOCKET_BLOCK; int oldblock; int ret = 0; oldblock = state->options & ROAR_VIO_CMD_OPTS_NONBLOCK ? ROAR_SOCKET_NONBLOCK : ROAR_SOCKET_BLOCK; if ( roar_vio_cmd_ctl(vio, ROAR_VIO_CTL_NONBLOCK, &newblock) == -1 ) return -1; if ( roar_vio_cmd_write(vio, NULL, 0) == -1 ) ret = -1; if ( roar_vio_cmd_read(vio, NULL, 0) == -1 ) ret = -1; if ( roar_vio_cmd_ctl(vio, ROAR_VIO_CTL_NONBLOCK, &oldblock) == -1 ) return -1; return ret; } int roar_vio_cmd_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_vio_cmd_state * state = (struct roar_vio_cmd_state *)vio->inst; char buf[1]; ROAR_DBG("roar_vio_cmd_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "cmd"; return 0; break; case ROAR_VIO_CTL_GET_NEXT: *(struct roar_vio_calls **)data = state->next; return -1; break; case ROAR_VIO_CTL_GET_FH: return -1; break; case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: // if ( !state->reader.opened ) { //for (i = 0; i < 128; i++) roar_vio_cmd_read(vio, buf, 0); // } if ( state->reader.opened ) { ROAR_DBG("roar_vio_cmd_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_READ_FH(0x%.8x), data=%p) = 0 // fh=%i", vio, cmd, data, state->reader.in); *(int*)data = state->reader.in; return 0; } return -1; break; case ROAR_VIO_CTL_GET_WRITE_FH: return -1; break; case ROAR_VIO_CTL_NONBLOCK: state->options |= ROAR_VIO_CMD_OPTS_NONBLOCK; if ( *(int*)data == ROAR_SOCKET_BLOCK ) state->options -= ROAR_VIO_CMD_OPTS_NONBLOCK; _LIBROAR_IGNORE_RET(roar_vio_ctl(state->next, cmd, data)); // this should help, but may not necessarily. break; default: return -1; } return 0; } #endif // MISC: int roar_vio_open_gzip(struct roar_vio_calls * calls, struct roar_vio_calls * dst, int level) { roar_debug_warn_obsolete("roar_vio_open_gzip", "roar_vio_open_zlib", NULL); #ifdef ROAR_HAVE_LIBZ return roar_vio_open_zlib(calls, dst, level, 1); #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } int roar_vio_open_gpg(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw, int wronly, char * opts, int options) { #if defined(ROAR_HAVE_BIN_GPG) && !defined(ROAR_WITHOUT_VIO_CMD) char command[1024]; char para[1024] = {0}; char * bin_gpg; int pwpipe[2]; int ret; /* #define ROAR_VIO_PGP_OPTS_NONE 0x00 #define ROAR_VIO_PGP_OPTS_ASCII 0x01 #define ROAR_VIO_PGP_OPTS_SIGN 0x02 #define ROAR_VIO_PGP_OPTS_TEXTMODE 0x04 */ if ( options & ROAR_VIO_PGP_OPTS_ASCII ) strncat(para, "--armor ", 16); if ( options & ROAR_VIO_PGP_OPTS_SIGN ) strncat(para, "--sign ", 16); if ( options & ROAR_VIO_PGP_OPTS_TEXTMODE ) strncat(para, "--textmode ", 16); bin_gpg = roar_libroar_get_path("bin-gpg", 0, NULL, NULL); if ( bin_gpg == NULL ) return -1; if ( pw != NULL ) { if ( pipe(pwpipe) == -1 ) { roar_mm_free_noerror(bin_gpg); return -1; } snprintf(command, sizeof(command), "%s --batch --no-verbose --quiet --passphrase-repeat 0 --passphrase-fd %i %s %s", bin_gpg, pwpipe[0], para, opts); write(pwpipe[1], pw, strlen(pw)); close(pwpipe[1]); } else { snprintf(command, sizeof(command), "%s --no-verbose --quiet %s %s", bin_gpg, para, opts); } roar_mm_free(bin_gpg); if ( wronly ) { ret = roar_vio_open_cmd(calls, dst, NULL, command, 0); } else { ret = roar_vio_open_cmd(calls, dst, command, NULL, 0); } if ( pw != NULL ) close(pwpipe[0]); return ret; #else return -1; #endif } int roar_vio_open_pgp_decrypt(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw) { return roar_vio_open_gpg(calls, dst, pw, 0, "-d", ROAR_VIO_PGP_OPTS_NONE); } int roar_vio_open_pgp_store(struct roar_vio_calls * calls, struct roar_vio_calls * dst, int options) { return roar_vio_open_gpg(calls, dst, NULL, 1, "--store", options); } int roar_vio_open_pgp_encrypt_sym(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw, int options) { return roar_vio_open_gpg(calls, dst, pw, 1, "--symmetric", options); } int roar_vio_open_pgp_encrypt_pub(struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * pw, int options, char * recipient) { char buf[1024]; snprintf(buf, sizeof(buf), "-e -r %s", recipient); return roar_vio_open_gpg(calls, dst, pw, 1, buf, options); } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_dstr.c��������������������������������������������������������������0000644�0001750�0001750�00000075653�12264733550�016135� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_dstr.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifndef ROAR_WITHOUT_VIO_DSTR static struct _roar_vio_dstr_type { const int id; const char * name; int (* setdef) (struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next); int (* openvio)(struct roar_vio_calls * calls, struct roar_vio_calls * dst, struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next); int pdeftype[16]; } _roar_vio_dstr_objs[] = { /* grep '^#define ROAR_VIO_DSTR_OBJT_' vio_dstr.h | cut -d' ' -f2 | while read objt; do name=`cut -d_ -f5,6,7,8,9,10 <<<$objt | tr A-Z a-z`; echo -e " {$objt,\t \"$name\","; echo " {ROAR_VIO_DEF_TYPE_EOL}},"; done; */ {ROAR_VIO_DSTR_OBJT_FILE, "file", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_FH, "fh", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_FD, "fd", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SOCKETFH, "socketfh", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_PASS, "pass", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_RE, "re", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_JUMBO, "jumbo", /* TODO */ NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_EXEC, "exec", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, /* special devices */ {ROAR_VIO_DSTR_OBJT_NULL, "null", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_ZERO, "zero", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_FULL, "full", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SOCKET, "socket", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_UNIX, "unix", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_DECNET, "decnet", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_TCP, "tcp", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_UDP, "udp", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_TCP6, "tcp6", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_UDP6, "udp6", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SOCKS, "socks", roar_vio_proxy_setdef, roar_vio_proxy_openvio, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SOCKS4, "socks4", roar_vio_proxy_setdef, roar_vio_proxy_openvio, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SOCKS4A, "socks4a", roar_vio_proxy_setdef, roar_vio_proxy_openvio, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SOCKS4D, "socks4d", roar_vio_proxy_setdef, roar_vio_proxy_openvio, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SOCKS5, "socks5", roar_vio_proxy_setdef, roar_vio_proxy_openvio, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SSH, "ssh", roar_vio_proxy_setdef, roar_vio_proxy_openvio, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_HTTP09, "http09", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_HTTP10, "http10", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_HTTP11, "http11", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_HTTP, "http", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_GOPHER, "gopher", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_GOPHER_PLUS,"gopher+", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_ICY, "icy", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_RTP2, "rtp2", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_RTP, "rtp", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_GZIP, "gzip", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_ZLIB, "zlib", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_BZIP2, "bzip2", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_PGP, "pgp", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_PGP_ENC, "pgp_enc", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_PGP_STORE, "pgp_store", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SSL1, "ssl1", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SSL2, "ssl2", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SSL3, "ssl3", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_TLS, "tls", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SSLTLS, "ssltls", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, /* Random numbers */ {ROAR_VIO_DSTR_OBJT_NRANDOM, "nrandom", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_URANDOM, "urandom", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_SRANDOM, "srandom", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_TRANSCODE, "transcode", /* TODO */ NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_RAUM, "raum", /* TODO */ NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_OGG, "ogg", /* TODO */ NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_TAR, "tar", /* TODO */ NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_MAGIC, "magic", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_TANTALOS, "tantalos", NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_INTERNAL, "INTERNAL", NULL, NULL, {ROAR_VIO_DEF_TYPE_FILE, ROAR_VIO_DEF_TYPE_SOCKET, ROAR_VIO_DEF_TYPE_FH, ROAR_VIO_DEF_TYPE_SOCKETFH, ROAR_VIO_DEF_TYPE_EOL}}, {ROAR_VIO_DSTR_OBJT_EOL, NULL, NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}} }; int roar_vio_dstr_get_type(const char * str) { int i; for (i = 0; _roar_vio_dstr_objs[i].id != ROAR_VIO_DSTR_OBJT_EOL; i++) { if ( strcasecmp(_roar_vio_dstr_objs[i].name, str) == 0 ) return _roar_vio_dstr_objs[i].id; } return -1; } struct _roar_vio_dstr_type * roar_vio_dstr_get_by_type (int type) { int i; for (i = 0; _roar_vio_dstr_objs[i].id != ROAR_VIO_DSTR_OBJT_EOL; i++) { if ( _roar_vio_dstr_objs[i].id == type ) return &(_roar_vio_dstr_objs[i]); } return NULL; } const char * roar_vio_dstr_get_name(const int type) { struct _roar_vio_dstr_type * ret; if ( (ret = roar_vio_dstr_get_by_type(type)) != NULL ) return ret->name; if ( type == ROAR_VIO_DSTR_OBJT_EOL ) return "<<EOL>>"; return NULL; } int roar_vio_dstr_register_type(int type, char *name, int (*setdef) (struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next), int (*openvio)(struct roar_vio_calls * calls, struct roar_vio_calls * dst, struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next)) { struct _roar_vio_dstr_type * ret; if ( (ret = roar_vio_dstr_get_by_type(type)) == NULL ) /* we can currently not register new types */ return -1; // check if things are allready set, we do not want to allow overwrite here. if ( setdef != NULL && ret->setdef != NULL ) return -1; if ( openvio != NULL && ret->openvio != NULL ) return -1; if ( setdef != NULL ) ret->setdef = setdef; if ( openvio != NULL ) ret->openvio = openvio; return 0; } static void _roar_vio_dstr_init_otherlibs (void) { roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroardsp", NULL); roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroareio", NULL); roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroarlight", NULL); roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroarmidi", NULL); } #endif int roar_vio_dstr_init_defaults (struct roar_vio_defaults * def, int type, int o_flags, mode_t o_mode) { if ( def == NULL ) return -1; memset(def, 0, sizeof(struct roar_vio_defaults)); def->type = type; def->o_flags = o_flags; def->o_mode = o_mode; return 0; } int roar_vio_dstr_init_defaults_c (struct roar_vio_defaults * def, int type, struct roar_vio_defaults * odef, int o_flags) { if ( o_flags < 1 ) o_flags = O_RDONLY; if ( odef == NULL ) { return roar_vio_dstr_init_defaults(def, type, o_flags, 0644); } else { return roar_vio_dstr_init_defaults(def, type, odef->o_flags, odef->o_mode); } } #ifndef ROAR_WITHOUT_VIO_DSTR #ifdef ROAR_HAVE_IO_POSIX static int _open_file(struct roar_vio_calls * calls, const char * filename, int flags, mode_t mode) { int fh; if ( calls == NULL || filename == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } #ifdef ROAR_TARGET_WIN32 flags |= O_BINARY; #endif ROAR_DBG("_open_file(calls=%p, filename='%s', flags=0x%x, mode=%i) = ?", calls, filename, flags, (int)mode); roar_err_clear_all(); if ( (fh = open(filename, flags, mode)) == -1 ) { roar_err_update(); return -1; } if ( roar_vio_open_fh(calls, fh) == -1 ) { close(fh); roar_err_to_errno(); return -1; } roar_err_update(); return 0; } #endif int roar_vio_open_default (struct roar_vio_calls * calls, struct roar_vio_defaults * def, char * opts) { ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s') = ?", calls, def, opts); if ( calls == NULL || def == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } switch (def->type) { case ROAR_VIO_DEF_TYPE_NONE: ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, dummy open", calls, def, opts, (int)def->type); break; #ifdef ROAR_HAVE_IO_POSIX case ROAR_VIO_DEF_TYPE_FILE: ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, file open", calls, def, opts, (int)def->type); if ( _open_file(calls, def->d.file, def->o_flags, def->o_mode) == -1 ) { ROAR_DBG("roar_vio_open_default(*): Can not open file: %i", roar_error); return -1; } break; #endif case ROAR_VIO_DEF_TYPE_SOCKET: ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, socket open", calls, def, opts, (int)def->type); if ( roar_vio_open_def_socket(calls, def, opts) == -1 ) return -1; break; case ROAR_VIO_DEF_TYPE_FH: ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, fh open", calls, def, opts, (int)def->type); if ( roar_vio_open_fh(calls, def->d.fh) == -1 ) return -1; break; case ROAR_VIO_DEF_TYPE_SOCKETFH: ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, socket fh open", calls, def, opts, (int)def->type); if ( roar_vio_open_fh_socket(calls, def->d.fh) == -1 ) return -1; break; default: ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s') = -1 // error=NOTSUP", calls, def, opts); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } return 0; } #endif int roar_vio_open_dstr_simple(struct roar_vio_calls * calls, const char * dstr, int o_flags) { struct roar_vio_defaults def; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, o_flags, 0644) == -1 ) return -1; if ( roar_vio_open_dstr_vio(calls, dstr, &def, 1, NULL) == -1 ) return -1; return 0; } struct roar_vio_calls * roar_vio_open_dstr_simple_new(const char * dstr, int o_flags) { struct roar_vio_calls * ret = roar_mm_malloc(sizeof(struct roar_vio_calls)); int err; if ( ret == NULL ) return NULL; if ( roar_vio_open_dstr_simple(ret, dstr, o_flags) == -1 ) { err = roar_error; roar_mm_free(ret); roar_error = err; return NULL; } ret->flags |= ROAR_VIO_FLAGS_FREESELF; return ret; } int roar_vio_open_dstr (struct roar_vio_calls * calls, const char * dstr, struct roar_vio_defaults * def, int dnum) { return roar_vio_open_dstr_vio(calls, dstr, def, dnum, NULL); } #define _ret(x) do { int _err = roar_error; roar_mm_free(dstr_copy); roar_error = _err; roar_err_to_errno(); return (x); } while (0) int roar_vio_open_dstr_vio(struct roar_vio_calls * calls, const char * dstr, struct roar_vio_defaults * def, int dnum, struct roar_vio_calls * vio) { #ifndef ROAR_WITHOUT_VIO_DSTR struct roar_vio_dstr_chain chain[ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN]; char * dstr_copy; char * next; char * this; char * name; char * opts; char * dst; char * c; int inopts; int type; int cc = 1; // current chain element if ( calls == NULL || dstr == NULL ) return -1; if ( dnum != 0 && def == NULL ) return -1; if ( (dstr_copy = roar_mm_strdup(dstr)) == NULL ) return -1; memset(chain, 0, sizeof(chain)); chain[0].type = ROAR_VIO_DSTR_OBJT_INTERNAL; next = dstr_copy; while (next != NULL) { if ( (cc+1) == ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN ) { _ret(-1); } this = next; next = strstr(next, "##"); if (next != NULL) { *next = 0; next += 2; } // we have the current token in 'this'. opts = NULL; dst = NULL; if ( strstr(this, ":") != NULL ) { name = this; inopts = 0; for (c = this; *c != 0; c++) { if ( *c == '[' ) { *c = 0; opts = c + 1; inopts = 1; } else if ( *c == ']' && inopts ) { *c = 0; inopts = 0; } else if ( *c == ':' && !inopts ) { *c = 0; dst = *(c+1) == 0 ? NULL : c + 1; break; } } } else { // we need to guess that this is here... // currently we guess this is a file in all cases name = "file"; dst = this; } ROAR_DBG("roar_vio_open_dstr_vio(*): name='%s', opts='%s', dst='%s'", name, opts, dst); if ( (type = roar_vio_dstr_get_type(name)) == -1 ) { _ret(-1); } ROAR_DBG("roar_vio_open_dstr_vio(*): type=0x%.4x(%s)", type, roar_vio_dstr_get_name(type)); chain[cc].type = type; chain[cc].opts = opts; chain[cc].dst = dst; chain[cc].def = NULL; chain[cc].vio = NULL; chain[cc].need_vio = -1; cc++; } chain[cc].type = ROAR_VIO_DSTR_OBJT_EOL; ROAR_DBG("roar_vio_open_dstr_vio(*): chain=%p", chain); if ( roar_vio_dstr_parse_opts(chain) == -1 ) { _ret(-1); } if ( roar_vio_dstr_set_defaults(chain, cc, def, dnum) == -1 ) { _ret(-1); } if ( roar_vio_dstr_build_chain(chain, calls, vio) == -1 ) { _ret(-1); } _ret(0); #else return -1; #endif } #undef _ret #ifndef ROAR_WITHOUT_VIO_DSTR int roar_vio_dstr_parse_opts(struct roar_vio_dstr_chain * chain) { if ( chain == NULL ) return -1; // TODO: we should add some code here later... return 0; } int roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain, int len, struct roar_vio_defaults * def, int dnum) { struct _roar_vio_dstr_type * type; struct roar_vio_dstr_chain * c, * next; int i; int tmp[8]; if ( chain == NULL ) return -1; if ( def == NULL && dnum != 0 ) return -1; if ( dnum > 1 ) /* currently not supported */ return -1; if ( dnum == 0 ) def = NULL; chain[len].def = def; for (i = len; i >= 0; i--) { c = &chain[i]; if ( i > 0 ) { next = &chain[i-1]; } else { next = NULL; if ( c->type != ROAR_VIO_DSTR_OBJT_INTERNAL ) return -1; } memset(tmp, 0, sizeof(tmp)); ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s)", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type)); ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): c->def=%p, c->def->type=%i", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type), c->def, c->def == NULL ? -1 : c->def->type); c->need_vio = 1; switch (c->type) { case ROAR_VIO_DSTR_OBJT_INTERNAL: c->need_vio = 0; break; case ROAR_VIO_DSTR_OBJT_EOL: tmp[0] = 1; case ROAR_VIO_DSTR_OBJT_PASS: case ROAR_VIO_DSTR_OBJT_RE: case ROAR_VIO_DSTR_OBJT_RTP2: // we currently only forward the defs case ROAR_VIO_DSTR_OBJT_GZIP: case ROAR_VIO_DSTR_OBJT_ZLIB: case ROAR_VIO_DSTR_OBJT_BZIP2: case ROAR_VIO_DSTR_OBJT_PGP: case ROAR_VIO_DSTR_OBJT_PGP_ENC: case ROAR_VIO_DSTR_OBJT_PGP_STORE: case ROAR_VIO_DSTR_OBJT_SSL1: case ROAR_VIO_DSTR_OBJT_SSL2: case ROAR_VIO_DSTR_OBJT_SSL3: case ROAR_VIO_DSTR_OBJT_TLS: case ROAR_VIO_DSTR_OBJT_MAGIC: if ( tmp[0] ) c->need_vio = 0; next->def = c->def; break; case ROAR_VIO_DSTR_OBJT_NULL: case ROAR_VIO_DSTR_OBJT_ZERO: case ROAR_VIO_DSTR_OBJT_FULL: case ROAR_VIO_DSTR_OBJT_NRANDOM: case ROAR_VIO_DSTR_OBJT_TANTALOS: next->def = &(next->store_def); roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_NONE, NULL, -1); break; case ROAR_VIO_DSTR_OBJT_FILE: if ( c->dst == NULL ) /* should we allow multible cascaed file: objects? */ return -1; c->need_vio = 0; next->def = &(next->store_def); roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_FILE, c->def, -1); if ( c->dst[0] == '/' && c->dst[1] == '/' ) { next->def->d.file = c->dst + 1; } else { next->def->d.file = c->dst; } break; case ROAR_VIO_DSTR_OBJT_FH: tmp[0] = 1; case ROAR_VIO_DSTR_OBJT_SOCKETFH: c->need_vio = 0; next->def = &(next->store_def); if ( c->def != NULL ) { tmp[2] = c->def->o_flags; tmp[3] = c->def->o_mode; } else { tmp[2] = O_RDONLY; tmp[3] = 0644; } if ( !strcasecmp(c->dst, "stdin") ) { tmp[1] = ROAR_STDIN; tmp[2] = O_RDONLY; } else if ( !strcasecmp(c->dst, "stdout") ) { tmp[1] = ROAR_STDOUT; tmp[2] = O_WRONLY; } else if ( !strcasecmp(c->dst, "stderr") ) { tmp[1] = ROAR_STDERR; tmp[2] = O_WRONLY; } else { if ( sscanf(c->dst, "%i", &tmp[1]) != 1 ) return -1; } roar_vio_dstr_init_defaults(next->def, tmp[0] ? ROAR_VIO_DEF_TYPE_FH : ROAR_VIO_DEF_TYPE_SOCKETFH, tmp[2], tmp[3]); next->def->d.fh = tmp[1]; break; #ifdef ROAR_HAVE_UNIX case ROAR_VIO_DSTR_OBJT_UNIX: c->need_vio = 0; next->def = &(next->store_def); if ( c->dst == NULL ) { // we don't have a destination? -> slow way if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_UNIX, SOCK_STREAM, c->def) == -1 ) return -1; } else { // we have a destination? -> fast way if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_unix_def(next->def, c->dst) == -1 ) return -1; } break; #endif case ROAR_VIO_DSTR_OBJT_SOCKET: c->need_vio = 0; next->def = &(next->store_def); if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(next->def, c->dst, -1, SOCK_STREAM, c->def) == -1 ) return -1; break; #ifdef ROAR_HAVE_LIBDNET case ROAR_VIO_DSTR_OBJT_DECNET: c->need_vio = 0; next->def = &(next->store_def); if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_DECnet, SOCK_STREAM, c->def) == -1 ) return -1; break; #endif #ifdef ROAR_HAVE_IPV4 case ROAR_VIO_DSTR_OBJT_TCP: c->need_vio = 0; next->def = &(next->store_def); if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_STREAM, c->def) == -1 ) return -1; break; case ROAR_VIO_DSTR_OBJT_UDP: c->need_vio = 0; next->def = &(next->store_def); if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_DGRAM, c->def) == -1 ) return -1; break; #endif #ifdef ROAR_HAVE_IPV6 case ROAR_VIO_DSTR_OBJT_TCP6: c->need_vio = 0; next->def = &(next->store_def); if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_STREAM, c->def) == -1 ) return -1; break; case ROAR_VIO_DSTR_OBJT_UDP6: c->need_vio = 0; next->def = &(next->store_def); if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_DGRAM, c->def) == -1 ) return -1; break; #endif case ROAR_VIO_DSTR_OBJT_HTTP09: case ROAR_VIO_DSTR_OBJT_HTTP10: case ROAR_VIO_DSTR_OBJT_HTTP11: c->need_vio = 1; next->def = &(next->store_def); if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 ) return -1; break; case ROAR_VIO_DSTR_OBJT_GOPHER: case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS: c->need_vio = 1; next->def = &(next->store_def); if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 ) return -1; break; case ROAR_VIO_DSTR_OBJT_ICY: c->need_vio = 1; next->def = &(next->store_def); if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_ICY, c->def) == -1 ) return -1; break; default: if ( (type = roar_vio_dstr_get_by_type(c->type)) == NULL ) { return -1; } if ( type->setdef == NULL ) _roar_vio_dstr_init_otherlibs(); if ( type->setdef == NULL ) { return -1; } if ( type->setdef(c, next) == -1 ) { return -1; } } if ( next != NULL ) { ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def=%p, next->def->type=%i", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type), next->def, next->def == NULL ? -1 : next->def->type); if ( next->def != NULL ) { ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def->o_flags=%i", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type), next->def->o_flags); } } else { ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next=NULL", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type)); } } ROAR_DBG("roar_vio_dstr_set_defaults(*) = 0"); return 0; } #define _ret(x) do { int _err = roar_error; roar_vio_close(calls); roar_error = _err; roar_err_to_errno(); ROAR_DBG("roar_vio_dstr_build_chain(*) = %i", (x)); return (x); } while(0) int roar_vio_dstr_build_chain(struct roar_vio_dstr_chain * chain, struct roar_vio_calls * calls, struct roar_vio_calls * vio) { struct _roar_vio_dstr_type * type; struct roar_vio_dstr_chain * c; struct roar_vio_defaults * def; struct roar_vio_calls * tc, * prev; int i; ROAR_DBG("roar_vio_dstr_build_chain(*) = ?"); if ( chain == NULL || calls == NULL ) return -1; if ( roar_vio_open_stack2(calls, NULL) == -1 ) return -1; ROAR_DBG("roar_vio_dstr_build_chain(*): chain=%p", chain); if ( (def = chain->def) != NULL ) { if ( (tc = roar_mm_malloc(sizeof(struct roar_vio_calls))) == NULL ) { _ret(-1); } if ( roar_vio_clear_calls(tc) == -1 ) { roar_mm_free(tc); _ret(-1); } if ( roar_vio_stack_add(calls, tc) == -1 ) { _ret(-1); } if ( chain->opts == NULL ) { if ( chain[1].type != ROAR_VIO_DSTR_OBJT_EOL ) { chain->opts = chain[1].opts; } } if ( roar_vio_open_default(tc, def, chain->opts) == -1 ) { _ret(-1); } prev = tc; } else { prev = vio; } for (i = 0; (c = &(chain[i]))->type != ROAR_VIO_DSTR_OBJT_EOL; i++) { ROAR_DBG("roar_vio_dstr_build_chain(*): i=%i, c->type=0x%.4x(%s): need_vio=%i, def(%p)->o_flags=%i", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type), c->need_vio, c->def, c->def != NULL ? c->def->o_flags : -1); if ( c->need_vio ) { if ( (tc = roar_mm_malloc(sizeof(struct roar_vio_calls))) == NULL ) { _ret(-1); } if ( roar_vio_clear_calls(tc) == -1 ) { roar_mm_free(tc); _ret(-1); } if ( roar_vio_stack_add(calls, tc) == -1 ) { _ret(-1); } switch (c->type) { case ROAR_VIO_DSTR_OBJT_PASS: if ( roar_vio_open_pass(tc, prev) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_RE: if ( roar_vio_open_re(tc, prev) == -1 ) { _ret(-1); } break; #ifdef ROAR_HAVE_LIBZ case ROAR_VIO_DSTR_OBJT_GZIP: if ( roar_vio_open_zlib(tc, prev, -1, 1) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_ZLIB: if ( roar_vio_open_zlib(tc, prev, -1, 0) == -1 ) { _ret(-1); } break; #endif case ROAR_VIO_DSTR_OBJT_BZIP2: case ROAR_VIO_DSTR_OBJT_PGP: if ( roar_vio_open_pgp_decrypt(tc, prev, NULL) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_HTTP09: case ROAR_VIO_DSTR_OBJT_HTTP10: case ROAR_VIO_DSTR_OBJT_HTTP11: if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_GOPHER: case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS: if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_ICY: if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_ICY, c->def) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_RTP2: if ( roar_vio_open_rtp(tc, prev, c->dst, c->def) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_PGP_ENC: case ROAR_VIO_DSTR_OBJT_PGP_STORE: if ( roar_vio_open_pgp_store(tc, prev, ROAR_VIO_PGP_OPTS_NONE) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_TANTALOS: if ( roar_vio_open_tantalos(tc, prev, c->dst, c->def) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_NULL: case ROAR_VIO_DSTR_OBJT_ZERO: case ROAR_VIO_DSTR_OBJT_FULL: case ROAR_VIO_DSTR_OBJT_NRANDOM: if ( roar_vio_open_misc_by_name(tc, roar_vio_dstr_get_name(c->type)) == -1 ) { _ret(-1); } break; case ROAR_VIO_DSTR_OBJT_SSL1: case ROAR_VIO_DSTR_OBJT_SSL2: case ROAR_VIO_DSTR_OBJT_SSL3: case ROAR_VIO_DSTR_OBJT_TLS: case ROAR_VIO_DSTR_OBJT_MAGIC: _ret(-1); break; default: if ( (type = roar_vio_dstr_get_by_type(c->type)) == NULL ) { _ret(-1); } if ( type->openvio == NULL ) _roar_vio_dstr_init_otherlibs(); if ( type->openvio == NULL ) { _ret(-1); } if ( type->openvio(tc, prev, c, &(chain[i+1])) == -1 ) { _ret(-1); } } prev = tc; } // else we can skip to the next :) } ROAR_DBG("roar_vio_dstr_build_chain(*) = 0"); return 0; } #undef _ret static inline ssize_t __libroar_dir_part_len(char * p, size_t len) { ssize_t i, c; c = -1; for (i = 0; i < len; i++, p++) if ( *p == '/' ) c = i; return c; } char * roar_vio_dstr_cat(char * buffer, ssize_t bufferlen, const struct roar_vio_dstr_pathelement * elements, size_t elementslen) { size_t needed = 0; size_t rootelement = 0; ssize_t ret; char * p; size_t i; if ( buffer == NULL ) bufferlen = -1; if ( elementslen == 0 ) { if ( bufferlen == -1 ) { if ( (buffer = roar_mm_malloc(2)) == NULL ) return NULL; bufferlen = 2; } if ( bufferlen >= 2 ) { buffer[0] = '.'; buffer[1] = 0; return buffer; } else { roar_err_set(ROAR_ERROR_NOSPC); return NULL; } } if ( elements == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } for (i = 0; i < elementslen; i++) { if ( elements[i].dstr == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } if ( !(elements[i].flags & ROAR_VIO_DSTR_PEF_ALLOW_MULTI) && strstr(elements[i].dstr, "##") != NULL ) { roar_err_set(ROAR_ERROR_INVAL); return NULL; } if ( !(elements[i].flags & ROAR_VIO_DSTR_PEF_ALLOW_PARENT) && strstr(elements[i].dstr, "..") != NULL ) { roar_err_set(ROAR_ERROR_INVAL); return NULL; } if ( strstr(elements[i].dstr, "##") != NULL ) { roar_err_set(ROAR_ERROR_NOTSUP); return NULL; } if ( strstr(elements[i].dstr, ":") != NULL ) { if ( !(elements[i].flags & ROAR_VIO_DSTR_PEF_ALLOW_ABSOLUTE) ) { roar_err_set(ROAR_ERROR_INVAL); return NULL; } rootelement = i; needed = 0; } needed += roar_mm_strlen(elements[i].dstr); } elements += rootelement; elementslen -= rootelement; if ( elementslen == 1 ) { if ( bufferlen == -1 ) { bufferlen = needed+1; if ( (buffer = roar_mm_malloc(bufferlen)) == NULL ) return NULL; } if ( bufferlen >= (elementslen + 1) ) { memcpy(buffer, elements[0].dstr, needed+1); return buffer; } else { roar_err_set(ROAR_ERROR_NOSPC); return NULL; } } needed += elementslen * 2; // for '.', '/' and '\0'. if ( bufferlen == -1 ) { bufferlen = needed; if ( (buffer = roar_mm_malloc(bufferlen)) == NULL ) return NULL; } if ( bufferlen < needed ) { roar_err_set(ROAR_ERROR_NOSPC); return NULL; } p = buffer; for (i = 0; i < elementslen; i++) { ret = roar_mm_strlen(elements[i].dstr); memcpy(p, elements[i].dstr, ret); if ( i == (elementslen-1) || elements[i].flags & ROAR_VIO_DSTR_PEF_IS_DIR ) { p += ret; } else { ret = __libroar_dir_part_len(p, ret); if ( ret == -1 ) { *p = '.'; p++; } else { p += ret; } } *p = '/'; p++; } p--; *p = 0; return buffer; } #endif //ll �������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_jumbo.c�������������������������������������������������������������0000644�0001750�0001750�00000011220�12264733550�016251� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_jumbo.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_jumbo (struct roar_vio_calls * calls, struct roar_vio_calls * vio, size_t buffersize) { struct roar_vio_jumbo * self; if ( (self = roar_mm_malloc(sizeof(struct roar_vio_jumbo))) == NULL ) { return -1; } memset(self, 0, sizeof(struct roar_vio_jumbo)); self->backend = vio; if ( roar_buffer_new(&(self->buffer), buffersize) == -1 ) { roar_mm_free(self); return -1; } memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->inst = self; calls->close = roar_vio_jumbo_close; calls->read = roar_vio_jumbo_read; calls->write = roar_vio_jumbo_write; calls->lseek = roar_vio_jumbo_lseek; calls->sync = roar_vio_jumbo_sync; calls->ctl = roar_vio_jumbo_ctl; return 0; } int roar_vio_jumbo_close (struct roar_vio_calls * vio) { struct roar_vio_jumbo * self = vio->inst; if ( roar_vio_jumbo_sync(vio) == -1 ) return -1; roar_buffer_free(self->buffer); roar_mm_free(self); return 0; } ssize_t roar_vio_jumbo_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_jumbo * self = vio->inst; return roar_vio_read(self->backend, buf, count); } ssize_t roar_vio_jumbo_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_jumbo * self = vio->inst; size_t buflen; void * data; ROAR_DBG("roar_vio_jumbo_write(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (unsigned long) count); if ( roar_buffer_get_len(self->buffer, &buflen) == -1 ) return -1; ROAR_DBG("roar_vio_jumbo_write(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (unsigned long) count); if ( roar_buffer_get_data(self->buffer, &data) == -1 ) return -1; ROAR_DBG("roar_vio_jumbo_write(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (unsigned long) count); if ( (self->pos + count) > buflen ) { if ( roar_vio_jumbo_sync(vio) == -1 ) return -1; // in case we write something that is longer than the buffer if ( count > buflen ) { return roar_vio_write(self->backend, data, count); } memcpy(data, buf, count); self->pos = count; } else { memcpy(data + self->pos, buf, count); self->pos += count; } ROAR_DBG("roar_vio_jumbo_write(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (unsigned long) count); return count; } roar_off_t roar_vio_jumbo_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { struct roar_vio_jumbo * self = vio->inst; if ( roar_vio_jumbo_sync(vio) == -1 ) return (roar_off_t) -1; return roar_vio_lseek(self->backend, offset, whence); } int roar_vio_jumbo_sync (struct roar_vio_calls * vio) { struct roar_vio_jumbo * self = vio->inst; void * data; if ( self->pos == 0 ) return 0; if ( roar_buffer_get_data(self->buffer, &data) == -1 ) return -1; // TODO: do this a bit more intelergent (RE?) if ( roar_vio_write(self->backend, data, self->pos) != (ssize_t)self->pos ) return -1; self->pos = 0; return 0; } int roar_vio_jumbo_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_vio_jumbo * self = vio->inst; switch (cmd) { case ROAR_VIO_CTL_NONBLOCK: return roar_vio_ctl(self->backend, cmd, data); break; } roar_err_set(ROAR_ERROR_BADRQC); return -1; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_magic.c�������������������������������������������������������������0000644�0001750�0001750�00000006477�12264733550�016237� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #if 0 static int roar_vio_magic_close (struct roar_vio_calls * vio); static ssize_t roar_vio_magic_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_magic * self = (struct roar_vio_magic *)(vio->inst); struct roar_buffer * inp; void * calls; size_t len; if (self == NULL) return -1; if ( roar_stack_get_cur(&(self->vios), &calls) == -1 ) return -1; inp = self->inp; if ( roar_buffer_get_len(inp, &len) == -1 ) return -1; if ( len ) { len = len > count ? count : len; if ( roar_buffer_shift_out(&inp, buf, &len) == -1 ) return -1; } count -= len; buf += len; if ( count ) { if ( (count = roar_vio_read((struct roar_vio_calls*) calls, buf, count)) == -1 ) return len; return len+count; } return len; } static ssize_t roar_vio_magic_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_magic * self = (struct roar_vio_magic *)(vio->inst); void * calls; if (self == NULL) return -1; if ( roar_stack_get_cur(&(self->vios), &calls) == -1 ) return -1; return roar_vio_write((struct roar_vio_calls*)calls, buf, count); } static roar_off_t roar_vio_magic_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { struct roar_vio_magic * self = (struct roar_vio_magic *)(vio->inst); void * calls; if (self == NULL) return -1; if ( roar_stack_get_cur(&(self->vios), &calls) == -1 ) return -1; return roar_vio_lseek((struct roar_vio_calls*)calls, offset, whence); } static int roar_vio_magic_sync (struct roar_vio_calls * vio) { struct roar_vio_magic * self = (struct roar_vio_magic *)(vio->inst); void * calls; if (self == NULL) return -1; if ( roar_stack_get_cur(&(self->vios), &calls) == -1 ) return -1; return roar_vio_sync((struct roar_vio_calls*)calls); } int roar_vio_open_magic (struct roar_vio_calls * calls, struct roar_vio_calls * dst, int * codec); #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_misc.c��������������������������������������������������������������0000644�0001750�0001750�00000013012�12264733550�016071� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_misc.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static ssize_t roar_vio_misc_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_misc * self = vio->inst; if ( self->read == NULL ) return -1; return self->read(buf, count, vio, self); } static ssize_t roar_vio_misc_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_misc * self = vio->inst; if ( self->write == NULL ) return -1; return self->write(buf, count, vio, self); } static roar_off_t roar_vio_misc_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { (void)vio, (void)offset, (void)whence; return 0; } static int roar_vio_misc_sync (struct roar_vio_calls * vio) { (void)vio; return 0; } static int roar_vio_misc_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_vio_misc * self; if ( vio == NULL || cmd == -1 ) return -1; self = vio->inst; switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(const char**)data = self->name; return 0; break; case ROAR_VIO_CTL_SET_NOSYNC: vio->sync = NULL; return 0; break; case ROAR_VIO_CTL_NONBLOCK: if ( self->support_nonblocking ) return 0; if ( *(int*)data == ROAR_SOCKET_BLOCK ) return 0; return -1; break; } return -1; } static int roar_vio_misc_close (struct roar_vio_calls * vio) { (void)vio; return 0; } int roar_vio_open_misc (struct roar_vio_calls * calls, const struct roar_vio_misc * callbacks) { if ( calls == NULL || callbacks == NULL ) return -1; memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->read = roar_vio_misc_read; calls->write = roar_vio_misc_write; calls->lseek = roar_vio_misc_lseek; calls->sync = roar_vio_misc_sync; calls->ctl = roar_vio_misc_ctl; calls->close = roar_vio_misc_close; calls->inst = (void*)callbacks; return 0; } static ssize_t roar_vio_misc_op_return_len (void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks) { (void)buf, (void)vio, (void)callbacks; return len; } static ssize_t roar_vio_misc_op_return_zero(void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks) { (void)buf, (void)len, (void)vio, (void)callbacks; return 0; } static ssize_t roar_vio_misc_op_zero(void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks) { (void)vio, (void)callbacks; memset(buf, 0, len); return len; } static ssize_t roar_vio_misc_op_full(void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks) { (void)buf, (void)len, (void)vio, (void)callbacks; roar_err_set(ROAR_ERROR_NOSPC); return -1; } static ssize_t roar_vio_misc_op_random_nonce(void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks) { (void)vio, (void)callbacks; if ( roar_random_gen_nonce(buf, len) == -1 ) return -1; return len; } static ssize_t roar_vio_misc_op_random_salt_nonce(void * buf, size_t len, struct roar_vio_calls * vio, struct roar_vio_misc * callbacks) { (void)vio, (void)callbacks; if ( roar_random_salt_nonce(buf, len) == -1 ) return -1; return len; } static const struct roar_vio_misc libroar_vio_miscs[] = { {.name = "null", .support_nonblocking = 1, .read = roar_vio_misc_op_return_zero, .write = roar_vio_misc_op_return_len}, {.name = "full", .support_nonblocking = 1, .read = roar_vio_misc_op_return_zero, .write = roar_vio_misc_op_full}, {.name = "zero", .support_nonblocking = 1, .read = roar_vio_misc_op_zero, .write = roar_vio_misc_op_return_len}, {.name = "nrandom", .support_nonblocking = 1, .read = roar_vio_misc_op_random_nonce, .write = roar_vio_misc_op_random_salt_nonce} }; int roar_vio_open_misc_by_name(struct roar_vio_calls * calls, const char * name) { size_t i; if ( calls == NULL || name == NULL ) return -1; for (i = 0; i < (sizeof(libroar_vio_miscs)/sizeof(*libroar_vio_miscs)); i++) if ( !strcasecmp(name, libroar_vio_miscs[i].name) ) return roar_vio_open_misc(calls, &(libroar_vio_miscs[i])); return -1; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_ops.c���������������������������������������������������������������0000644�0001750�0001750�00000006576�12264733551�015761� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_ops.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define ROAR_VIO_COPY_BUFSIZE 1024 #define BUFMAX 65536 #ifdef ROAR_HAVE_IO_POSIX #define _CAN_OPERATE #endif #ifdef _CAN_OPERATE static inline ssize_t _send_file_raw (int out, int in) { ssize_t r = 0; #ifdef ROAR_HAVE_LINUX_SENDFILE ssize_t ret; #endif #if defined(__linux__) && defined(ROAR_HAVE_IPV4) int cork_new = 1, cork_old; socklen_t cork_len = sizeof(int); if ( getsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, &cork_len) == -1 ) { cork_old = -1; } else { setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_new, sizeof(int)); } #endif roar_debug_warn_obsolete("roar_file_send_raw", "roar_vio_copy_data", NULL); #ifdef ROAR_HAVE_LINUX_SENDFILE while ((ret = sendfile(out, in, NULL, BUFMAX)) > 0) r += ret; #endif // TODO: try mmap here! #if defined(__linux__) && defined(ROAR_HAVE_IPV4) if ( cork_old != -1 ) setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, cork_len); #endif return r; } #endif ssize_t roar_vio_copy_data (struct roar_vio_calls * out, struct roar_vio_calls * in) { char buf[ROAR_VIO_COPY_BUFSIZE]; ssize_t len; ssize_t done = 0; #ifdef _CAN_OPERATE int in_fh, out_fh; #endif ROAR_DBG("roar_vio_copy_data(out=%p, in=%p) = ?", out, in); if ( out == NULL || in == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } #ifdef _CAN_OPERATE if ( roar_vio_ctl(in, ROAR_VIO_CTL_GET_READ_FH, &in_fh) == 0 ) if ( roar_vio_ctl(out, ROAR_VIO_CTL_GET_WRITE_FH, &out_fh) == 0 ) _send_file_raw(out_fh, in_fh); #endif roar_err_clear_all(); while ((len = roar_vio_read(in, buf, ROAR_VIO_COPY_BUFSIZE)) > 0) { if ( roar_vio_write(out, buf, len) != len ) return -1; done += len; ROAR_DBG("roar_vio_copy_data(out=%p, in=%p): len=%li, done=%li", out, in, (long int)len, (long int)done); } ROAR_DBG("roar_vio_copy_data(out=%p, in=%p): len=%li, done=%li", out, in, (long int)len, (long int)done); roar_err_clear_all(); ROAR_DBG("roar_vio_copy_data(out=%p, in=%p) = %li", out, in, (long int)done); return done; } //ll ����������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_pipe.c��������������������������������������������������������������0000644�0001750�0001750�00000022041�12264733551�016076� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_pipe.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_pipe (struct roar_vio_calls * s0, struct roar_vio_calls * s1, int type, int flags) { #ifndef ROAR_WITHOUT_VIO_PIPE struct roar_vio_pipe * self; int rw = flags & (O_RDONLY|O_WRONLY|O_RDWR); if ( s0 == NULL || s1 == NULL ) return -1; if ( (self = roar_mm_malloc(sizeof(struct roar_vio_pipe))) == NULL ) return -1; memset(self, 0, sizeof(struct roar_vio_pipe)); self->refcount = 2; self->flags = flags; if ( type == ROAR_VIO_PIPE_TYPE_AUTO ) { #ifdef ROAR_TARGET_WIN32 type = ROAR_VIO_PIPE_TYPE_BUFFER; #else type = ROAR_VIO_PIPE_TYPE_SOCKET; #endif } self->type = type; switch (type) { case ROAR_VIO_PIPE_TYPE_BUFFER: // no buffers need to be set up here, // we handle the NULL pointer in the reader and writer func roar_mm_free(self); return -1; break; case ROAR_VIO_PIPE_TYPE_PIPE: self->b.p[0] = self->b.p[1] = self->b.p[2] = self->b.p[3] = -1; if ( rw == O_RDWR || rw == O_RDONLY ) if ( pipe(self->b.p) == -1 ) { roar_mm_free(self); return -1; } if ( rw == O_RDWR || rw == O_WRONLY ) if ( pipe((self->b.p) + 2) == -1 ) { close(self->b.p[0]); close(self->b.p[1]); roar_mm_free(self); return -1; } break; #ifdef ROAR_HAVE_UNIX case ROAR_VIO_PIPE_TYPE_SOCKET: if ( socketpair(AF_UNIX, SOCK_STREAM, 0, self->b.p) == -1 ) { roar_mm_free(self); return -1; } if ( rw == O_RDONLY ) { ROAR_SHUTDOWN(self->b.p[0], SHUT_WR); ROAR_SHUTDOWN(self->b.p[1], SHUT_RD); } else if ( rw == O_WRONLY ) { ROAR_SHUTDOWN(self->b.p[0], SHUT_RD); ROAR_SHUTDOWN(self->b.p[1], SHUT_WR); } break; #endif default: roar_mm_free(self); return -1; } roar_vio_pipe_init(s0, self, flags); roar_vio_pipe_init(s1, self, flags); self->s0 = s0; return 0; #else return -1; #endif } #ifndef ROAR_WITHOUT_VIO_PIPE int roar_vio_pipe_init (struct roar_vio_calls * s, struct roar_vio_pipe * self, int flags) { int nonblock = ROAR_SOCKET_NONBLOCK; if ( s == NULL || self == NULL ) return -1; memset(s, 0, sizeof(struct roar_vio_calls)); s->flags = ROAR_VIO_FLAGS_NONE; s->refc = 1; s->close = roar_vio_pipe_close; s->read = roar_vio_pipe_read; s->write = roar_vio_pipe_write; s->sync = roar_vio_pipe_sync; s->inst = (void*) self; if ( flags & O_NONBLOCK ) { roar_vio_pipe_ctl(s, ROAR_VIO_CTL_NONBLOCK, &nonblock); } return 0; } int roar_vio_pipe_close (struct roar_vio_calls * vio) { struct roar_vio_pipe * self; int idx; if ( vio == NULL ) return -1; if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL ) return -1; self->refcount--; switch (self->type) { case ROAR_VIO_PIPE_TYPE_BUFFER: // this will be a bit more complex as we need to change the flags, too. break; case ROAR_VIO_PIPE_TYPE_PIPE: switch (ROAR_VIO_PIPE_S(self, vio)) { case 0: close(self->b.p[0]); close(self->b.p[3]); self->b.p[0] = -1; self->b.p[3] = -1; break; case 1: close(self->b.p[1]); close(self->b.p[2]); self->b.p[1] = -1; self->b.p[2] = -1; break; } break; #ifdef ROAR_HAVE_UNIX case ROAR_VIO_PIPE_TYPE_SOCKET: close(self->b.p[idx = ROAR_VIO_PIPE_S(self, vio)]); self->b.p[idx] = -1; break; #endif } if ( ! self->refcount ) { roar_mm_free(self); } vio->inst = NULL; return 0; } int roar_vio_pipe_sync (struct roar_vio_calls * vio) { // we may add fdatasync() calls here depending on the type // but in general they should not be needed on pipes. (void)vio; return 0; } int roar_vio_pipe_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_vio_pipe * self; if (vio == NULL || cmd == -1) return -1; if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL ) return -1; switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "pipe"; return 0; break; case ROAR_VIO_CTL_GET_FH: case ROAR_VIO_CTL_GET_SELECT_FH: #ifdef ROAR_HAVE_UNIX if ( self->type == ROAR_VIO_PIPE_TYPE_SOCKET ) { *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)]; return 0; } else { return -1; } #else return -1; #endif break; case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: switch (self->type) { #ifdef ROAR_HAVE_UNIX case ROAR_VIO_PIPE_TYPE_SOCKET: *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)]; return 0; break; #endif case ROAR_VIO_PIPE_TYPE_PIPE: *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)*2]; return 0; break; } case ROAR_VIO_CTL_GET_WRITE_FH: case ROAR_VIO_CTL_GET_SELECT_WRITE_FH: switch (self->type) { #ifdef ROAR_HAVE_UNIX case ROAR_VIO_PIPE_TYPE_SOCKET: *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)]; return 0; break; #endif case ROAR_VIO_PIPE_TYPE_PIPE: *(int*)data = self->b.p[(ROAR_VIO_PIPE_SR(self,vio)*2)+1]; return 0; break; } break; case ROAR_VIO_CTL_NONBLOCK: switch (self->type) { case ROAR_VIO_PIPE_TYPE_PIPE: if ( roar_socket_nonblock(self->b.p[ROAR_VIO_PIPE_S(self,vio)*2], *(int*)data) == -1 ) return -1; return roar_socket_nonblock(self->b.p[(ROAR_VIO_PIPE_SR(self,vio)*2)+1], *(int*)data); break; #ifdef ROAR_HAVE_UNIX case ROAR_VIO_PIPE_TYPE_SOCKET: return roar_socket_nonblock(self->b.p[ROAR_VIO_PIPE_S(self,vio)], *(int*)data); break; #endif } break; } return -1; } ssize_t roar_vio_pipe_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_pipe * self; int idx; if ( vio == NULL ) return -1; if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL ) return -1; switch (self->type) { case ROAR_VIO_PIPE_TYPE_BUFFER: idx = ROAR_VIO_PIPE_S(self,vio); if ( (idx == 0 ? O_WRONLY : O_RDONLY) == (self->flags & (O_RDONLY|O_WRONLY|O_RDWR)) ) { raise(SIGPIPE); return -1; } if ( self->b.b[idx] == NULL ) return 0; if ( roar_buffer_shift_out(&(self->b.b[idx]), buf, &count) == -1 ) return -1; return count; break; case ROAR_VIO_PIPE_TYPE_PIPE: return read(self->b.p[ROAR_VIO_PIPE_S(self,vio)*2], buf, count); break; #ifdef ROAR_HAVE_UNIX case ROAR_VIO_PIPE_TYPE_SOCKET: return read(self->b.p[ROAR_VIO_PIPE_S(self,vio)], buf, count); break; #endif } return -1; } ssize_t roar_vio_pipe_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_pipe * self; struct roar_buffer * next; void * data; int idx; if ( vio == NULL ) return -1; if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL ) return -1; switch (self->type) { case ROAR_VIO_PIPE_TYPE_BUFFER: if ( self->refcount < 2 ) { raise(SIGPIPE); return -1; } idx = ROAR_VIO_PIPE_SR(self,vio); if ( (idx == 0 ? O_WRONLY : O_RDONLY) == (self->flags & (O_RDONLY|O_WRONLY|O_RDWR)) ) { raise(SIGPIPE); return -1; } if ( roar_buffer_new_data(&next, count, &data) == -1 ) return -1; memcpy(data, buf, count); if ( self->b.b[idx] == NULL ) { self->b.b[idx] = next; } else { if ( roar_buffer_moveinto(self->b.b[idx], &next) == -1 ) { roar_buffer_free(next); return -1; } } return count; break; case ROAR_VIO_PIPE_TYPE_PIPE: return write(self->b.p[(ROAR_VIO_PIPE_SR(self,vio)*2)+1], buf, count); break; #ifdef ROAR_HAVE_UNIX case ROAR_VIO_PIPE_TYPE_SOCKET: return write(self->b.p[ROAR_VIO_PIPE_S(self,vio)], buf, count); break; #endif } return -1; } #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_proto.c�������������������������������������������������������������0000644�0001750�0001750�00000041454�12264733552�016316� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_proto.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifndef ROAR_WITHOUT_VIO_PROTO #include <roaraudio/proto_gopher.h> #endif int roar_vio_proto_init_def (struct roar_vio_defaults * def, char * dstr, int proto, struct roar_vio_defaults * odef) { #ifndef ROAR_WITHOUT_VIO_PROTO int port = 0; int ret; char * ed; char * tmp; int flags = ROAR_VIOF_READWRITE; if ( def == NULL ) return -1; switch (proto) { case ROAR_VIO_PROTO_P_HTTP: port = 80; break; case ROAR_VIO_PROTO_P_GOPHER: port = 70; break; case ROAR_VIO_PROTO_P_ICY: port = 8000; break; default: return -1; } if ( dstr == NULL ) dstr = "//"; if ( odef->o_flags & ROAR_VIOF_NONBLOCK ) flags |= ROAR_VIOF_NONBLOCK; if ( roar_vio_dstr_init_defaults(def, ROAR_VIO_DEF_TYPE_SOCKET, flags, 0644) == -1 ) return -1; if ( roar_vio_socket_init_tcp4_def(def, "localhost", port) == -1 ) return -1; if ( !strncmp(dstr, "//", 2) ) dstr += 2; if ( (ed = strstr(dstr, "/")) != NULL ) *ed = 0; if ( (tmp = strstr(dstr, "@")) != NULL ) dstr = tmp + 1; ROAR_DBG("roar_vio_proto_init_def(*): def->o_flags=%i", def->o_flags); ret = roar_vio_socket_init_dstr_def(def, dstr, -1, SOCK_STREAM, def); ROAR_DBG("roar_vio_proto_init_def(*): def->o_flags=%i", def->o_flags); if ( ed != NULL ) *ed = '/'; ROAR_DBG("roar_vio_proto_init_def(*): dstr='%s'", dstr); return ret; #else return -1; #endif } int roar_vio_open_proto (struct roar_vio_calls * calls, struct roar_vio_calls * dst, const char * dstr, int proto, struct roar_vio_defaults * odef) { #ifndef ROAR_WITHOUT_VIO_PROTO struct roar_userpass userpass = {.subtype = -1, .user = NULL, .pass = NULL}; struct roar_vio_proto * self; const char * host; char * tmp; int ret; ROAR_DBG("roar_vio_open_proto(calls=%p, dst=%p, dstr='%s', proto=%i, odef=%p) = ?", calls, dst, dstr, proto, odef); if ( calls == NULL || dst == NULL || odef == NULL ) return -1; ROAR_DBG("roar_vio_open_proto(*): odef->o_flags=%i", odef->o_flags); ROAR_DBG("roar_vio_open_proto(*) = ?"); if ( (self = roar_mm_malloc(sizeof(struct roar_vio_proto))) == NULL ) return -1; memset(self, 0, sizeof(struct roar_vio_proto)); self->next = dst; calls->inst = self; calls->read = roar_vio_proto_read; calls->write = roar_vio_proto_write; calls->sync = roar_vio_proto_sync; calls->ctl = roar_vio_proto_ctl; calls->close = roar_vio_proto_close; ROAR_DBG("roar_vio_open_proto(*) = ?"); if ( dstr != NULL ) { dstr += 2; host = dstr; if ( (tmp = strstr(dstr, "/")) == NULL ) return -1; *tmp++ = 0; dstr = tmp; if ( (tmp = strstr(dstr, "#")) != NULL ) *tmp = 0; } else { ROAR_DBG("roar_vio_open_proto(*): no dstr!, odef->type=%i", odef->type); if ( odef->type == ROAR_VIO_DEF_TYPE_FILE ) { dstr = odef->d.file; host = "localhost"; for (; *dstr == '/'; dstr++); } else if ( odef->type == ROAR_VIO_DEF_TYPE_SOCKET ) { dstr = ""; // index document host = odef->d.socket.host; } else { return -1; } } if ( (tmp = strstr(host, "@")) != NULL ) { userpass.user = (char*)host; *tmp = 0; host = tmp + 1; if ( (tmp = strstr(userpass.user, ":")) != NULL ) { *tmp = 0; userpass.pass = tmp + 1; } } ROAR_DBG("roar_vio_open_proto(*) = ?"); ROAR_DBG("roar_vio_open_proto(*): proto=%i, host='%s', file='%s', userpass={.user='%s', .pass='%s'}", proto, host, dstr, userpass.user, userpass.pass); self->proto = proto; if ( odef->o_flags & ROAR_VIOF_NONBLOCK ) { if ( roar_vio_nonblock(calls, ROAR_SOCKET_BLOCK) == -1 ) { return -1; } } switch (proto) { case ROAR_VIO_PROTO_P_HTTP: case ROAR_VIO_PROTO_P_ICY: ret = roar_vio_open_proto_http(calls, dst, host, dstr, userpass.user != NULL ? &userpass : NULL); break; case ROAR_VIO_PROTO_P_GOPHER: ret = roar_vio_open_proto_gopher(calls, dst, host, dstr); break; default: ROAR_DBG("roar_vio_open_proto(*) = -1 // no matching protocol"); roar_err_set(ROAR_ERROR_NOTSUP); ret = -1; break; } if ( odef->o_flags & ROAR_VIOF_NONBLOCK ) { if ( roar_vio_nonblock(calls, ROAR_SOCKET_NONBLOCK) == -1 ) { return -1; } } return ret; #else return -1; #endif } #ifndef ROAR_WITHOUT_VIO_PROTO ssize_t roar_vio_proto_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_proto * self = vio->inst; ssize_t ret; ssize_t have = 0; size_t len; ROAR_DBG("roar_vio_proto_read(*): have=%lli, count=%lli", (long long int)have, (long long int)count); if ( self->reader.buffer != NULL ) { len = count; if ( roar_buffer_shift_out(&(self->reader.buffer), buf, &len) == -1 ) { // This is very bad. return -1; } if ( len ) { have = len; buf += len; count -= len; } } ROAR_DBG("roar_vio_proto_read(*): have=%lli, count=%lli", (long long int)have, (long long int)count); if ( count == 0 ) return have; ROAR_DBG("roar_vio_proto_read(*): have=%lli, count=%lli", (long long int)have, (long long int)count); if ( (ret = roar_vio_read(self->next, buf, count)) == -1 ) return ret; return have + ret; } ssize_t roar_vio_proto_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_proto * self = vio->inst; return roar_vio_write(self->next, buf, count); } int roar_vio_proto_sync (struct roar_vio_calls * vio) { struct roar_vio_proto * self = vio->inst; return roar_vio_sync(self->next); } int roar_vio_proto_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_vio_proto * self; if (vio == NULL || cmd == -1) return -1; self = vio->inst; ROAR_DBG("roar_vio_proto_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; switch (self->proto) { case ROAR_VIO_PROTO_P_HTTP: *(char**)data = "http"; break; case ROAR_VIO_PROTO_P_GOPHER: *(char**)data = "gopher"; break; case ROAR_VIO_PROTO_P_ICY: *(char**)data = "icy"; break; default: *(char**)data = "proto"; break; } return 0; break; case ROAR_VIO_CTL_GET_NEXT: *(struct roar_vio_calls **)data = self->next; return 0; break; case ROAR_VIO_CTL_SET_NEXT: self->next = *(struct roar_vio_calls **)data; return 0; break; case ROAR_VIO_CTL_GET_MIMETYPE: if ( data == NULL ) return -1; if ( self->content_type == NULL ) return -1; *(char**)data = self->content_type; return 0; break; case ROAR_VIO_CTL_GET_FH: case ROAR_VIO_CTL_GET_SELECT_FH: if ( self->reader.buffer == NULL && self->writer.buffer == NULL ) return roar_vio_ctl(self->next, cmd, data); return -1; break; case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: if ( self->reader.buffer == NULL ) return roar_vio_ctl(self->next, cmd, data); return -1; break; case ROAR_VIO_CTL_GET_WRITE_FH: case ROAR_VIO_CTL_GET_SELECT_WRITE_FH: if ( self->writer.buffer == NULL ) return roar_vio_ctl(self->next, cmd, data); return -1; break; } return roar_vio_ctl(self->next, cmd, data); } int roar_vio_proto_close (struct roar_vio_calls * vio) { struct roar_vio_proto * self = vio->inst; if ( roar_vio_close(self->next) == -1 ) return -1; if ( self->content_type != NULL ) roar_mm_free(self->content_type); roar_mm_free(self); return 0; } static int _parse_header(struct roar_keyval * kv, char ** buf, int * aligned, char * endofheader) { char * p = *buf; char c = 0; if ( !(*aligned) ) { for (; *p != 0 && *p != '\r' && *p != '\n'; p++); p++; if ( *p == '\n' ) p++; } if ( p >= endofheader ) return -1; /* if ( *p == '\r' || *p == '\n' ) return 0; */ kv->key = p; for (; *p != 0 && *p != '\r' && *p != '\n' && *p != ':'; p++); if ( *p == 0 ) return -1; if ( p >= endofheader ) return -1; c = *p; *p = 0; if ( c == '\r' && *(p+1) == '\n' ) p++; p++; if ( c == '\r' || c == '\n' ) { if ( *(kv->key) == '\r' || *(kv->key) == '\n' ) return 0; // printf("Key-only\n"); kv->value = kv->key; kv->key = NULL; *buf = p; return 1; } for (; *p == ' '; p++); if ( *p == 0 ) return -1; kv->value = p; for (; *p != 0 && *p != '\r' && *p != '\n'; p++); if ( *p == 0 ) return -1; if ( p >= endofheader ) return -1; c = *p; *p = 0; if ( c == '\r' && *(p+1) == '\n' ) p++; p++; *buf = p; if ( c == '\r' || c == '\n' ) { // printf("aligned\n"); *aligned = 1; p++; } else { // printf("non-aligned(c=0x%x)\n", (int)c); *aligned = 0; } if ( *(kv->key) != 0 ) return 1; return 0; } static void _handle_header (struct roar_vio_proto * self, struct roar_keyval * kv) { ROAR_DBG("_handle_header(*): Header: key='%s', value='%s'", kv->key, kv->value); if ( kv->key == NULL || kv->value == NULL ) return; if ( !strcasecmp(kv->key, "Content-Type") ) { if ( self->content_type != NULL ) roar_mm_free(self->content_type); self->content_type = roar_mm_strdup(kv->value); } } static inline char * _up2http_auth (struct roar_userpass * up) { char * inbuf, * outbuf; size_t inlen, outlen; ssize_t ret; //Authorization: Basic dXNlcjpwdw== if ( up == NULL ) return NULL; if ( up->subtype != -1 ) return NULL; if ( up->user == NULL || up->pass == NULL ) return NULL; inlen = roar_mm_strlen(up->user) + roar_mm_strlen(up->pass) + 2; inbuf = roar_mm_malloc(inlen); if ( inbuf == NULL ) return NULL; inbuf[0] = 0; roar_mm_strlcat(inbuf, up->user, inlen); roar_mm_strlcat(inbuf, ":", inlen); roar_mm_strlcat(inbuf, up->pass, inlen); outlen = ((inlen * 3) / 2) + 3 /* padding... */ + 6 /* 'Basic ' */; outbuf = roar_mm_malloc(outlen); if ( outbuf == NULL ) { roar_mm_free(inbuf); return NULL; } strncpy(outbuf, "Basic ", 7); ROAR_DBG("_up2http_auth(up=%p{.subtype=%i, .user='%s', .pass='%s'): inbuf='%s', outbuf='%s'", up, up->subtype, up->user, up->pass, inbuf, outbuf); ret = roar_base64_encode(NULL, outbuf + 6, outlen - 6, inbuf, inlen - 1, NULL, 1); ROAR_DBG("_up2http_auth(up=%p{.subtype=%i, .user='%s', .pass='%s'): inbuf='%s', outbuf='%s'", up, up->subtype, up->user, up->pass, inbuf, outbuf); roar_mm_free(inbuf); if ( ret == -1 ) { roar_mm_free(outbuf); return NULL; } return outbuf; } int roar_vio_open_proto_http (struct roar_vio_calls * calls, struct roar_vio_calls * dst, const char * host, const char * file, struct roar_userpass * up) { struct roar_keyval kv; struct roar_vio_proto * self; struct roar_buffer * bufbuf; void * vpbuf; char * authbuf; char * buf; char * endofheader = NULL; char * p; char b0[80], b1[80]; int status; int len; int oeflen = 4; int aligned = 1; int error; ROAR_DBG("roar_vio_open_proto_http(calls=%p, dst=%p, host='%s', file='%s') = ?", calls, dst, host, file); if ( calls == NULL || dst == NULL || host == NULL || file == NULL ) return -1; self = calls->inst; calls->write = NULL; // Disable write as we do not support this if ( roar_buffer_new_data(&bufbuf, 1024, &vpbuf) == -1 ) return -1; buf = vpbuf; ROAR_DBG("roar_vio_open_proto_http(calls=%p, dst=%p, host='%s', file='%s') = ?", calls, dst, host, file); if ( roar_vio_printf(dst, "GET /%s HTTP/1.1\r\n", file) == -1 ) return -1; roar_vio_printf(dst, "Host: %s\r\n", host); roar_vio_printf(dst, "User-Agent: roar_vio_open_proto_http() $Revision: 1.36 $\r\n"); roar_vio_printf(dst, "Connection: close\r\n"); if ( up != NULL ) { if ( (authbuf = _up2http_auth(up)) != NULL ) { roar_vio_printf(dst, "Authorization: %s\r\n", authbuf); roar_mm_free(authbuf); } } roar_vio_printf(dst, "\r\n"); ROAR_DBG("roar_vio_open_proto_http(*) = ?"); roar_vio_sync(dst); ROAR_DBG("roar_vio_open_proto_http(*) = ?"); if ( (len = roar_vio_read(dst, buf, 1023)) < 1 ) { ROAR_DBG("roar_vio_open_proto_http(*) = -1"); roar_buffer_free(bufbuf); return -1; } ROAR_DBG("roar_vio_open_proto_http(*): got %i bytes from server.", len); buf[len] = 0; ROAR_DBG("roar_vio_open_proto_http(*) = ?"); if ( sscanf(buf, "%79s %i %79s\n", b0, &status, b1) != 3 ) { ROAR_DBG("roar_vio_open_proto_http(*) = -1"); roar_buffer_free(bufbuf); return -1; } ROAR_DBG("roar_vio_open_proto_http(*): b0='%s'", b0); ROAR_DBG("roar_vio_open_proto_http(*) = ?"); if ( status != 200 ) { ROAR_DBG("roar_vio_open_proto_http(*) = -1 // status=%i", status); roar_buffer_free(bufbuf); if ( roar_err_convert(&error, ROAR_ERROR_TYPE_ROARAUDIO, status, ROAR_ERROR_TYPE_HTTP) != ROAR_ERROR_NONE ) { roar_err_set(ROAR_ERROR_UNKNOWN); } else { roar_err_set(error); } return -1; } ROAR_DBG("roar_vio_open_proto_http(*): status=%i", status); // ROAR_WARN("roar_vio_open_proto_http(*): buf='%s'", buf); endofheader = strstr(buf, "\r\n\r\n"); if ( endofheader == NULL ) { endofheader = strstr(buf, "\n\n"); oeflen = 2; } ROAR_DBG("roar_vio_open_proto_http(*): endofheader=%p\n", endofheader); p = buf; while ( _parse_header(&kv, &p, &aligned, endofheader) > 0 ) if ( aligned ) _handle_header(self, &kv); while ( endofheader == NULL ) { if ( (len = roar_vio_read(dst, buf, 1023)) < 1 ) return -1; buf[len] = 0; endofheader = strstr(buf, "\r\n\r\n"); if ( endofheader == NULL ) { endofheader = strstr(buf, "\n\n"); oeflen = 2; } /* Doesn't work good. while ( _parse_header(&kv, &p, &aligned, endofheader) > 0 ) if ( aligned ) _handle_header(self, &kv); */ p = buf; while ( _parse_header(&kv, &p, &aligned, endofheader) > 0 ) if ( aligned ) _handle_header(self, &kv); ROAR_DBG("roar_vio_open_proto_http(*): endofheader=%p\n", endofheader); } ROAR_DBG("roar_vio_open_proto_http(*): endofheader=%p\n", endofheader); ROAR_DBG("roar_vio_open_proto_http(*): buf=%p\n", buf); if ( (endofheader - buf) == (len - oeflen) ) { roar_buffer_free(bufbuf); bufbuf = NULL; } if ( bufbuf != NULL ) { if ( roar_buffer_set_offset(bufbuf, endofheader - buf + oeflen) == -1 || roar_buffer_set_len(bufbuf, len - (endofheader - buf + oeflen) - 0 /* ??? */) == -1 ) { // TODO: FIXME: handle this in a better way. ROAR_ERR("roar_vio_open_proto_http(*): Can not set data area of buffer %p, VERY BAD.", bufbuf); } } self->reader.buffer = bufbuf; /* if ( !strcmp((buf+len)-4, "\r\n\r\n") ) return 0; while (*buf != '\r' && *buf != '\n') { if ( (len = roar_vio_read(dst, buf, 1023)) < 1 ) return -1; } */ return 0; } int roar_vio_open_proto_gopher (struct roar_vio_calls * calls, struct roar_vio_calls * dst, const char * host, const char * file) { struct roar_vio_proto * self; char type; const char * mime = NULL; if ( calls == NULL || dst == NULL || host == NULL || file == NULL ) return -1; self = calls->inst; calls->write = NULL; // Disable write as we do not support this ROAR_DBG("roar_vio_open_proto_gopher(calls=%p, dst=%p, host='%s', file='%s') = ?", calls, dst, host, file); type = file[0]; file++; ROAR_DBG("roar_vio_open_proto_gopher(*): type='%c'", type); switch (type) { case ROAR_GOPHER_TYPE_FILE: mime = "text/plain"; break; case ROAR_GOPHER_TYPE_DIR: mime = "inode/directory"; break; case ROAR_GOPHER_TYPE_BIN: mime = "application/octet-stream"; break; case ROAR_GOPHER_TYPE_GIF: mime = "image/gif"; break; case ROAR_GOPHER_TYPE_HTML: mime = "text/html"; break; } if ( mime != NULL ) { self->content_type = roar_mm_strdup(mime); } roar_vio_printf(dst, "%s\r\n", file); roar_vio_sync(dst); // for encryption/compression layers return 0; } #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_proxy.c�������������������������������������������������������������0000644�0001750�0001750�00000016533�12264733552�016334� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_proxy.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_proxy_init_def(struct roar_vio_defaults * def, char * dstr, enum roar_vio_proxy_type type, struct roar_vio_defaults * odef) { int hint = -1; (void)type; // TODO: generate hints from type. ROAR_DBG("roar_vio_proxy_init_def(def=%p, dstr='%s', type=%i, odef=%p) = ?", def, dstr, (int)type, odef); if ( roar_vio_dstr_init_defaults(def, ROAR_VIO_DEF_TYPE_SOCKET, O_RDWR, 0644) == -1 ) return -1; if ( roar_vio_socket_init_dstr_def(def, dstr, hint, odef == NULL ? SOCK_STREAM : odef->d.socket.type, odef) == -1 ) { ROAR_DBG("roar_vio_proxy_init_def(def=%p, dstr='%s', type=%i, odef=%p) = -1", def, dstr, (int)type, odef); return -1; } ROAR_DBG("roar_vio_proxy_init_def(def=%p, dstr='%s', type=%i, odef=%p) = 0", def, dstr, (int)type, odef); return 0; } static int roar_vio_proxy_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if ( cmd == ROAR_VIO_CTL_GET_NAME ) { *(char **)data = "proxy"; return 0; } return roar_vio_pass_ctl(vio, cmd, data); } static int init_socks4(struct roar_vio_calls * dst, enum roar_vio_proxy_type type, struct roar_vio_defaults * odef) { char buf[9] = { 0x04, // [0] Version 0x01, // [1] mode=connect (listen is 0x02) 0, 0, 0, 0, // [2..5] host IP 0, // [6] Port MSB 0, // [7] Port LSB 0x00 // [8] EOS (\0) of username }; enum roar_vio_proxy_type needed_type = ROAR_VIO_PROXY_INVALID; ROAR_DBG("init_socks4(dst=%p, type=%i, odef=%p{.d.socket={.domain=%i, .type=%i, .host='%s'}}) = ?", dst, (int)type, odef, odef->d.socket.domain, odef->d.socket.type, odef->d.socket.host); switch (odef->d.socket.domain) { #ifdef ROAR_HAVE_IPV4 case AF_INET: needed_type = ROAR_VIO_PROXY_SOCKS4; break; #endif #ifdef ROAR_HAVE_LIBDNET case AF_DECnet: if ( odef->d.socket.sa.dn.sdn_objnum == 0 ) { needed_type = ROAR_VIO_PROXY_SOCKS4d; } else { needed_type = ROAR_VIO_PROXY_SOCKS4; } break; #endif #ifdef ROAR_HAVE_IPV6 case AF_INET6: #endif #ifdef ROAR_HAVE_IPX case AF_IPX: #endif #ifdef ROAR_HAVE_UNIX case AF_UNIX: #endif default: roar_err_set(ROAR_ERROR_AFNOTSUP); return -1; break; } if ( needed_type == ROAR_VIO_PROXY_SOCKS4 && type != needed_type ) needed_type = type; if ( needed_type != type ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } switch (odef->d.socket.domain) { #ifdef ROAR_HAVE_IPV4 case AF_INET: if ( roar_vio_socket_init_inet4host_def(odef) == -1 ) return -1; buf[2] = ((char*)&(odef->d.socket.sa.in.sin_port))[0]; buf[3] = ((char*)&(odef->d.socket.sa.in.sin_port))[1]; buf[4] = ((char*)&(odef->d.socket.sa.in.sin_addr.s_addr))[0]; buf[5] = ((char*)&(odef->d.socket.sa.in.sin_addr.s_addr))[1]; buf[6] = ((char*)&(odef->d.socket.sa.in.sin_addr.s_addr))[2]; buf[7] = ((char*)&(odef->d.socket.sa.in.sin_addr.s_addr))[3]; ROAR_DBG("init_socks4(dst=%p, type=%i, odef=%p{.d.socket={.domain=%i, .type=%i, .host='%s'}}): buf[]={%i, %i, %i, %i, %i, %i, %i, %i, %i}", dst, (int)type, odef, odef->d.socket.domain, odef->d.socket.type, odef->d.socket.host, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]); break; #endif #ifdef ROAR_HAVE_LIBDNET case AF_DECnet: if ( type == ROAR_VIO_PROXY_SOCKS4 ) { buf[2] = 0; buf[3] = odef->d.socket.sa.dn.sdn_objnum; buf[4] = 0; buf[5] = 2; buf[6] = odef->d.socket.sa.dn.sdn_nodeaddr[0]; buf[7] = odef->d.socket.sa.dn.sdn_nodeaddr[1]; } else { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } break; #endif } if ( roar_vio_write(dst, buf, sizeof(buf)) != (ssize_t)sizeof(buf) ) return -1; if ( roar_vio_read(dst, buf, 8) != (ssize_t)8 ) return -1; if ( buf[1] != 0x5a ) { roar_err_set(ROAR_ERROR_UNKNOWN); return -1; } return 0; } int roar_vio_open_proxy (struct roar_vio_calls * calls, struct roar_vio_calls * dst, enum roar_vio_proxy_type type, struct roar_vio_defaults * odef) { int init_only = -1; int (*init)(struct roar_vio_calls * dst, enum roar_vio_proxy_type type, struct roar_vio_defaults * odef) = NULL; ROAR_DBG("roar_vio_open_proxy(calls=%p, dst=%p, type=%i, odef=%p{.type=%i}) = ?", calls, dst, (int)type, odef, (int)odef->type); if ( odef->type != ROAR_VIO_DEF_TYPE_SOCKET ) { roar_err_set(ROAR_ERROR_NOTSOCK); return -1; } switch (type) { case ROAR_VIO_PROXY_NONE: init_only = 1; init = NULL; break; case ROAR_VIO_PROXY_SOCKS: case ROAR_VIO_PROXY_SOCKS4: case ROAR_VIO_PROXY_SOCKS4a: case ROAR_VIO_PROXY_SOCKS4d: init_only = 1; init = init_socks4; break; #ifndef DEBUG default: break; #endif } if ( init_only == 1 ) { if ( init != NULL ) if ( init(dst, type, odef) == -1 ) return -1; if ( roar_vio_open_pass(calls, dst) == -1 ) return -1; calls->ctl = roar_vio_proxy_ctl; return 0; } else { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } } // DSTR interface: static enum roar_vio_proxy_type _dstrtype2proxytype(struct roar_vio_dstr_chain * chainelement) { switch (chainelement->type) { case ROAR_VIO_DSTR_OBJT_SOCKS: return ROAR_VIO_PROXY_SOCKS; break; case ROAR_VIO_DSTR_OBJT_SOCKS4: return ROAR_VIO_PROXY_SOCKS4; break; case ROAR_VIO_DSTR_OBJT_SOCKS4A: return ROAR_VIO_PROXY_SOCKS4a; break; case ROAR_VIO_DSTR_OBJT_SOCKS4D: return ROAR_VIO_PROXY_SOCKS4d; break; case ROAR_VIO_DSTR_OBJT_SOCKS5: return ROAR_VIO_PROXY_SOCKS5; break; default: return ROAR_VIO_PROXY_INVALID; break; } } int roar_vio_proxy_setdef(struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next) { next->def = &(next->store_def); return roar_vio_proxy_init_def(next->def, cur->dst, _dstrtype2proxytype(cur), cur->def); } int roar_vio_proxy_openvio(struct roar_vio_calls * calls, struct roar_vio_calls * dst, struct roar_vio_dstr_chain * cur, struct roar_vio_dstr_chain * next) { return roar_vio_open_proxy(calls, dst, _dstrtype2proxytype(cur), cur->def); } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_rtp.c���������������������������������������������������������������0000644�0001750�0001750�00000026435�12264733552�015762� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_rtp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static const struct { int pt; struct roar_audio_info info; } _g_rtp_pt[] = { {ROAR_RTP_PT_A_PCMU, {.codec = ROAR_CODEC_MULAW, .bits = 8, .rate = 8000, .channels = 1}}, {ROAR_RTP_PT_A_PCMA, {.codec = ROAR_CODEC_ALAW, .bits = 8, .rate = 8000, .channels = 1}}, {ROAR_RTP_PT_A_L16_441_2, {.codec = ROAR_CODEC_PCM_S_BE, .bits = 16, .rate = 44100, .channels = 2}}, {ROAR_RTP_PT_A_L16_441_1, {.codec = ROAR_CODEC_PCM_S_BE, .bits = 16, .rate = 44100, .channels = 1}}, {-1, {-1, -1, -1, -1}} }; static int _info2pt (struct roar_audio_info * info) { int i; ROAR_DBG("_info2pt(info=%p{.codec=%s(%i), .bits=%i, .rate=%i, .channels=%i}) = ?", info, roar_codec2str(info->codec), info->codec, info->bits, info->rate, info->channels); for (i = 0; _g_rtp_pt[i].pt != -1; i++) { if ( info->codec == _g_rtp_pt[i].info.codec && info->bits == _g_rtp_pt[i].info.bits && info->rate == _g_rtp_pt[i].info.rate && info->channels == _g_rtp_pt[i].info.channels ) { return _g_rtp_pt[i].pt; } } ROAR_DBG("_info2pt(info=%p{.codec=%s(%i), .bits=%i, .rate=%i, .channels=%i}) = -1", info, roar_codec2str(info->codec), info->codec, info->bits, info->rate, info->channels); return -1; } #if 0 static const struct roar_audio_info * _pt2info (int pt) { int i; for (i = 0; _g_rtp_pt[i].pt != -1; i++) { if ( _g_rtp_pt[i].pt == pt ) { return &(_g_rtp_pt[i].info); } } return NULL; } #endif int roar_vio_open_rtp (struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * dstr, struct roar_vio_defaults * odef) { struct roar_rtp_inst * self = NULL; ROAR_DBG("roar_vio_open_rtp(calls=%p, dst=%p, dstr='%s', odef=%p) = ?", calls, dst, dstr, odef); if ( calls == NULL || dst == NULL ) return -1; if ( (self = roar_mm_malloc(sizeof(struct roar_rtp_inst))) == NULL ) return -1; ROAR_DBG("roar_vio_open_rtp(calls=%p, dst=%p, dstr='%s', odef=%p) = ?", calls, dst, dstr, odef); memset(self, 0, sizeof(struct roar_rtp_inst)); self->vio = dst; self->bpf = 0; self->mtu = 768; memset(&(self->info), 0, sizeof(struct roar_audio_info)); self->header.version = 2; self->header.payload_type = ROAR_RTP_PT_UNKNOWN; // TODO: init with random values: // Sequence Number // ts // SSRC memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->inst = self; calls->read = roar_vio_rtp_read; calls->write = roar_vio_rtp_write; calls->sync = roar_vio_rtp_sync; calls->ctl = roar_vio_rtp_ctl; calls->close = roar_vio_rtp_close; ROAR_DBG("roar_vio_open_rtp(calls=%p, dst=%p, dstr='%s', odef=%p) = 0", calls, dst, dstr, odef); return 0; } ssize_t roar_vio_rtp_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_rtp_inst * self = vio->inst; size_t len_need = self->mtu * 4 + sizeof(struct roar_rtp_header); // we hope to never get pkgs with size > 4*mtu size_t len_have; ssize_t have = 0; ssize_t ret; union { void * vp; char * cp; uint16_t * u16; uint32_t * u32; } data; size_t dataoffset; int i; ROAR_DBG("roar_vio_rtp_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); if ( self->rx_decoded != NULL ) { // handle this case and set to NULL if the buffer is empty // set have; // increment buf, decrement count } if ( count == 0 ) return have; if ( self->io == NULL ) { if ( roar_buffer_new(&(self->io), len_need) == -1 ) return have ? have : -1; len_have = len_need; } else { if ( roar_buffer_get_len(self->io, &len_have) == -1 ) return have ? have : -1; if ( len_have < len_need ) { if ( roar_buffer_set_len(self->io, len_need) == -1 ) { if ( roar_buffer_free(self->io) == -1 ) return have ? have : -1; self->io = NULL; if ( have != 0 ) { return have; } else { return roar_vio_rtp_read(vio, buf, count); // restart our self from the beginning with no buffer } } } } if ( roar_buffer_get_data(self->io, &(data.vp)) == -1 ) return have ? have : -1; if ( (ret = roar_vio_read(self->vio, data.vp, len_need)) == -1 ) return have ? have : -1; if ( (data.cp[0] & 0x02) == 0x02 ) /* version check */ return have ? have : -1; self->header.csrc_count = (data.cp[0] & 0xF0) >> 4; self->header.payload_type = (data.cp[1] & 0xFE) >> 1; // TODO: check old seqnum < new seqnum self->header.seq_num = ROAR_NET2HOST16(data.u16[1]); // TODO: check timestamp: self->header.ts = ROAR_NET2HOST32(data.u32[1]); self->header.ssrc = ROAR_NET2HOST32(data.u32[2]); for (i = 0; i < self->header.csrc_count; i++) { self->header.csrc[i] = ROAR_NET2HOST16(data.u32[3+i]); } dataoffset = 3*4 + self->header.csrc_count*4; ret -= dataoffset; data.vp += dataoffset; if ( ret <= (ssize_t)count ) { memcpy(buf, data.vp, ret); ROAR_DBG("roar_vio_rtp_read(vio=%p, buf=%p, count=?) = %llu", vio, buf, (long long unsigned)(have+ret)); return have + ret; } else { } ROAR_DBG("roar_vio_rtp_read(vio=%p, buf=%p, count=?) = -1", vio, buf); return -1; } ssize_t roar_vio_rtp_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_rtp_inst * self = vio->inst; size_t len_need = count + sizeof(struct roar_rtp_header); // this is a bit more than we need // we ignore this at the moment size_t len_have; union { void * vp; char * cp; uint16_t * u16; uint32_t * u32; } data; size_t dataoffset; ssize_t ret; int i; ROAR_DBG("roar_vio_rtp_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); if ( self->mtu < (sizeof(struct roar_rtp_header) + self->bpf) ) return -1; if ( len_need > self->mtu ) { len_have = 0; ret = 0; while (count) { len_need = self->mtu - sizeof(struct roar_rtp_header); if ( count < len_need ) len_need = count; if ( (ret = roar_vio_rtp_write(vio, buf, len_need)) == -1 ) break; len_have += ret; buf += ret; count -= ret; } return len_have ? (ssize_t)len_have : ret; } if ( self->io == NULL ) { if ( roar_buffer_new(&(self->io), len_need) == -1 ) return -1; len_have = len_need; } else { if ( roar_buffer_get_len(self->io, &len_have) == -1 ) return -1; if ( len_have < len_need ) { if ( roar_buffer_set_len(self->io, len_need) == -1 ) { if ( roar_buffer_free(self->io) == -1 ) return -1; self->io = NULL; return roar_vio_rtp_write(vio, buf, count); // restart ower self from the beginning with no buffer } } } ROAR_DBG("roar_vio_rtp_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); if ( roar_buffer_get_data(self->io, &(data.vp)) == -1 ) return -1; memset(data.vp, 0, len_need); self->header.seq_num++; data.cp[0] = 2; data.cp[0] |= self->header.csrc_count << 4; data.cp[1] |= self->header.payload_type << 1; data.u16[1] = ROAR_HOST2NET16(self->header.seq_num); data.u32[1] = ROAR_HOST2NET32(self->header.ts); data.u32[2] = ROAR_HOST2NET32(self->header.ssrc); for (i = 0; i < self->header.csrc_count; i++) { data.u32[3+i] = ROAR_HOST2NET32(self->header.csrc[i]); } dataoffset = 3*4 + self->header.csrc_count*4; memcpy(data.vp + dataoffset, buf, count); ROAR_DBG("roar_vio_rtp_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); if ( (ret = roar_vio_write(self->vio, data.vp, count+dataoffset)) == -1 ) return -1; len_have = ret - dataoffset; self->header.ts += len_have / self->bpf; return len_have; } int roar_vio_rtp_sync (struct roar_vio_calls * vio) { struct roar_rtp_inst * self = vio->inst; ROAR_DBG("roar_vio_rtp_sync(vio=%p) = ?", vio); return roar_vio_sync(self->vio); } int roar_vio_rtp_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_rtp_inst * self = vio->inst; struct roar_stream * s = NULL; struct roar_stream_server * ss = NULL; struct roar_audio_info * info = NULL; ROAR_DBG("roar_vio_rtp_ctl(vio=%p, cmd=%i, data=%p) = ?", vio, cmd, data); if (vio == NULL || cmd == -1) return -1; ROAR_DBG("roar_vio_rtp_ctl(vio=%p, cmd=%i, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "rtp"; return 0; break; case ROAR_VIO_CTL_SET_SSTREAM: s = ROAR_STREAM(ss = data); info = &(s->info); break; case ROAR_VIO_CTL_SET_STREAM: s = ROAR_STREAM(data); info = &(s->info); break; case ROAR_VIO_CTL_SET_AUINFO: info = data; break; case ROAR_VIO_CTL_GET_NEXT: *(struct roar_vio_calls **)data = self->vio; return 0; break; case ROAR_VIO_CTL_SET_NEXT: self->vio = *(struct roar_vio_calls **)data; return 0; break; } ROAR_DBG("roar_vio_rtp_ctl(vio=%p, cmd=%i, data=%p) = ?", vio, cmd, data); if ( info != NULL ) { switch (info->codec) { case ROAR_CODEC_PCM_S_LE: case ROAR_CODEC_PCM_S_PDP: info->codec = ROAR_CODEC_PCM_S_BE; break; case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_PDP: info->codec = ROAR_CODEC_PCM_U_BE; break; } memcpy(&(self->info), info, sizeof(struct roar_audio_info)); self->header.payload_type = _info2pt(info); self->bpf = info->channels * info->bits / 8; _LIBROAR_IGNORE_RET(roar_vio_ctl(self->vio, cmd, data)); return 0; } return roar_vio_ctl(self->vio, cmd, data); } int roar_vio_rtp_close (struct roar_vio_calls * vio) { struct roar_rtp_inst * self = vio->inst; int ret; ROAR_DBG("roar_vio_rtp_close(vio=%p) = ?", vio); ret = roar_vio_close(self->vio); if ( self->io != NULL ) if ( roar_buffer_free(self->io) == -1 ) ret = -1; roar_mm_free(self); ROAR_DBG("roar_vio_rtp_close(vio=%p) = %i", vio, ret); return ret; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_select.c������������������������������������������������������������0000644�0001750�0001750�00000016255�12264733552�016433� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_select.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" ssize_t roar_vio_select(struct roar_vio_select * vios, size_t len, struct roar_vio_selecttv * rtv, struct roar_vio_selectctl * ctl) { #ifdef ROAR_HAVE_SELECT struct timeval tv; fd_set rfds, wfds, efds; #endif size_t i; #ifdef ROAR_HAVE_SELECT int max_fh = -1; #endif int ret; #ifdef DEBUG char * name; #endif ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p) = ?", vios, (long long unsigned int)len, rtv, ctl); if ( len == 0 ) { ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p) = 0", vios, (long long unsigned int)len, rtv, ctl); return 0; } if ( vios == NULL ) { ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p) = -1", vios, (long long unsigned int)len, rtv, ctl); return -1; } // pepaer internal structs: for (i = 0; i < len; i++) { if ( vios[i].eventsq & ROAR_VIO_SELECT_NO_RETEST ) continue; ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p): vios[i=%i].fh=%i", vios, (long long unsigned int)len, rtv, ctl, i, vios[i].fh); if ( vios[i].fh == -1 ) { #ifdef DEBUG name = NULL; if ( roar_vio_ctl(vios[i].vio, ROAR_VIO_CTL_GET_NAME, &name) != 0 ) name = NULL; ROAR_DBG("roar_vio_select(*): vios[%i]'s name is: '%s'", i, name); #endif vios[i].internal.action = ROAR_VIO_SELECT_ACTION_NONE; if ( vios[i].eventsq & ROAR_VIO_SELECT_READ ) { if ( roar_vio_ctl(vios[i].vio, ROAR_VIO_CTL_GET_SELECT_READ_FH, &(vios[i].internal.fh[0])) == -1 ) { vios[i].internal.action |= ROAR_VIO_SELECT_ACTION_VIOS; vios[i].internal.fh[0] = -1; } else { vios[i].internal.action |= ROAR_VIO_SELECT_ACTION_SELECT; } } if ( vios[i].eventsq & ROAR_VIO_SELECT_WRITE ) { if ( roar_vio_ctl(vios[i].vio, ROAR_VIO_CTL_GET_SELECT_WRITE_FH, &(vios[i].internal.fh[1])) == -1 ) { vios[i].internal.action |= ROAR_VIO_SELECT_ACTION_VIOS; vios[i].internal.fh[1] = -1; } else { vios[i].internal.action |= ROAR_VIO_SELECT_ACTION_SELECT; } } if ( vios[i].eventsq & ROAR_VIO_SELECT_EXCEPT ) { if ( roar_vio_ctl(vios[i].vio, ROAR_VIO_CTL_GET_SELECT_FH, &(vios[i].internal.fh[2])) == -1 ) { vios[i].internal.action |= ROAR_VIO_SELECT_ACTION_VIOS; vios[i].internal.fh[2] = -1; } else { vios[i].internal.action |= ROAR_VIO_SELECT_ACTION_SELECT; } } ROAR_DBG("roar_vio_select(*): vios[%i].internal.fh[] = {%i, %i, %i}", i, vios[i].internal.fh[0], vios[i].internal.fh[1], vios[i].internal.fh[2]); } else { vios[i].internal.action = ROAR_VIO_SELECT_ACTION_SELECT; vios[i].internal.fh[0] = vios[i].fh; vios[i].internal.fh[1] = vios[i].fh; vios[i].internal.fh[2] = vios[i].fh; } } // check: for (i = 0; i < len; i++) { if ( vios[i].eventsq & ROAR_VIO_SELECT_NO_RETEST ) continue; if ( !( vios[i].internal.action == 0 || vios[i].internal.action == ROAR_VIO_SELECT_ACTION_SELECT ) ) { // we currently do not support non-select selects. // TODO: Fix this. ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p) = -1", vios, (long long unsigned int)len, rtv, ctl); return -1; } } #ifdef ROAR_HAVE_SELECT // prepaer fdsets: FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); for (i = 0; i < len; i++) { if ( vios[i].eventsq & ROAR_VIO_SELECT_NO_RETEST ) continue; if ( vios[i].eventsq & ROAR_VIO_SELECT_READ ) { ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p): vios[i=%i] is READ, fh=%i", vios, (long long unsigned int)len, rtv, ctl, i, vios[i].internal.fh[0]); FD_SET(vios[i].internal.fh[0], &rfds); if ( vios[i].internal.fh[0] > max_fh ) max_fh = vios[i].internal.fh[0]; } if ( vios[i].eventsq & ROAR_VIO_SELECT_WRITE ) { ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p): vios[i=%i] is WRITE, fh=%i", vios, (long long unsigned int)len, rtv, ctl, i, vios[i].internal.fh[1]); FD_SET(vios[i].internal.fh[1], &wfds); if ( vios[i].internal.fh[1] > max_fh ) max_fh = vios[i].internal.fh[1]; } if ( vios[i].eventsq & ROAR_VIO_SELECT_EXCEPT ) { ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p): vios[i=%i] is EXCEPT, fh=%i", vios, (long long unsigned int)len, rtv, ctl, i, vios[i].internal.fh[2]); FD_SET(vios[i].internal.fh[2], &efds); if ( vios[i].internal.fh[2] > max_fh ) max_fh = vios[i].internal.fh[2]; } } // the the select: if ( rtv == NULL ) { tv.tv_sec = 1024; tv.tv_usec = 0; } else { tv.tv_sec = rtv->sec; tv.tv_usec = rtv->nsec / 1000; if ( tv.tv_sec == 0 && tv.tv_usec == 0 ) tv.tv_usec = 1; } ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p): Doing select() with max_fh=%i", vios, (long long unsigned int)len, rtv, ctl, max_fh); ret = select(max_fh + 1, &rfds, &wfds, &efds, &tv); ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p): select() returned %i", vios, (long long unsigned int)len, rtv, ctl, ret); // ret == -1 -> Error // ret == 0 -> No data if ( ret < 1 ) { ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p) = %lli", vios, (long long unsigned int)len, rtv, ctl, (long long int)ret); return ret; } // set eventsa: for (i = 0; i < len; i++) { if ( vios[i].eventsq & ROAR_VIO_SELECT_NO_RETEST ) continue; vios[i].eventsa = ROAR_VIO_SELECT_NONE; if ( vios[i].eventsq & ROAR_VIO_SELECT_READ ) if ( FD_ISSET(vios[i].internal.fh[0], &rfds) ) vios[i].eventsa |= ROAR_VIO_SELECT_READ; if ( vios[i].eventsq & ROAR_VIO_SELECT_WRITE ) if ( FD_ISSET(vios[i].internal.fh[1], &wfds) ) vios[i].eventsa |= ROAR_VIO_SELECT_WRITE; if ( vios[i].eventsq & ROAR_VIO_SELECT_EXCEPT ) if ( FD_ISSET(vios[i].internal.fh[2], &efds) ) vios[i].eventsa |= ROAR_VIO_SELECT_EXCEPT; } #else ret = -1; #endif ROAR_DBG("roar_vio_select(vios=%p, len=%llu, rtv=%p, ctl=%p) = %lli", vios, (long long unsigned int)len, rtv, ctl, (long long int)ret); return ret; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_socket.c������������������������������������������������������������0000644�0001750�0001750�00000037125�12264733552�016443� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_socket.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_BSDSOCKETS #define _CAN_OPERATE #endif int roar_vio_open_def_socket (struct roar_vio_calls * calls, struct roar_vio_defaults * def, char * opts) { #ifdef _CAN_OPERATE int fh = -1; socklen_t len = 0; int listening = 0; int one_client = 0; int client; int connection_less = 0; if ( calls == NULL || def == NULL ) return -1; if ( opts != NULL ) { if ( strstr(opts, "listen") != NULL ) { listening = 1; one_client = 1; } } if ( def->type != ROAR_VIO_DEF_TYPE_SOCKET ) return -1; switch (def->d.socket.domain) { #ifdef ROAR_HAVE_IPV4 case AF_INET: len = sizeof(struct sockaddr_in); if ( roar_vio_socket_init_inet4host_def(def) == -1 ) return -1; switch (def->d.socket.type) { case SOCK_STREAM: fh = roar_socket_new(ROAR_SOCKET_TYPE_TCP); break; case SOCK_DGRAM: fh = roar_socket_new(ROAR_SOCKET_TYPE_UDP); connection_less = 1; break; default: return -1; } break; #endif #ifdef ROAR_HAVE_UNIX case AF_UNIX: len = sizeof(struct sockaddr_un); switch (def->d.socket.type) { case SOCK_STREAM: fh = roar_socket_new(ROAR_SOCKET_TYPE_UNIX); break; case SOCK_DGRAM: connection_less = 1; return -1; break; default: return -1; } break; #endif #ifdef ROAR_HAVE_LIBDNET case AF_DECnet: len = sizeof(struct sockaddr_dn); if ( roar_vio_socket_init_decnetnode_def(def) == -1 ) return -1; switch (def->d.socket.type) { case SOCK_STREAM: fh = roar_socket_new(ROAR_SOCKET_TYPE_DECNET); break; default: return -1; } break; #endif #ifdef ROAR_HAVE_IPV6 case AF_INET6: len = sizeof(struct sockaddr_in6); switch (def->d.socket.type) { case SOCK_STREAM: fh = roar_socket_new(ROAR_SOCKET_TYPE_TCP6); break; case SOCK_DGRAM: fh = roar_socket_new(ROAR_SOCKET_TYPE_UDP6); connection_less = 1; break; default: return -1; } break; #endif #ifdef ROAR_HAVE_IPX case AF_IPX: len = sizeof(struct sockaddr_ipx); return -1; break; #endif default: return -1; } if ( fh == -1 ) return -1; if ( listening ) { if ( bind(fh, &(def->d.socket.sa.sa), len) == -1 ) { close(fh); return -1; } if ( !connection_less ) { if ( listen(fh, one_client ? 1 : 16) == -1 ) { close(fh); return -1; } if ( one_client ) { client = accept(fh, NULL, NULL); close(fh); if ( client == -1 ) { return -1; } fh = client; } } } else { if ( def->o_flags & ROAR_VIOF_NONBLOCK ) { if ( roar_socket_nonblock(fh, ROAR_SOCKET_NONBLOCK) == -1 ) { close(fh); return -1; } } if ( connect(fh, &(def->d.socket.sa.sa), len) == -1 ) { #ifdef EINPROGRESS if ( errno != EINPROGRESS ) { #endif roar_err_from_errno(); close(fh); return -1; #ifdef EINPROGRESS } #endif } } if ( roar_vio_open_fh_socket(calls, fh) == -1 ) { close(fh); return -1; } // there is no problem if the shutdown()s fail. // some socket domains don't support unidirectional connections // this just free()s some kernel buffers :) switch (def->o_flags & (O_RDONLY|O_WRONLY|O_RDWR)) { case O_RDONLY: ROAR_SHUTDOWN(fh, SHUT_WR); break; case O_WRONLY: ROAR_SHUTDOWN(fh, SHUT_RD); break; } return 0; #else return -1; #endif } int roar_vio_socket_init_socket_def (struct roar_vio_defaults * def, int domain, int type) { #ifdef _CAN_OPERATE if ( def == NULL || domain == -1 || type == -1 ) return -1; // we do not memset(def, 0, sizeof(...)) here // because this is allready done in roar_vio_dstr_init_defaults() // if we would be would override o_flags/o_mode and maybe others memset(&(def->d.socket.sa), 0, sizeof(def->d.socket.sa)); def->type = ROAR_VIO_DEF_TYPE_SOCKET; def->d.socket.domain = domain; def->d.socket.type = type; def->d.socket.sa.sa.sa_family = domain; return 0; #else return -1; #endif } int roar_vio_socket_init_dstr_def (struct roar_vio_defaults * def, char * dstr, int hint, int type, struct roar_vio_defaults * odef) { #ifdef _CAN_OPERATE char * host; #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6) int port; #endif #if defined(ROAR_HAVE_IPV4) int ret; #endif if ( def == NULL ) return -1; if ( dstr == NULL && odef == NULL ) return -1; if ( dstr == NULL ) dstr = ""; ROAR_DBG("roar_vio_socket_init_dstr_def(def=%p, dstr='%s', hint=%i, type=%i, odef=%p) = ?", def, dstr, hint, type, odef); if ( hint == -1 ) { if ( 0 ) { // this is needed to keep the syntx ok, compiler will throw it away #ifdef ROAR_HAVE_IPV6 } else if ( strstr(dstr, "[") != NULL ) { // [ip]:service hint = AF_INET6; #endif #ifdef ROAR_HAVE_LIBDNET } else if ( strstr(dstr, "::") != NULL ) { // node::object hint = AF_DECnet; #endif #ifdef ROAR_HAVE_IPX } else if ( strstr(dstr, "(") != NULL ) { // net:mac(service) hint = AF_IPX; #endif #ifdef ROAR_HAVE_UNIX } else if ( strstr(dstr, "/") != NULL ) { // /path/to/sock hint = AF_UNIX; #endif #ifdef ROAR_HAVE_IPV4 } else if ( strstr(dstr, ":") != NULL ) { // host:port hint = AF_INET; #endif } } if ( hint == -1 && odef != NULL ) { // if we still don't know what this is we try // to use the parent objects request ROAR_DBG("roar_vio_socket_init_dstr_def(*): hint=-1 && odef!=NULL"); if ( odef->type == ROAR_VIO_DEF_TYPE_SOCKET ) { ROAR_DBG("roar_vio_socket_init_dstr_def(*): hint=-1 && odef!=NULL, using hint from odef"); hint = odef->d.socket.domain; } } if ( hint == -1 ) /* we really have no glue what this is... */ return -1; #ifdef ROAR_HAVE_UNIX if ( hint == AF_UNIX ) { if ( *dstr != 0 && strcmp(dstr, "//") != 0 ) { return roar_vio_socket_init_unix_def(def, dstr); } else { if ( roar_vio_socket_conv_def(odef, AF_UNIX) == -1 ) return -1; return roar_vio_socket_init_unix_def(def, odef->d.socket.sa.un.sun_path); } } #endif ROAR_DBG("roar_vio_socket_init_dstr_def(*) = ?"); if ( *dstr == 0 ) { if ( roar_vio_socket_conv_def(odef, hint) == -1 ) return -1; if ( odef->d.socket.type != type ) return -1; if ( def != odef ) memcpy(def, odef, sizeof(struct roar_vio_defaults)); return 0; } for (; *dstr == '/'; dstr++); ROAR_DBG("roar_vio_socket_init_dstr_def(*) = ?"); switch (hint) { #ifdef ROAR_HAVE_IPV4 case AF_INET: host = dstr; for (; *dstr != 0 && *dstr != ':'; dstr++); if ( *dstr == ':' ) { // we have a port :) *dstr++ = 0; if ( (port = roar_vio_socket_get_port(dstr, AF_INET, type)) == -1 ) return -1; ret = roar_vio_socket_init_inet4_def(def, host, port, type); *(dstr-1) = ':'; return ret; } else { if ( roar_vio_socket_conv_def(odef, AF_INET) == -1 ) return -1; return roar_vio_socket_init_inet4_def(def, host, ROAR_NET2HOST16(odef->d.socket.sa.in.sin_port), type); } break; #endif #ifdef ROAR_HAVE_LIBDNET case AF_DECnet: ROAR_DBG("roar_vio_socket_init_dstr_def(*) = ?"); host = dstr; if ( type != SOCK_STREAM ) return -1; if ( (dstr = strstr(dstr, "::")) == NULL ) { if ( roar_vio_socket_conv_def(odef, AF_DECnet) == -1 ) return -1; return -1; // return roar_vio_socket_init_decnet_def(def, host, -1, dstr); } else { *dstr = 0; dstr += 2; return roar_vio_socket_init_decnet_def(def, host, -1, dstr); } break; #endif #ifdef ROAR_HAVE_IPV6 case AF_INET6: return -1; break; #endif #ifdef ROAR_HAVE_IPX case AF_IPX: return -1; break; #endif default: return -1; } return 0; #else return -1; #endif } #ifdef _CAN_OPERATE int roar_vio_socket_conv_def (struct roar_vio_defaults * def, int domain) { if ( def == NULL || domain == -1 ) return -1; #ifdef ROAR_HAVE_UNIX if ( domain == AF_UNIX ) { if ( def->type == ROAR_VIO_DEF_TYPE_SOCKET ) { if ( def->d.socket.domain == AF_UNIX ) return 0; return -1; } else { if ( def->type == ROAR_VIO_DEF_TYPE_FILE ) return roar_vio_socket_init_unix_def(def, def->d.file); return -1; } } #endif if ( def->type != ROAR_VIO_DEF_TYPE_SOCKET ) return -1; if ( def->d.socket.domain == domain ) return 0; // we sould add support to convert IPv4 <-> IPv6 here return -1; } int roar_vio_socket_get_port (char * service, int domain, int type) { #ifdef ROAR_HAVE_GETSERVBYNAME struct servent * serv = NULL; char * proto = NULL; #endif int port; char * ts; if ( service == NULL || domain == -1 || type == -1 ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( (ts = strstr(service, "/")) != NULL ) *ts = 0; if ( sscanf(service, "%i", &port) == 1 ) return port; if ( ts != NULL ) *ts = '/'; switch (domain) { #ifdef ROAR_HAVE_IPV6 case AF_INET6: #endif #ifdef ROAR_HAVE_IPV4 case AF_INET: #endif #if defined(ROAR_HAVE_IPV6) || defined(ROAR_HAVE_IPV4) switch (type) { case SOCK_STREAM: #ifdef ROAR_HAVE_GETSERVBYNAME proto = "tcp"; #endif break; case SOCK_DGRAM: #ifdef ROAR_HAVE_GETSERVBYNAME proto = "udp"; #endif break; default: return -1; } break; #endif #ifdef ROAR_HAVE_LIBDNET case AF_DECnet: #ifdef ROAR_HAVE_GETOBJECTBYNAME return getobjectbyname(service); #else if ( !strcmp(service, "roar") ) return 0; roar_err_set(ROAR_ERROR_NOENT); return -1; #endif break; #endif default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; } #ifdef ROAR_HAVE_GETSERVBYNAME if ( ts != NULL ) *ts = 0; if ( (serv = getservbyname(service, proto)) == NULL ) { roar_err_from_errno(); ROAR_DBG("roar_vio_socket_get_port(*): Unknown service: %s/%s: %s", service, proto, strerror(errno)); if ( ts != NULL ) *ts = '/'; return -1; } if ( ts != NULL ) *ts = '/'; return ROAR_NET2HOST16(serv->s_port); #endif roar_err_set(ROAR_ERROR_NOTSUP); return -1; } #endif // AF_UNIX: int roar_vio_socket_init_unix_def (struct roar_vio_defaults * def, const char * path) { #if defined(ROAR_HAVE_UNIX) && defined(_CAN_OPERATE) if ( def == NULL || path == NULL ) return -1; if ( roar_vio_socket_init_socket_def(def, AF_UNIX, SOCK_STREAM) == -1 ) return -1; strncpy(def->d.socket.sa.un.sun_path, path, sizeof(def->d.socket.sa.un.sun_path) - 1); return 0; #else return -1; #endif } // AF_DECnet: int roar_vio_socket_init_decnetnode_def(struct roar_vio_defaults * def) { #if defined(ROAR_HAVE_LIBDNET) && defined(_CAN_OPERATE) char * node; char * ed; struct nodeent * ne; if ( def == NULL ) return -1; if ( def->d.socket.host == NULL ) return -1; if ( (node = roar_mm_strdup(def->d.socket.host)) == NULL ) return -1; if ( (ed = strstr(node, "/")) != NULL ) *ed = 0; ne = getnodebyname(node); roar_mm_free(ed); if ( ne == NULL ) { ROAR_ERR("roar_vio_socket_init_decnetnode_def(*): Can\'t resolve node name '%s'", node); return -1; } memcpy(&(def->d.socket.sa.dn.sdn_add.a_addr), ne->n_addr, 2); return 0; #else return -1; #endif } int roar_vio_socket_init_decnet_def (struct roar_vio_defaults * def, const char * node, int object, char * objname) { #if defined(ROAR_HAVE_LIBDNET) && defined(_CAN_OPERATE) struct sockaddr_dn * dn; if ( def == NULL ) return -1; if ( object < 1 && objname == NULL ) return -1; if ( object == -1 ) object = roar_vio_socket_get_port(objname, AF_DECnet, SOCK_STREAM); if ( object == -1 ) { if ( objname == NULL ) { return -1; } else { object = 0; } } if ( roar_vio_socket_init_socket_def(def, AF_DECnet, SOCK_STREAM) == -1 ) return -1; def->d.socket.host = node; dn = &(def->d.socket.sa.dn); dn->sdn_flags = 0; dn->sdn_objnum = object; dn->sdn_nodeaddrl = 2; if ( objname == NULL ) { dn->sdn_objnamel = 0; } else { dn->sdn_objnamel = strlen(objname); if ( dn->sdn_objnamel > DN_MAXOBJL ) dn->sdn_objnamel = DN_MAXOBJL; memcpy(&(dn->sdn_objname), objname, dn->sdn_objnamel); } return 0; #else return -1; #endif } // AF_INET: int roar_vio_socket_init_inet4host_def(struct roar_vio_defaults * def) { #if defined(ROAR_HAVE_IPV4) && defined(_CAN_OPERATE) struct hostent * he; char * ed, * pd; if ( def == NULL ) return -1; if ( def->d.socket.host == NULL ) return -1; if ( (ed = strstr(def->d.socket.host, "/")) != NULL ) *ed = 0; if ( (pd = strstr(def->d.socket.host, ":")) != NULL ) *pd = 0; if ( (he = gethostbyname(def->d.socket.host)) == NULL ) { ROAR_ERR("roar_vio_socket_init_inet4host_def(*): Can\'t resolve host name '%s'", def->d.socket.host); if ( ed != NULL ) *ed = '/'; return -1; } if ( pd != NULL ) *pd = ':'; if ( ed != NULL ) *ed = '/'; memcpy((struct in_addr *)&def->d.socket.sa.in.sin_addr, he->h_addr, sizeof(struct in_addr)); return 0; #else return -1; #endif } int roar_vio_socket_init_inet4_def (struct roar_vio_defaults * def, const char * host, int port, int type) { #if defined(ROAR_HAVE_IPV4) && defined(_CAN_OPERATE) if ( roar_vio_socket_init_socket_def(def, AF_INET, type) == -1 ) return -1; def->d.socket.host = host; def->d.socket.sa.in.sin_port = ROAR_HOST2NET16(port); return 0; #else return -1; #endif } int roar_vio_socket_init_tcp4_def (struct roar_vio_defaults * def, const char * host, int port) { return roar_vio_socket_init_inet4_def(def, host, port, SOCK_STREAM); } int roar_vio_socket_init_udp4_def (struct roar_vio_defaults * def, const char * host, int port) { return roar_vio_socket_init_inet4_def(def, host, port, SOCK_DGRAM); } // AF_INET6: int roar_vio_socket_init_inet6host_def(struct roar_vio_defaults * def); int roar_vio_socket_init_inet6_def (struct roar_vio_defaults * def, const char * host, int port, int type) { return -1; } int roar_vio_socket_init_tcp6_def (struct roar_vio_defaults * def, const char * host, int port) { return roar_vio_socket_init_inet6_def(def, host, port, SOCK_STREAM); } int roar_vio_socket_init_udp6_def (struct roar_vio_defaults * def, const char * host, int port) { return roar_vio_socket_init_inet6_def(def, host, port, SOCK_DGRAM); } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_stack.c�������������������������������������������������������������0000644�0001750�0001750�00000012071�12264733553�016252� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_stack.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_stack (struct roar_vio_calls * calls) { return roar_vio_open_stack2(calls, free); } int roar_vio_open_stack2 (struct roar_vio_calls * calls, void (*func)(void*)) { struct roar_vio_stack * self; if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( func == NULL ) func = roar_mm_free_retvoid; if ( (self = roar_mm_malloc(sizeof(struct roar_vio_stack))) == NULL ) return -1; memset(self, 0, sizeof(struct roar_vio_stack)); memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; self->free = func; calls->inst = self; calls->close = roar_vio_stack_close; calls->ctl = roar_vio_stack_ctl; calls->read = roar_vio_stack_read; calls->write = roar_vio_stack_write; calls->lseek = roar_vio_stack_lseek; calls->sync = roar_vio_stack_sync; return 0; } int roar_vio_stack_add (struct roar_vio_calls * calls, struct roar_vio_calls * vio) { struct roar_vio_stack * self; if ( calls == NULL || vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( (self = calls->inst) == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( self->next == ROAR_VIO_STACK_MAX ) return -1; self->cur = self->calls[self->next++] = vio; return 0; } int roar_vio_stack_close (struct roar_vio_calls * vio) { struct roar_vio_stack * self; int i; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( (self = vio->inst) == NULL ) return -1; if ( self->cur != NULL ) { if ( roar_vio_close(self->cur) == -1 ) return -1; for (i = 0; i < self->next; i++) self->free(self->calls[i]); } roar_mm_free(self); return 0; } int roar_vio_stack_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if (vio == NULL || cmd == -1) return -1; switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "stack"; return 0; break; case ROAR_VIO_CTL_GET_FH: case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_WRITE_FH: case ROAR_VIO_CTL_SELECT: return roar_vio_ctl(((struct roar_vio_stack*)(vio->inst))->cur, cmd, data); break; case ROAR_VIO_CTL_GET_NEXT: *(struct roar_vio_calls **)data = ((struct roar_vio_stack*)(vio->inst))->cur; return 0; break; } return roar_vio_ctl(((struct roar_vio_stack*)(vio->inst))->cur, cmd, data); } ssize_t roar_vio_stack_read (struct roar_vio_calls * vio, void *buf, size_t count) { if ( vio == NULL ) return -1; if ( vio->inst == NULL ) return -1; if ( ((struct roar_vio_stack*)(vio->inst))->cur == NULL ) return -1; return roar_vio_read(((struct roar_vio_stack*)(vio->inst))->cur, buf, count); } ssize_t roar_vio_stack_write (struct roar_vio_calls * vio, void *buf, size_t count) { if ( vio == NULL ) return -1; if ( vio->inst == NULL ) return -1; if ( ((struct roar_vio_stack*)(vio->inst))->cur == NULL ) return -1; return roar_vio_write(((struct roar_vio_stack*)(vio->inst))->cur, buf, count); } roar_off_t roar_vio_stack_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { if ( vio == NULL ) return -1; if ( vio->inst == NULL ) return -1; if ( ((struct roar_vio_stack*)(vio->inst))->cur == NULL ) return -1; return roar_vio_lseek(((struct roar_vio_stack*)(vio->inst))->cur, offset, whence); } int roar_vio_stack_sync (struct roar_vio_calls * vio) { if ( vio == NULL ) return -1; if ( vio->inst == NULL ) return -1; if ( ((struct roar_vio_stack*)(vio->inst))->cur == NULL ) return -1; return roar_vio_sync(((struct roar_vio_stack*)(vio->inst))->cur); } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_stdio.c�������������������������������������������������������������0000644�0001750�0001750�00000012716�12264733553�016275� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_stdio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_open_stdio (struct roar_vio_calls * calls, FILE * dst) { #ifndef ROAR_WITHOUT_VIO_STDIO if ( calls == NULL || dst == NULL ) return -1; memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->read = roar_vio_stdio_read; calls->write = roar_vio_stdio_write; calls->lseek = roar_vio_stdio_lseek; calls->sync = roar_vio_stdio_sync; calls->close = roar_vio_stdio_close; calls->inst = dst; return 0; #else return -1; #endif } FILE * roar_vio_to_stdio (struct roar_vio_calls * calls, int flags) { #ifdef ROAR_HAVE_FOPENCOOKIE cookie_io_functions_t foc_funcs; #endif // (void)flags is the the individual sections because later added APIs // may require those flags. if ( calls == NULL ) return NULL; #if defined(ROAR_HAVE_FOPENCOOKIE) (void)flags; memset(&foc_funcs, 0, sizeof(cookie_io_functions_t)); foc_funcs.close = roar_vio_to_stdio_close; foc_funcs.read = roar_vio_to_stdio_read; foc_funcs.write = roar_vio_to_stdio_write; return fopencookie((void*) calls, "rw", foc_funcs); #elif defined(ROAR_HAVE_FUNOPEN) (void)flags; return funopen((void*) calls, roar_vio_to_stdio_read, roar_vio_to_stdio_write, roar_vio_to_stdio_lseek, roar_vio_to_stdio_close); #else return NULL; #endif } #if defined(ROAR_HAVE_FOPENCOOKIE) || defined(ROAR_HAVE_FUNOPEN) int roar_vio_to_stdio_close (void *__cookie) { return roar_vio_close((struct roar_vio_calls *) __cookie); } #if defined(ROAR_HAVE_FOPENCOOKIE) ssize_t roar_vio_to_stdio_read (void *__cookie, char *__buf, size_t __nbytes) { #elif defined(ROAR_HAVE_FUNOPEN) int roar_vio_to_stdio_read(void *__cookie, char *__buf, int __nbytes) { #endif return roar_vio_read((struct roar_vio_calls *) __cookie, __buf, __nbytes); } #if defined(ROAR_HAVE_FOPENCOOKIE) ssize_t roar_vio_to_stdio_write (void *__cookie, __const char *__buf, size_t __n) { #elif defined(ROAR_HAVE_FUNOPEN) int roar_vio_to_stdio_write(void *__cookie, const char *__buf, int __n) { #endif ROAR_DBG("roar_vio_to_stdio_write(*) = ?"); return roar_vio_write((struct roar_vio_calls *) __cookie, (char *) __buf, __n); } #if defined(ROAR_HAVE_FOPENCOOKIE) int roar_vio_to_stdio_lseek (void *__cookie, _IO_off64_t *__pos, int __w); #elif defined(ROAR_HAVE_FUNOPEN) fpos_t roar_vio_to_stdio_lseek(void *__cookie, fpos_t __pos, int __w) { return roar_vio_lseek((struct roar_vio_calls *) __cookie, __pos, __w); } #endif #endif // VIOs: // stdio: #ifndef ROAR_WITHOUT_VIO_STDIO ssize_t roar_vio_stdio_read (struct roar_vio_calls * vio, void *buf, size_t count) { return fread(buf, 1, count, (FILE*)(vio->inst)); } ssize_t roar_vio_stdio_write (struct roar_vio_calls * vio, void *buf, size_t count) { return fwrite(buf, 1, count, (FILE*)(vio->inst)); } roar_off_t roar_vio_stdio_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { // ftell() is broken on win. It sometimes returnes the binary offset and sometimes // the text mode offset (why? why are both diffrent?). #if defined(ROAR_HAVE_FSEEK) && defined(ROAR_HAVE_FTELL) && !defined(ROAR_TARGET_WIN32) if ( fseek((FILE*)(vio->inst), offset, whence) == -1 ) return -1; return ftell((FILE*)(vio->inst)); #else return (roar_off_t)-1; #endif } int roar_vio_stdio_sync (struct roar_vio_calls * vio) { return fflush((FILE*)(vio->inst)); } int roar_vio_stdio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if ( vio == NULL || cmd == -1 ) return -1; switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "stdio"; return 0; break; #ifdef ROAR_HAVE_FILENO case ROAR_VIO_CTL_GET_FH: case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_WRITE_FH: case ROAR_VIO_CTL_GET_SELECT_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: case ROAR_VIO_CTL_GET_SELECT_WRITE_FH: *(int*)data = fileno((FILE*)(vio->inst)); return 0; break; #endif } return -1; } int roar_vio_stdio_close (struct roar_vio_calls * vio) { return fclose((FILE*)(vio->inst)); } #endif //ll ��������������������������������������������������roaraudio-1.0beta11/libroar/vio_stdvios.c�����������������������������������������������������������0000644�0001750�0001750�00000006137�12264733553�016646� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_stdvios.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static struct roar_vio_calls _libroar_vio_stdvios[3] = { { .inst = (void*)(ROAR_INSTINT)(ROAR_STDIN + 1), .flags = 0x00000000, .refc = 1, .read = roar_vio_basic_read, .write = roar_vio_basic_write, .lseek = roar_vio_basic_lseek, .sync = roar_vio_basic_sync, .ctl = roar_vio_basic_ctl, .close = roar_vio_basic_close }, { .inst = (void*)(ROAR_INSTINT)(ROAR_STDOUT + 1), .flags = 0x00000000, .refc = 1, .read = roar_vio_basic_read, .write = roar_vio_basic_write, .lseek = roar_vio_basic_lseek, .sync = roar_vio_basic_sync, .ctl = roar_vio_basic_ctl, .close = roar_vio_basic_close }, { .inst = (void*)(ROAR_INSTINT)(ROAR_STDERR + 1), .flags = 0x00000000, .refc = 1, .read = roar_vio_basic_read, .write = roar_vio_basic_write, .lseek = roar_vio_basic_lseek, .sync = roar_vio_basic_sync, .ctl = roar_vio_basic_ctl, .close = roar_vio_basic_close } }; #ifndef ROAR_TARGET_WIN32 struct roar_vio_calls * roar_stdin = &(_libroar_vio_stdvios[0]); struct roar_vio_calls * roar_stdout = &(_libroar_vio_stdvios[1]); struct roar_vio_calls * roar_stderr = &(_libroar_vio_stdvios[2]); #else struct roar_vio_calls ** libroar_stdvio_win32workaround(int fh) { static struct roar_vio_calls * vios[3] = { &(_libroar_vio_stdvios[0]), &(_libroar_vio_stdvios[1]), &(_libroar_vio_stdvios[2]) }; if ( fh >= 0 && fh <= 2) { return &(vios[fh]); } else { roar_strap(ROAR_TRAP_GROUP_LIBROAR, "libroar_stdvio_win32workaround.bad-fh"); roar_err_set(ROAR_ERROR_BADFH); // just in case somebody uses a debugger. return NULL; } } #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_stream.c������������������������������������������������������������0000644�0001750�0001750�00000027750�12264733553�016452� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_stream.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" static ssize_t _vio_stream_read (struct roar_vio_calls * vio, void *buf, size_t count) { return roar_vio_read(roar_get_connection_vio2(vio->inst), buf, count); } static ssize_t _vio_stream_write (struct roar_vio_calls * vio, void *buf, size_t count) { return roar_vio_write(roar_get_connection_vio2(vio->inst), buf, count); } static roar_off_t _vio_stream_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { return roar_vio_lseek(roar_get_connection_vio2(vio->inst), offset, whence); } static int _vio_stream_sync (struct roar_vio_calls * vio) { return roar_vio_sync(roar_get_connection_vio2(vio->inst)); } static int _vio_stream_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if (vio == NULL) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if (cmd == -1) { roar_err_set(ROAR_ERROR_INVAL); return -1; } switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } *(char**)data = "stream"; return 0; break; case ROAR_VIO_CTL_GET_NEXT: *(struct roar_vio_calls **)data = roar_get_connection_vio2(vio->inst); return 0; break; case ROAR_VIO_CTL_SET_NEXT: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_NONBLOCK: return roar_vio_ctl(roar_get_connection_vio2(vio->inst), ROAR_VIO_CTL_NONBLOCK, data); break; } return roar_vio_ctl(roar_get_connection_vio2(vio->inst), cmd, data); } static int _vio_stream_close (struct roar_vio_calls * vio) { roar_vio_close(roar_get_connection_vio2(vio->inst)); roar_mm_free(vio->inst); return 0; } int roar_vio_simple_stream (struct roar_vio_calls * calls, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, const char * server, int dir, const char * name, int mixer) { struct roar_connection * con = NULL; struct roar_stream stream; int err; if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( roar_stream_new(&stream, rate, channels, bits, codec) == -1 ) return -1; con = roar_mm_malloc(sizeof(struct roar_connection)); if ( con == NULL ) return -1; memset(con, 0, sizeof(struct roar_connection)); if ( roar_simple_connect(con, server, name) == -1 ) { roar_mm_free_noerror(con); return -1; } if ( roar_stream_connect(con, &stream, dir, mixer) == -1 ) { err = roar_error; roar_disconnect(con); roar_mm_free(con); roar_error = err; return -1; } if ( roar_stream_exec(con, &stream) == -1 ) { err = roar_error; roar_disconnect(con); roar_mm_free(con); roar_error = err; return -1; } roar_vio_clear_calls(calls); calls->inst = con; calls->read = _vio_stream_read; calls->write = _vio_stream_write; calls->lseek = _vio_stream_lseek; calls->sync = _vio_stream_sync; calls->ctl = _vio_stream_ctl; calls->close = _vio_stream_close; if ( dir == ROAR_DIR_PLAY ) { roar_vio_shutdown(calls, SHUT_RD); } else if ( dir == ROAR_DIR_MONITOR || dir == ROAR_DIR_RECORD ) { roar_vio_shutdown(calls, SHUT_WR); } return 0; } static int _roar_simple_new_stream_obj (struct roar_connection * con, struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, int dir, int mixer) { struct roar_libroar_config * config = roar_libroar_get_config(); char file[80] = ""; int fh = -1, listen = -1; static int count = 0; int port = 0; #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_LIBDNET) int opt = 1; #endif #ifdef ROAR_HAVE_IPV4 struct sockaddr_in socket_addr; socklen_t len = sizeof(struct sockaddr_in); #else struct sockaddr socket_addr; socklen_t len = sizeof(struct sockaddr); #endif #ifdef ROAR_HAVE_SELECT int confh; fd_set fds; struct timeval timeout = {10, 0}; struct roar_message mes; #endif #ifdef ROAR_HAVE_UNIX int socks[2]; // for socketpair() #endif struct roar_sockname sockname; // make valgrind happy memset(&socket_addr, 0, sizeof(socket_addr)); #ifdef ROAR_HAVE_SELECT memset(&mes, 0, sizeof(mes)); #endif ROAR_DBG("_roar_simple_new_stream_obj(con=%p, s=%p, rate=%i, channels=%i, bits=%i, codec=%i, dir=%i, mixer=%i) = ?", con, s, (int)rate, (int)channels, (int)bits, (int)codec, dir, mixer); if ( config != NULL ) { if ( config->workaround.workarounds & ROAR_LIBROAR_CONFIG_WAS_USE_EXECED ) { return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); } } ROAR_DBG("_roar_simple_new_stream_obj(con=%p, s=%p, rate=%i, channels=%i, bits=%i, codec=%i, dir=%i, mixer=%i) = ?", con, s, (int)rate, (int)channels, (int)bits, (int)codec, dir, mixer); roar_libroar_nowarn(); if ( roar_vio_ctl(roar_get_connection_vio2(con), ROAR_VIO_CTL_GET_SOCKNAME, &sockname) == -1 ) { roar_libroar_warn(); #ifdef ROAR_OS_OPENBSD sockname.type = ROAR_SOCKET_TYPE_UNIX; #else ROAR_DBG("_roar_simple_new_stream_obj(con=%p, s=%p, rate=%i, channels=%i, bits=%i, codec=%i, dir=%i, mixer=%i) = -1", con, s, (int)rate, (int)channels, (int)bits, (int)codec, dir, mixer); return -1; #endif } roar_libroar_warn(); ROAR_DBG("_roar_simple_new_stream_obj(con=%p, s=%p, rate=%i, channels=%i, bits=%i, codec=%i, dir=%i, mixer=%i) = ?", con, s, (int)rate, (int)channels, (int)bits, (int)codec, dir, mixer); if ( sockname.type == ROAR_SOCKET_TYPE_DECNET ) { if ( roar_socket_get_local_nodename() ) { snprintf(file, sizeof(file), "%s::roar$TMP%04x%02x", roar_socket_get_local_nodename(), getpid(), count++); } else { return -1; } #ifdef ROAR_HAVE_IPV4 } else { strncpy(file, inet_ntoa(socket_addr.sin_addr), sizeof(file) - 1); #endif } if ( sockname.type != ROAR_SOCKET_TYPE_UNIX ) { if ( (listen = roar_socket_listen(sockname.type, file, port)) == -1 ) { return -1; } } if ( sockname.type == ROAR_SOCKET_TYPE_INET ) { #ifdef ROAR_HAVE_IPV4 setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(int)); len = sizeof(struct sockaddr_in); if ( getsockname(listen, (struct sockaddr *)&socket_addr, &len) == -1 ) { return -1; } port = ROAR_NET2HOST16(socket_addr.sin_port); ROAR_DBG("roar_simple_new_stream_obj(*): port=%i", port); #else return -1; #endif } else if ( sockname.type == ROAR_SOCKET_TYPE_DECNET ) { #ifdef ROAR_HAVE_LIBDNET setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)); #else return -1; #endif } if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) { return -1; } if ( roar_stream_connect(con, s, dir, mixer) == -1 ) { return -1; } if ( sockname.type != ROAR_SOCKET_TYPE_UNIX ) { #ifdef ROAR_HAVE_SELECT if ( roar_stream_connect_to_ask(con, s, sockname.type, file, port) != -1 ) { FD_ZERO(&fds); FD_SET(listen, &fds); confh = roar_get_connection_fh(con); if ( confh != -1 ) { FD_SET(confh, &fds); } if ( select((confh > listen ? confh : listen) + 1, &fds, NULL, NULL, &timeout) < 1 ) { close(listen); // we don't need to check the content as we know it failed... if ( roar_recv_message(con, &mes, NULL) == -1 ) return -1; if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 ) return -1; return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); } if ( FD_ISSET(listen, &fds) ) { if ( (fh = accept(listen, NULL, NULL)) != -1 ) { /* errr, do we need we any error handling here? */ } if ( roar_recv_message(con, &mes, NULL) == -1 ) { if ( fh != -1 ) close(fh); fh = -1; } else if ( mes.cmd != ROAR_CMD_OK ) { if ( fh != -1 ) close(fh); fh = -1; } } else { // we don't need to check the content as we know it failed... if ( roar_recv_message(con, &mes, NULL) == -1 ) { close(listen); return -1; } if ( mes.cmd != ROAR_CMD_OK ) { close(listen); if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 ) return -1; return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); } else { // seems like we have a positive reply. So we retry the listen socket: FD_ZERO(&fds); FD_SET(listen, &fds); timeout.tv_sec = 0; timeout.tv_usec = 128000L; fh = -1; if ( select(listen + 1, &fds, NULL, NULL, &timeout) > 0 ) { if ( (fh = accept(listen, NULL, NULL)) == -1 ) { close(listen); if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 ) return -1; return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); } } } } } close(listen); #else return -1; #endif } else { // this is sockname.type == ROAR_SOCKET_TYPE_UNIX #ifdef ROAR_HAVE_UNIX if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) { roar_kick(con, ROAR_OT_STREAM, s->id); // we do not need to check for errors // as we return -1 in both whys return -1; } if ( roar_stream_passfh(con, s, socks[0]) == -1 ) { roar_kick(con, ROAR_OT_STREAM, s->id); // we do not need to check for errors // as we return -1 anyway. close(socks[0]); close(socks[1]); return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); } close(socks[0]); fh = socks[1]; #else roar_kick(con, ROAR_OT_STREAM, s->id); return -1; #endif } if ( fh != -1 ) { if ( dir == ROAR_DIR_PLAY ) { (void)ROAR_SHUTDOWN(fh, SHUT_RD); } else if ( dir == ROAR_DIR_MONITOR || dir == ROAR_DIR_RECORD ) { (void)ROAR_SHUTDOWN(fh, SHUT_WR); } } s->fh = fh; ROAR_DBG("_roar_simple_new_stream_obj(con=%p, s=%p, rate=%i, channels=%i, bits=%i, codec=%i, dir=%i, mixer=%i) = %i", con, s, (int)rate, (int)channels, (int)bits, (int)codec, dir, mixer, fh); return fh; } int roar_vio_simple_new_stream_obj (struct roar_vio_calls * calls, struct roar_connection * con, struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, int dir, int mixer) { struct roar_stream stream; int fh; ROAR_DBG("roar_vio_simple_new_stream_obj(*) = ?"); if ( calls == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( s == NULL ) s = &stream; if ( (fh = _roar_simple_new_stream_obj(con, s, rate, channels, bits, codec, dir, mixer)) == -1 ) { ROAR_DBG("roar_vio_simple_new_stream_obj(*) = -1"); return -1; } ROAR_DBG("roar_vio_simple_new_stream_obj(*): fh=%i", fh); return roar_vio_open_fh_socket(calls, fh); } //ll ������������������������roaraudio-1.0beta11/libroar/vio_string.c������������������������������������������������������������0000644�0001750�0001750�00000007123�12264733553�016455� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_string.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" int roar_vio_putc (struct roar_vio_calls * vio, char c) { return roar_vio_write(vio, &c, 1); } int roar_vio_getc (struct roar_vio_calls * vio) { unsigned char c; if ( roar_vio_read(vio, &c, 1) != 1 ) return EOF; return c; } int roar_vio_printf(struct roar_vio_calls * vio, const char *format, ...) { va_list ap; int ret; char buf[8192]; va_start(ap, format); ret = vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); return roar_vio_write(vio, buf, ret); } char * roar_vio_fgets (struct roar_vio_calls * vio, char * s, size_t size) { size_t have = 0; size_t need = size; ssize_t ret; char cur; char buf[1024]; roar_off_t offs; char * eol; if ( size == 0 ) return s; if ( vio == NULL || s == NULL ) return NULL; // space for the \0 size -= 1; if ( (offs = roar_vio_lseek(vio, 0, SEEK_CUR)) == (roar_off_t)-1 ) { // need to use the one byte at a time methode while ( have < size ) { if ( roar_vio_read(vio, &cur, 1) != 1 ) break; s[have] = cur; have++; if ( cur == '\n' ) break; } } else { // can use the optimized version eol = NULL; memset(s, '+', size); while ( have < size && eol == NULL ) { ret = roar_vio_read(vio, buf, need > 1023 ? 1023 : need); if ( ret == -1 || ret == 0 ) break; ROAR_DBG("roar_vio_fgets(*): have=%u", (unsigned int) have); buf[1023] = 0; if ( (eol = strstr(buf, "\n")) == NULL ) { memcpy(s, buf, ret); s += ret; have += ret; need -= ret; } else { offs = eol - buf - ret + 1; if ( roar_vio_lseek(vio, offs, SEEK_CUR) == -1 ) return NULL; ROAR_DBG("roar_vio_fgets(*): have=%u", (unsigned int) have); ROAR_DBG("roar_vio_fgets(*): eol - buf=%lli", (long long) (eol - buf)); ret = (size_t)(eol - buf); ret++; ROAR_DBG("roar_vio_fgets(*): ret=%lli", (long long) ret); memcpy(s, buf, ret); have += ret; ROAR_DBG("roar_vio_fgets(*): have=%u", (unsigned int) have); break; } ROAR_DBG("roar_vio_fgets(*): have=%u", (unsigned int) have); } } ROAR_DBG("roar_vio_fgets(*): have=%u", (unsigned int) have); if ( !have ) return NULL; s[have] = 0; return s; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_tantalos.c����������������������������������������������������������0000644�0001750�0001750�00000005664�12264733553�017004� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_tantalos.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define _LEN 1024 #ifdef ROAR_HAVE_LIBSLP static struct roar_slp_cookie * roar_vio_open_get_cookie (int reinit) { static struct roar_slp_cookie cookie; static int inited = 0; if ( !inited ) { if ( roar_slp_cookie_init(&cookie, NULL) == -1 ) return NULL; inited++; } return &cookie; } #endif int roar_vio_open_tantalos (struct roar_vio_calls * calls, struct roar_vio_calls * dst, char * key, struct roar_vio_defaults * odef) { #ifdef ROAR_HAVE_LIBSLP struct roar_slp_cookie * cookie; char url[_LEN]; int i; int need_search = 0; time_t now = time(NULL); (void)dst; if ( (cookie = roar_vio_open_get_cookie(0)) == NULL ) return -1; if ( cookie->matchcount == 0 ) { need_search++; } else { for (i = 0; i < cookie->matchcount; i++) { if ( cookie->match[i].tod < now ) { need_search++; } } } if ( need_search ) { if ( (cookie = roar_vio_open_get_cookie(1)) == NULL ) return -1; if ( roar_slp_search(cookie, ROAR_SLP_URL_TYPE_DOWNLOAD_HTTP) == -1 ) return -1; } // work on key: for (; *key == '/'; key++); for (i = 0; i < cookie->matchcount; i++) { strncpy(url, cookie->match[i].url + ROAR_SLP_URL_TYPE_DOWNLOAD_HTTP_LEN - 4, _LEN); roar_mm_strscat(url, "?key="); roar_mm_strscat(url, key); ROAR_DBG("roar_vio_open_tantalos(*): url='%s'", url); if ( roar_vio_open_dstr_vio(calls, url, odef, 1, NULL) == 0 ) return 0; memset(calls, 0, sizeof(struct roar_vio_calls)); } return -1; #else return -1; #endif } //ll ����������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_winsock.c�����������������������������������������������������������0000644�0001750�0001750�00000007524�12264733553�016631� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_winsock.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_TARGET_WIN32 static int _get_fh(struct roar_vio_calls * vio) { int fh; if ( roar_vio_basic_ctl(vio, ROAR_VIO_CTL_GET_FH, &fh) == -1 ) return -1; return fh; } ssize_t roar_vio_winsock_read (struct roar_vio_calls * vio, void *buf, size_t count) { return recv(_get_fh(vio), buf, count, 0); } ssize_t roar_vio_winsock_write (struct roar_vio_calls * vio, void *buf, size_t count) { return send(_get_fh(vio), buf, count, 0); } int roar_vio_winsock_sync (struct roar_vio_calls * vio) { return 0; } int roar_vio_winsock_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { int tmp; int s_r = 0, s_w = 0; if ( vio == NULL || cmd == -1 ) return -1; ROAR_DBG("roar_vio_winsock_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "winsock"; return 0; break; case ROAR_VIO_CTL_GET_SELECT_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: case ROAR_VIO_CTL_GET_SELECT_WRITE_FH: ROAR_DBG("roar_vio_winsock_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_SELECT_*FH(0x%.8x), data=%p) = 0 // fh=%i", vio, cmd, data, _get_fh(vio)); *(int*)data = _get_fh(vio); return 0; break; case ROAR_VIO_CTL_SET_NOSYNC: vio->sync = NULL; return 0; break; case ROAR_VIO_CTL_ACCEPT: tmp = accept(_get_fh(vio), NULL, 0); if ( tmp == -1 ) return -1; // most proably a socket. if ( roar_vio_open_fh_socket(data, tmp) == -1 ) { closesocket(tmp); return -1; } return 0; break; case ROAR_VIO_CTL_SHUTDOWN: tmp = *(int*)data; if ( tmp & ROAR_VIO_SHUTDOWN_READ ) { s_r = 1; tmp -= ROAR_VIO_SHUTDOWN_READ; } if ( tmp & ROAR_VIO_SHUTDOWN_WRITE ) { s_w = 1; tmp -= ROAR_VIO_SHUTDOWN_WRITE; } if ( tmp != 0 ) /* we currently only support R and W shutdowns */ return -1; if ( s_r && s_w ) { tmp = SHUT_RDWR; } else if ( s_r ) { tmp = SHUT_RD; } else if ( s_w ) { tmp = SHUT_WR; } else { return 0; // nothing to do. } return shutdown(_get_fh(vio), tmp); break; case ROAR_VIO_CTL_GET_SOCKNAME: case ROAR_VIO_CTL_GET_PEERNAME: return roar_vio_basic_ctl(vio, cmd, data); break; } roar_err_set(ROAR_ERROR_BADRQC); return -1; } int roar_vio_winsock_close (struct roar_vio_calls * vio) { closesocket(_get_fh(vio)); return 0; } #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vio_zlib.c��������������������������������������������������������������0000644�0001750�0001750�00000037546�12264733554�016124� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_gzip.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #ifdef ROAR_HAVE_LIBZ #include <zlib.h> struct roar_vio_gzip { struct roar_vio_calls * next; struct roar_buffer * outbuf, * inbuf; int compressor_error, decompressor_error; int compressor_flush; int compressor_used; z_stream compressor, decompressor; gz_header gz_compressorheader, gz_decompressorheader; }; static void * _zalloc(voidpf opaque, uInt items, uInt size) { (void)opaque; return roar_mm_calloc(items, size); } static void _zfree(voidpf opaque, voidpf address) { (void)opaque; roar_mm_free(address); } static void _set_error (int error) { int raerror = ROAR_ERROR_UNKNOWN; switch (error) { case Z_OK: raerror = ROAR_ERROR_NONE; break; case Z_STREAM_END: raerror = ROAR_ERROR_NODATA; break; case Z_NEED_DICT: raerror = ROAR_ERROR_INVAL; break; case Z_ERRNO: roar_err_from_errno(); break; case Z_STREAM_ERROR: raerror = ROAR_ERROR_INVAL; break; case Z_DATA_ERROR: raerror = ROAR_ERROR_BADCKSUM; break; case Z_MEM_ERROR: raerror = ROAR_ERROR_NOMEM; break; case Z_BUF_ERROR: raerror = ROAR_ERROR_FAULT; break; case Z_VERSION_ERROR: raerror = ROAR_ERROR_BADVERSION; break; } ROAR_DBG("_set_error(error=%i): raerror=%s", error, roar_error2str(raerror)); roar_err_set(raerror); } static int _init(struct roar_vio_gzip * self, struct roar_vio_calls * dst, int level, int gzip) { int ret; ROAR_DBG("_init(self=%p, dst=%p, level=%i, gzip=%i) = ?", self, dst, level, gzip); if ( self == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } ROAR_DBG("_init(self=%p, dst=%p, level=%i, gzip=%i) = ?", self, dst, level, gzip); if ( level == -1 ) { level = Z_DEFAULT_COMPRESSION; } memset(self, 0, sizeof(struct roar_vio_gzip)); self->next = dst; self->outbuf = NULL; self->inbuf = NULL; self->compressor_error = ROAR_ERROR_NONE; self->decompressor_error = ROAR_ERROR_NONE; self->compressor_flush = Z_SYNC_FLUSH; self->compressor_used = 0; self->compressor.zalloc = _zalloc; self->compressor.zfree = _zfree; self->compressor.opaque = NULL; self->compressor.next_in = NULL; self->compressor.next_out = NULL; self->decompressor.zalloc = _zalloc; self->decompressor.zfree = _zfree; self->decompressor.opaque = NULL; self->decompressor.next_in = NULL; self->decompressor.next_out = NULL; ROAR_DBG("_init(self=%p, dst=%p, level=%i, gzip=%i) = ?", self, dst, level, gzip); // for the magic numbers: see the zlib.h header file. There are no const for them. if ( (ret = deflateInit2(&(self->compressor), level, Z_DEFLATED, 15 + (gzip ? 16 : 0), 8, Z_DEFAULT_STRATEGY)) != Z_OK ) { _set_error(ret); return -1; } ROAR_DBG("_init(self=%p, dst=%p, level=%i, gzip=%i) = ?", self, dst, level, gzip); if ( (ret = inflateInit2(&(self->decompressor), 15+32)) != Z_OK ) { deflateEnd(&(self->compressor)); _set_error(ret); return -1; } ROAR_DBG("_init(self=%p, dst=%p, level=%i, gzip=%i) = ?", self, dst, level, gzip); // gzheader is descriped in RFC1952. memset(&(self->gz_compressorheader), 0, sizeof(self->gz_compressorheader)); self->gz_compressorheader.os = 255; // os='unknown' self->gz_compressorheader.hcrc = 0; // for compatibility memset(&(self->gz_decompressorheader), 0, sizeof(self->gz_decompressorheader)); self->gz_decompressorheader.os = 255; // os='unknown' self->gz_decompressorheader.hcrc = 0; // for compatibility if ( gzip ) { if ( (ret = deflateSetHeader(&(self->compressor), &(self->gz_compressorheader))) != Z_OK ) { deflateEnd(&(self->compressor)); inflateEnd(&(self->decompressor)); _set_error(ret); return -1; } } ROAR_DBG("_init(self=%p, dst=%p, level=%i, gzip=%i) = 0", self, dst, level, gzip); return 0; } static ssize_t roar_vio_zlib_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_gzip * self = vio->inst; struct roar_buffer * leftbuf; void * leftbufdata; size_t buflen; ssize_t len; size_t have = 0; int ret; unsigned char inbuf[1024]; ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); if ( self->decompressor_error != ROAR_ERROR_NONE ) { roar_err_set(self->decompressor_error); return -1; } ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); while ( self->inbuf != NULL ) { ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu): self->inbuf=%p", vio, buf, (long long unsigned)count, self->inbuf); if ( roar_buffer_get_data(self->inbuf, &leftbufdata) == -1 ) return -1; if ( roar_buffer_get_len(self->inbuf, &buflen) == -1 ) return -1; ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); self->decompressor.next_out = buf; self->decompressor.avail_out = count; self->decompressor.next_in = leftbufdata; self->decompressor.avail_in = buflen; ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu): in: %llu Bytes, out: count Bytes.", vio, buf, (long long unsigned)count, (long long unsigned int)buflen); ret = inflate(&(self->decompressor), Z_NO_FLUSH); ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu): inflate() returned %i", vio, buf, (long long unsigned)count, ret); len = count - self->decompressor.avail_out; if ( ret == Z_STREAM_END ) { count = len; ret = Z_OK; } if ( ret != Z_OK ) { if ( len == 0 ) { _set_error(ret); return -1; } else { have += len; return have; } } buf += len; have += len; count -= len; if ( len == (ssize_t)buflen ) { ret = roar_buffer_next(&(self->inbuf)); } else { ret = roar_buffer_set_offset(self->inbuf, len); } if ( ret == -1 ) { roar_err_set((self->decompressor_error = ROAR_ERROR_LOSTSYNC)); return -1; } if ( count == 0 ) return have; } ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); self->decompressor.next_out = buf; self->decompressor.avail_out = count; self->decompressor.next_in = NULL; self->decompressor.avail_in = 0; while (self->decompressor.avail_out > 0) { ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu): generating new output...", vio, buf, (long long unsigned)count); if ( self->decompressor.avail_in == 0 ) { ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu): reading more data", vio, buf, (long long unsigned)count); len = roar_vio_read(self->next, inbuf, sizeof(inbuf)); if ( len == -1 ) { have += count - self->decompressor.avail_out; if ( have == 0 ) { // error is still set (by roar_vio_read()). return -1; } else { return 0; } } else if ( len == 0 ) { break; } ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu): len=%llu", vio, buf, (long long unsigned)count, (long long unsigned)len); self->decompressor.next_in = inbuf; self->decompressor.avail_in = len; } ret = inflate(&(self->decompressor), Z_NO_FLUSH); ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu): inflate() returned %i", vio, buf, (long long unsigned)count, ret); if ( ret == Z_STREAM_END ) ret = Z_OK; if ( ret != Z_OK ) { if ( (count - self->decompressor.avail_out) == 0 ) { _set_error(ret); return -1; } else { break; } } ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); } if ( self->decompressor.avail_in != 0 ) { if ( roar_buffer_new_data(&leftbuf, self->decompressor.avail_in, &leftbufdata) == -1 ) { roar_err_set((self->decompressor_error = ROAR_ERROR_LOSTSYNC)); return -1; } memcpy(leftbufdata, self->decompressor.next_in, self->decompressor.avail_in); if ( self->inbuf == NULL ) { self->inbuf = leftbuf; } else { if ( roar_buffer_moveinto(self->inbuf, &leftbuf) == -1 ) { roar_buffer_free(leftbuf); roar_err_set((self->decompressor_error = ROAR_ERROR_LOSTSYNC)); return -1; } } } have += count - self->decompressor.avail_out; ROAR_DBG("roar_vio_zlib_read(vio=%p, buf=%p, count=%llu) = %llu", vio, buf, (long long unsigned)count, (long long unsigned)have); return have; } static ssize_t roar_vio_zlib_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_vio_gzip * self = vio->inst; struct roar_buffer * leftbuf; void * leftbufdata; size_t outlen; size_t buflen; char outbuf[1024]; ssize_t len; int ret; ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); self->compressor_used = 1; if ( self->compressor_error != ROAR_ERROR_NONE ) { roar_err_set(self->compressor_error); return -1; } ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); while (self->outbuf != NULL) { if ( roar_buffer_get_data(self->outbuf, &leftbufdata) == -1 ) return -1; if ( roar_buffer_get_len(self->outbuf, &buflen) == -1 ) return -1; len = roar_vio_write(self->next, leftbufdata, buflen); if ( len == -1 ) { return -1; } else if ( len == (ssize_t)buflen ) { if ( roar_buffer_next(&(self->outbuf)) == -1 ) { roar_err_set((self->compressor_error = ROAR_ERROR_LOSTSYNC)); return -1; } } else { if ( roar_buffer_set_offset(self->outbuf, len) == -1 ) { roar_err_set((self->compressor_error = ROAR_ERROR_LOSTSYNC)); return -1; } return 0; } } ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); self->compressor.next_in = buf; self->compressor.avail_in = count; while (self->compressor.avail_in || count == 0) { self->compressor.next_out = (unsigned char *)outbuf; self->compressor.avail_out = sizeof(outbuf); outlen = self->compressor.total_out; ret = deflate(&(self->compressor), count == 0 ? self->compressor_flush : Z_NO_FLUSH); outlen = self->compressor.total_out - outlen; ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu): deflate() returned %i", vio, buf, (long long unsigned)count, ret); ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu): outlen=%llu", vio, buf, (long long unsigned)count, (long long unsigned int)outlen); if ( count != 0 && ret != Z_OK ) { len = count - self->compressor.avail_in; if ( len != 0 ) { return len; } else { _set_error(ret); return -1; } } if ( outlen != 0 ) { len = roar_vio_write(self->next, outbuf, outlen); if ( len < (ssize_t)outlen ) { if ( roar_buffer_new_data(&leftbuf, outlen - len, &leftbufdata) == -1 ) { roar_err_set((self->compressor_error = ROAR_ERROR_LOSTSYNC)); return -1; } memcpy(leftbufdata, outbuf+len, outlen - len); if ( self->outbuf == NULL ) { self->outbuf = leftbuf; } else { if ( roar_buffer_moveinto(self->outbuf, &leftbuf) == -1 ) { roar_buffer_free(leftbuf); roar_err_set((self->compressor_error = ROAR_ERROR_LOSTSYNC)); return -1; } } break; } } ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); if ( count == 0 && ( (self->compressor_flush == Z_FINISH && ret == Z_STREAM_END) || (self->compressor_flush != Z_FINISH && ret == Z_BUF_ERROR) ) ) return 0; ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned)count); } len = count - self->compressor.avail_in; ROAR_DBG("roar_vio_zlib_write(vio=%p, buf=%p, count=%llu) = %llu", vio, buf, (long long unsigned)count, (long long unsigned int)len); return len; } static roar_off_t roar_vio_zlib_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { (void)vio, (void)offset, (void)whence; roar_err_set(ROAR_ERROR_NOSYS); return (roar_off_t)-1; } static int roar_vio_zlib_sync (struct roar_vio_calls * vio) { struct roar_vio_gzip * self = vio->inst; if ( self->compressor_used ) if ( self->compressor_error == ROAR_ERROR_NONE ) if ( roar_vio_zlib_write(vio, NULL, 0) == -1 ) return -1; roar_err_set(ROAR_ERROR_NOSYS); return -1; } static int roar_vio_zlib_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_vio_gzip * self; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } self = vio->inst; switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "zlib"; return 0; break; case ROAR_VIO_CTL_GET_NEXT: *(struct roar_vio_calls **)data = self->next; return 0; break; case ROAR_VIO_CTL_GET_FH: case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_WRITE_FH: case ROAR_VIO_CTL_GET_SELECT_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: case ROAR_VIO_CTL_GET_SELECT_WRITE_FH: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_NONBLOCK: return roar_vio_ctl(self->next, cmd, data); break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; } } static int roar_vio_zlib_close (struct roar_vio_calls * vio) { struct roar_vio_gzip * self; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } self = vio->inst; self->compressor_flush = Z_FINISH; roar_vio_zlib_sync(vio); deflateEnd(&(self->compressor)); inflateEnd(&(self->decompressor)); if ( self->outbuf != NULL ) roar_buffer_free(self->outbuf); if ( self->inbuf != NULL ) roar_buffer_free(self->inbuf); roar_mm_free(self); return 0; } int roar_vio_open_zlib(struct roar_vio_calls * calls, struct roar_vio_calls * dst, int level, int gzip) { struct roar_vio_gzip * self; ROAR_DBG("roar_vio_open_zlib(calls=%p, dst=%p, level=%i, gzip=%i) = ?", calls, dst, level, gzip); if ( calls == NULL || dst == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } self = roar_mm_malloc(sizeof(struct roar_vio_gzip)); if ( _init(self, dst, level, gzip) == -1 ) { roar_mm_free_noerror(self); ROAR_DBG("roar_vio_open_zlib(calls=%p, dst=%p, level=%i, gzip=%i) = -1 // error=%s", calls, dst, level, gzip, roar_error2str(err)); return -1; } ROAR_DBG("roar_vio_open_zlib(calls=%p, dst=%p, level=%i, gzip=%i) = ?", calls, dst, level, gzip); memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->inst = self; calls->read = roar_vio_zlib_read; calls->write = roar_vio_zlib_write; calls->lseek = roar_vio_zlib_lseek; calls->sync = roar_vio_zlib_sync; calls->ctl = roar_vio_zlib_ctl; calls->close = roar_vio_zlib_close; ROAR_DBG("roar_vio_open_zlib(calls=%p, dst=%p, level=%i, gzip=%i) = 0", calls, dst, level, gzip); return 0; } #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/vs.c��������������������������������������������������������������������0000644�0001750�0001750�00000117053�12264733554�014727� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vs.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #if defined(ROAR_HAVE_GETSOCKOPT) && defined(ROAR_HAVE_SETSOCKOPT) #define _HAVE_SOCKOPT #endif #define LOCAL_CLOCK ROAR_CLOCK_DEFAULT #define ASYNC_QLEN 4 #define FLAG_NONE 0x0000 #define FLAG_STREAM 0x0001 #define FLAG_NONBLOCK 0x0002 #define FLAG_BUFFERED 0x0004 #define FLAG_CLOSEFILE 0x0008 #define FLAG_FREE_VOL 0x0010 #define FLAG_DEF_PAUSE 0x0020 #define FLAG_VIO_RE 0x0040 #define FLAG_DIR_IN 0x1000 #define FLAG_DIR_OUT 0x2000 #define _initerr() roar_err_clear_all() #define _seterr(x) do { if ( error != NULL ) *error = (x); roar_err_set((x)); ROAR_DBG("roar_vs_*(*): *error=%s(%i)", roar_vs_strerr((x)), (x)); } while(0) #define _seterrre() do { _seterr(roar_error); } while(0) #define _seterrse() do { roar_err_from_errno(); _seterr(roar_error); } while(0) #define _ckvss(ret) do { if ( vss == NULL ) { _seterr(ROAR_ERROR_FAULT); return (ret); } } while(0) #define _ckasync(ret) do { if ( _handle_async(vss, error) == -1 ) { return (ret); } } while(0) struct roar_vs { int flags; struct roar_connection con_store; struct roar_connection * con; struct roar_stream stream; struct roar_vio_calls vio; struct roar_vio_calls vio_re; struct roar_vio_calls * vio_ptr; struct roar_audio_info info; size_t readc, writec; int mixerid; int first_primid; struct roar_buffer * readbuffer, * writebuffer; struct roar_vio_calls file_store; struct roar_vio_calls * file; struct roar_buffer * readring, * writering; #ifdef _HAVE_SOCKOPT struct { float target; float window; float minlag; float p; } latc; #endif struct { ssize_t last_pos; ssize_t last_offset; struct roar_time last_time; } latmes; struct { int level; size_t lock; size_t qlen; int qcmd[ASYNC_QLEN]; int qsubcmd[ASYNC_QLEN]; int read_latency; int last_backend; } async; }; static int _roar_vs_find_first_prim(roar_vs_t * vss); static int _send_async_req(roar_vs_t * vss, int cmd, int subcmd, int stream, int * error) { struct roar_message mes; uint16_t * data = (uint16_t *) mes.data; if ( !vss->async.level ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( vss->async.lock ) { _seterr(ROAR_ERROR_BUSY); return -1; } if ( vss->async.qlen == ASYNC_QLEN ) { _seterr(ROAR_ERROR_NOSPC); return -1; } memset(&mes, 0, sizeof(mes)); mes.cmd = cmd; mes.stream = stream; mes.pos = 0; if ( cmd == ROAR_CMD_GET_STREAM_PARA && subcmd == ROAR_STREAM_PARA_INFO ) { mes.datalen = 4; data[0] = ROAR_HOST2NET16(0); // Version and reserved data[1] = ROAR_HOST2NET16(ROAR_STREAM_PARA_INFO); // stream } else if ( cmd == ROAR_CMD_GET_STREAM ) { mes.datalen = 1; mes.data[0] = mes.stream; } else { _seterr(ROAR_ERROR_NOSYS); return -1; } if ( roar_send_message(vss->con, &mes, NULL) == -1 ) { _seterrre(); return -1; } vss->async.qcmd[vss->async.qlen] = cmd; vss->async.qsubcmd[vss->async.qlen] = subcmd; vss->async.qlen++; vss->async.read_latency = 0; return 0; } static int _handle_async_req(roar_vs_t * vss, int * error) { struct roar_message mes; char * data = NULL; uint16_t * ud16 = (uint16_t *) mes.data; ssize_t offset; int cmd, subcmd; size_t i; if ( roar_recv_message(vss->con, &mes, &data) == -1 ) { _seterrre(); } cmd = vss->async.qcmd[0]; subcmd = vss->async.qsubcmd[0]; vss->async.qlen--; for (i = 1; i < ASYNC_QLEN; i++) { vss->async.qcmd[i-1] = vss->async.qcmd[i]; vss->async.qsubcmd[i-1] = vss->async.qsubcmd[i]; } //printf("mes.cmd=%i, cmd=%i, subcmd=%i\n", (int)mes.cmd, cmd, subcmd); if ( mes.cmd == ROAR_CMD_OK ) { switch (cmd) { case ROAR_CMD_GET_STREAM_PARA: if ( subcmd == ROAR_STREAM_PARA_INFO ) { if ( mes.datalen >= 16 ) { for (i = 0; i < mes.datalen/2; i++) { ud16[i] = ROAR_HOST2NET16(ud16[i]); } if ( ud16[0] == 0 || ud16[1] == 1 ) { offset = ud16[7]; offset *= 1000; offset *= vss->info.rate; offset /= 1000000; vss->latmes.last_offset = offset; } } } else { ROAR_WARN("_handle_async_req(vss=%p, error=%p): Got unexpected reply for command GET_STREAM_PARA, subcommand %i", vss, error, subcmd); } break; case ROAR_CMD_GET_STREAM: if ( roar_clock_gettime(&(vss->latmes.last_time), LOCAL_CLOCK) == -1 ) { vss->latmes.last_pos = -1; } else { vss->latmes.last_pos = mes.pos; } //printf("vss->latmes.last_pos=%li, mes.pos=%li\n", (long int)vss->latmes.last_pos, (long int)mes.pos); break; default: ROAR_WARN("_handle_async_req(vss=%p, error=%p): Got unexpected reply for command %i", vss, error, cmd); _seterr(ROAR_ERROR_NOSYS); break; } } if ( data != NULL ) roar_mm_free(data); return 0; } static inline int _handle_async(roar_vs_t * vss, int * error) { while (vss->async.qlen) { if ( _handle_async_req(vss, error) == -1 ) { return -1; } } return 0; } static void _check_async(roar_vs_t * vss) { struct roar_vio_select vios; struct roar_vio_selecttv tv = {0, 0}; if ( !vss->async.qlen ) return; ROAR_VIO_SELECT_SETVIO(&vios, roar_get_connection_vio2(vss->con), ROAR_VIO_SELECT_READ); if ( roar_vio_select(&vios, 1, &tv, NULL) < 1 ) return; if ( !(vios.eventsa & ROAR_VIO_SELECT_READ) ) return; _handle_async_req(vss, NULL); } const char * roar_vs_strerr(int error) { const char * ret = roar_error2str(error); if ( ret == NULL ) return "(unknown)"; return ret; } static roar_vs_t * roar_vs_init(int * error) { roar_vs_t * vss = roar_mm_malloc(sizeof(roar_vs_t)); if ( vss == NULL ) { _seterrse(); return NULL; } memset(vss, 0, sizeof(roar_vs_t)); vss->vio_ptr = &(vss->vio); vss->mixerid = -1; vss->first_primid = -1; #ifdef _HAVE_SOCKOPT vss->latc.target = -2.; // must be less than latc.minlag! vss->latc.window = -1.; vss->latc.minlag = -1.; vss->latc.p = 0.005; #endif vss->latmes.last_pos = -1; vss->async.last_backend = ROAR_VS_BACKEND_NONE; return vss; } roar_vs_t * roar_vs_new_from_con(struct roar_connection * con, int * error) { roar_vs_t * vss = roar_vs_init(error); if ( vss == NULL ) return NULL; vss->con = con; return vss; } roar_vs_t * roar_vs_new(const char * server, const char * name, int * error) { roar_vs_t * vss = roar_vs_init(error); int ret; if ( vss == NULL ) return NULL; vss->con = &(vss->con_store); _initerr(); ret = roar_simple_connect(vss->con, server, name); if ( ret == -1 ) { roar_vs_close(vss, ROAR_VS_TRUE, NULL); _seterrre(); return NULL; } return vss; } int roar_vs_stream(roar_vs_t * vss, const struct roar_audio_info * info, int dir, int * error) { struct roar_stream_info sinfo; int ret; _ckvss(-1); if ( vss->flags & FLAG_STREAM ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( dir == ROAR_DIR_FILTER ) vss->flags |= FLAG_DEF_PAUSE; _initerr(); if ( info != &(vss->info) ) memcpy(&(vss->info), info, sizeof(struct roar_audio_info)); ret = roar_vio_simple_new_stream_obj(&(vss->vio), vss->con, &(vss->stream), info->rate, info->channels, info->bits, info->codec, dir, vss->mixerid ); if ( roar_vio_open_re(&(vss->vio_re), &(vss->vio)) != -1 ) { vss->flags |= FLAG_VIO_RE; vss->vio_ptr = &(vss->vio_re); } if ( ret == -1 ) { _seterrre(); return -1; } if ( vss->mixerid != -1 ) { if ( roar_stream_get_info(vss->con, &(vss->stream), &sinfo) != -1 ) { vss->mixerid = sinfo.mixer; } } if ( vss->mixerid != -1 ) _roar_vs_find_first_prim(vss); vss->flags |= FLAG_STREAM; switch (dir) { case ROAR_DIR_PLAY: vss->flags |= FLAG_DIR_OUT; break; } return 0; } roar_vs_t * roar_vs_new_simple(const char * server, const char * name, int rate, int channels, int codec, int bits, int dir, int * error) { roar_vs_t * vss = roar_vs_new(server, name, error); int ret; if (vss == NULL) return NULL; memset(&(vss->info), 0, sizeof(vss->info)); vss->info.rate = rate; vss->info.channels = channels; vss->info.codec = codec; vss->info.bits = bits; ret = roar_vs_stream(vss, &(vss->info), dir, error); if (ret == -1) { roar_vs_close(vss, ROAR_VS_TRUE, NULL); return NULL; } return vss; } int roar_vs_file(roar_vs_t * vss, struct roar_vio_calls * vio, int closefile, int * error) { _ckvss(-1); if ( vio == NULL || (closefile != ROAR_VS_TRUE && closefile != ROAR_VS_FALSE)) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( vss->file != NULL ) { _seterr(ROAR_ERROR_INVAL); return -1; } vss->file = vio; if ( closefile == ROAR_VS_TRUE ) vss->flags |= FLAG_CLOSEFILE; return 0; } int roar_vs_file_simple(roar_vs_t * vss, const char * filename, int * error) { struct roar_vio_defaults def; struct roar_vio_calls * file; char buf[64]; ssize_t ret; int dir = O_RDONLY; int codec = -1; const char * content_type; _ckvss(-1); if ( vss->file != NULL ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( vss->flags & FLAG_STREAM ) { switch (vss->flags & (FLAG_DIR_IN|FLAG_DIR_OUT)) { case FLAG_DIR_IN: dir = O_WRONLY; break; case FLAG_DIR_OUT: dir = O_RDONLY; break; case FLAG_DIR_IN|FLAG_DIR_OUT: dir = O_RDWR; break; default: _seterr(ROAR_ERROR_INVAL); return -1; } } file = &(vss->file_store); _initerr(); if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, dir, 0644) == -1 ) { _seterrre(); return -1; } if ( roar_vio_open_dstr(file, filename, &def, 1) == -1 ) { _seterrre(); return -1; } if ( !(vss->flags & FLAG_STREAM) ) { if ( roar_vio_ctl(file, ROAR_VIO_CTL_GET_MIMETYPE, &content_type) != -1 ) { codec = roar_mime2codec(content_type); } if ( codec == -1 ) { ret = roar_vio_read(file, buf, sizeof(buf)); codec = roar_file_codecdetect(buf, ret); if ( codec == -1 ) { roar_vio_close(file); _seterr(ROAR_ERROR_INVAL); // Other value? return -1; } if ( roar_vio_lseek(file, 0, SEEK_SET) != 0 ) { roar_vio_close(file); _seterrre(); return -1; } } memset(&(vss->info), 0, sizeof(vss->info)); vss->info.rate = ROAR_RATE_DEFAULT; vss->info.channels = ROAR_CHANNELS_DEFAULT; vss->info.codec = codec; vss->info.bits = ROAR_BITS_DEFAULT; ret = roar_vs_stream(vss, &(vss->info), ROAR_DIR_PLAY, error); if ( ret == -1 ) { roar_vio_close(file); return -1; } } if ( roar_vs_file(vss, file, ROAR_VS_TRUE, error) == -1 ) { roar_vio_close(file); return -1; } return 0; } roar_vs_t * roar_vs_new_from_file(const char * server, const char * name, const char * filename, int * error) { roar_vs_t * vss = roar_vs_new(server, name, error); if ( vss == NULL ) return NULL; if ( roar_vs_file_simple(vss, filename, error) != 0 ) { roar_vs_close(vss, ROAR_VS_TRUE, NULL); return NULL; } return vss; } int roar_vs_buffer(roar_vs_t * vss, size_t buffer, int * error) { _ckvss(-1); if ( vss->flags & FLAG_BUFFERED ) return -1; if ( roar_buffer_ring_new(&(vss->readring), buffer, 0) == -1 ) { _seterrre(); return -1; } if ( roar_buffer_ring_new(&(vss->writering), buffer, 0) == -1 ) { _seterrre(); roar_buffer_free(vss->readring); vss->readring = NULL; return -1; } vss->flags |= FLAG_BUFFERED; return 0; } int roar_vs_close(roar_vs_t * vss, int killit, int * error) { if ( killit != ROAR_VS_TRUE && killit != ROAR_VS_FALSE ) { _seterr(ROAR_ERROR_INVAL); return -1; } _ckvss(-1); _ckasync(-1); if ( vss->readbuffer != NULL ) roar_buffer_free(vss->readbuffer); if ( vss->writebuffer != NULL ) roar_buffer_free(vss->writebuffer); if ( vss->readring != NULL ) roar_buffer_free(vss->readring); if ( vss->writering != NULL ) roar_buffer_free(vss->writering); if ( vss->file != NULL && vss->flags & FLAG_CLOSEFILE ) roar_vio_close(vss->file); if ( vss->flags & FLAG_STREAM ) { if ( killit == ROAR_VS_TRUE ) { roar_kick(vss->con, ROAR_OT_STREAM, roar_stream_get_id(&(vss->stream))); } roar_vio_close(vss->vio_ptr); } if ( vss->con == &(vss->con_store) ) { roar_disconnect(vss->con); } roar_mm_free(vss); return 0; } static ssize_t roar_vs_write_direct(roar_vs_t * vss, const void * buf, size_t len, int * error) { ssize_t ret = roar_vio_write(vss->vio_ptr, (void*)buf, len); if ( ret == -1 ) { #ifdef EAGAIN if ( roar_error == ROAR_ERROR_AGAIN ) return 0; #endif _seterrre(); } else { if ( !(vss->flags & FLAG_BUFFERED) ) { //printf("A: vss->writec=%zu, ret=%zi\n", vss->writec, ret); vss->writec += ret; } } //printf("B: vss->writec=%zu, ret=%zi\n", vss->writec, ret); return ret; } ssize_t roar_vs_write(roar_vs_t * vss, const void * buf, size_t len, int * error) { ssize_t ret; size_t writelen; _ckvss(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } _initerr(); if ( vss->flags & FLAG_BUFFERED ) { writelen = len; if ( roar_buffer_ring_write(vss->writering, (void*)buf, &writelen) == -1 ) { _seterrre(); return -1; } ret = writelen; vss->writec += ret; } else { ret = roar_vs_write_direct(vss, buf, len, error); } return ret; } ssize_t roar_vs_read (roar_vs_t * vss, void * buf, size_t len, int * error) { ssize_t ret; _ckvss(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } _initerr(); ret = roar_vio_read(vss->vio_ptr, buf, len); if ( ret == -1 ) { _seterrre(); } else { vss->readc += ret; } return ret; } int roar_vs_sync (roar_vs_t * vss, int wait, int * error) { struct roar_event waits, triggered; _ckvss(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( wait != ROAR_VS_NOWAIT && wait != ROAR_VS_WAIT ) { _seterr(ROAR_ERROR_INVAL); return -1; } _initerr(); if ( roar_vio_sync(vss->vio_ptr) == -1 ) { _seterrre(); return -1; } if ( wait == ROAR_VS_WAIT ) { _ckasync(-1); memset(&waits, 0, sizeof(waits)); waits.event = ROAR_OE_STREAM_XRUN; waits.emitter = -1; waits.target = roar_stream_get_id(&(vss->stream)); waits.target_type = ROAR_OT_STREAM; if ( roar_wait(vss->con, &triggered, &waits, 1) == -1 ) { _seterrre(); return -1; } } return 0; } int roar_vs_blocking (roar_vs_t * vss, int val, int * error) { int old = -1; _ckvss(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } old = vss->flags & FLAG_NONBLOCK ? ROAR_VS_FALSE : ROAR_VS_TRUE; _initerr(); switch (val) { case ROAR_VS_TRUE: if ( roar_vio_nonblock(vss->vio_ptr, ROAR_SOCKET_BLOCK) == -1 ) { _seterrre(); return -1; } vss->flags |= FLAG_NONBLOCK; vss->flags -= FLAG_NONBLOCK; return old; break; case ROAR_VS_FALSE: if ( roar_vio_nonblock(vss->vio_ptr, ROAR_SOCKET_NONBLOCK) == -1 ) { _seterrre(); return -1; } vss->flags |= FLAG_NONBLOCK; return old; break; case ROAR_VS_TOGGLE: if ( old == ROAR_VS_TRUE ) { return roar_vs_blocking(vss, ROAR_VS_FALSE, error); } else { return roar_vs_blocking(vss, ROAR_VS_TRUE, error); } break; case ROAR_VS_ASK: return old; break; } _seterr(ROAR_ERROR_INVAL); return -1; } static int _roar_vs_find_first_prim(roar_vs_t * vss) { struct roar_stream stream; struct roar_stream_info info; int id[ROAR_STREAMS_MAX]; int num; int i; int * error = NULL; // needed for _ckasync() macro _ckasync(-1); if ( vss->first_primid != -1 ) return vss->first_primid; if ( vss->mixerid == -1 ) return -1; if ( (num = roar_list_streams(vss->con, id, ROAR_STREAMS_MAX)) == -1 ) { return -1; } for (i = 0; i < num; i++) { if ( roar_get_stream(vss->con, &stream, id[i]) == -1 ) continue; if ( stream.dir != ROAR_DIR_OUTPUT ) continue; if ( roar_stream_get_info(vss->con, &stream, &info) == -1 ) continue; if ( info.mixer == vss->mixerid ) { vss->first_primid = id[i]; return id[i]; } } return -1; } ssize_t roar_vs_position(roar_vs_t * vss, int backend, int * error) { struct roar_stream stream; struct roar_stream out_stream; struct roar_stream_info out_info; size_t offset = 0; _ckvss(-1); _ckasync(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } _initerr(); if ( roar_get_stream(vss->con, &stream, roar_stream_get_id(&(vss->stream))) == -1 ) { _seterrre(); return -1; } if ( backend == ROAR_VS_BACKEND_DEFAULT ) { backend = ROAR_VS_BACKEND_FIRST; } switch (backend) { case ROAR_VS_BACKEND_NONE: // return stream.pos; // do nothing. break; case ROAR_VS_BACKEND_FIRST: if ( vss->first_primid == -1 ) { _seterr(ROAR_ERROR_UNKNOWN); return -1; } backend = vss->first_primid; break; default: if ( backend < 0 ) { _seterr(ROAR_ERROR_INVAL); return -1; } break; } vss->async.last_backend = backend; if ( backend >= 0 ) { roar_stream_new_by_id(&out_stream, backend); if ( roar_stream_get_info(vss->con, &out_stream, &out_info) == -1 ) { _seterrre(); return -1; } offset = out_info.delay * vss->info.rate; offset /= 1000000; } if ( roar_clock_gettime(&(vss->latmes.last_time), LOCAL_CLOCK) == -1 ) { vss->latmes.last_pos = -1; } else { vss->latmes.last_pos = stream.pos; vss->latmes.last_offset = offset; } return stream.pos + offset; } #ifdef _HAVE_SOCKOPT static void roar_vs_latency_managed(roar_vs_t * vss, roar_mus_t lat) { struct roar_vio_sysio_sockopt sockopt; float tmp = ((float)lat/1000.0) - vss->latc.target; int val; tmp *= vss->latc.p; sockopt.level = SOL_SOCKET; sockopt.optname = SO_SNDBUF; sockopt.optval = &val; sockopt.optlen = sizeof(val); if ( roar_vio_ctl(vss->vio_ptr, ROAR_VIO_CTL_GET_SYSIO_SOCKOPT, &sockopt) == -1 ) return; val /= 2; tmp = 1.0 - tmp; val = (float)val*tmp; sockopt.optlen = sizeof(val); if ( roar_vio_ctl(vss->vio_ptr, ROAR_VIO_CTL_SET_SYSIO_SOCKOPT, &sockopt) == -1 ) return; } #endif roar_mus_t roar_vs_latency(roar_vs_t * vss, int backend, int wait, int * error) { ssize_t pos; ssize_t bps; // byte per sample size_t lioc; // local IO (byte) counter size_t lpos; // local position signed long long int lag; struct roar_time rt; _initerr(); _ckvss(0); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return 0; } _check_async(vss); if ( wait == ROAR_VS_WAIT ) { _ckasync(0); pos = roar_vs_position(vss, backend, error); if (pos == -1) { _seterrre(); return 0; } if ( vss->writec == 0 ) { lioc = vss->readc; } else { //printf("writec=%zu\n", vss->writec); lioc = vss->writec; } bps = roar_info2samplesize(&(vss->info)); if ( bps == -1 ) { _seterrre(); return 0; } lpos = (lioc*8) / bps; lag = (signed long long int)lpos - (signed long long int)pos; lag /= vss->info.channels; // we now have the lag in frames // return value are mus // so we need to multiply with 1s/mus and // multiply by 1/rate lag *= 1000000; // 1s/mus lag /= vss->info.rate; #ifdef _HAVE_SOCKOPT if (vss->latc.target > vss->latc.minlag) { roar_vs_latency_managed(vss, lag); } #endif vss->async.read_latency = 1; if ( lag == 0 ) { _seterr(ROAR_ERROR_NONE); } return lag; } else if ( wait == ROAR_VS_NOWAIT ) { vss->async.read_latency = 1; if ( vss->latmes.last_pos == -1 ) { _seterr(ROAR_ERROR_NODATA); return 0; } if ( vss->writec == 0 ) { lioc = vss->readc; } else { //printf("writec=%zu\n", vss->writec); lioc = vss->writec; } bps = roar_info2samplesize(&(vss->info)); if ( bps == -1 ) { _seterrre(); return 0; } lpos = (lioc*8) / bps; //printf("pos=%zi, lpos=%zi, bps=%zi, diff[lpos-pos]=%zi\n", pos, lpos, bps, (lpos - pos)); lag = (signed long long int)lpos - (signed long long int)(vss->latmes.last_pos + vss->latmes.last_offset); lag /= vss->info.channels; // we now have the lag in frames // return value are mus // so we need to multiply with 1s/mus and // multiply by 1/rate lag *= 1000000; // 1s/mus lag /= vss->info.rate; _initerr(); if ( roar_clock_gettime(&rt, LOCAL_CLOCK) == -1 ) { _seterrre(); return 0; } // printf("%lli, %lli\n", (rt.t_sec - vss->latmes.last_time.t_sec ), (rt.t_ssec/2 - vss->latmes.last_time.t_ssec/2)/ 18446744073710LL); // printf("%lli, %llu\n", rt.t_sec, rt.t_ssec); lag -= (rt.t_sec - vss->latmes.last_time.t_sec ) * 1000000LL; lag -= ((int64_t)(rt.t_ssec/2) - (int64_t)(vss->latmes.last_time.t_ssec/2)) / 9223372036855LL; if ( lag == 0 ) { _seterr(ROAR_ERROR_NONE); } return lag; } else if ( wait == ROAR_VS_ASYNC ) { if ( _send_async_req(vss, ROAR_CMD_GET_STREAM, -1, roar_stream_get_id(&(vss->stream)), error) == -1 ) return 0; switch (backend) { case ROAR_VS_BACKEND_NONE: break; case ROAR_VS_BACKEND_FIRST: if ( vss->first_primid == -1 ) { _seterr(ROAR_ERROR_UNKNOWN); return 0; } backend = vss->first_primid; break; default: if ( backend < 0 ) { _seterr(ROAR_ERROR_INVAL); return -1; } break; } vss->async.last_backend = backend; if ( backend >= 0 ) if ( _send_async_req(vss, ROAR_CMD_GET_STREAM_PARA, ROAR_STREAM_PARA_INFO, backend, error) == -1 ) return 0; _seterr(ROAR_ERROR_NODATA); return 0; } _seterr(ROAR_ERROR_INVAL); return 0; } static int roar_vs_flag(roar_vs_t * vss, int flag, int val, int * error) { struct roar_stream_info info; int old = -1; _ckvss(-1); _ckasync(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( val != ROAR_VS_ASK ) old = roar_vs_flag(vss, flag, ROAR_VS_ASK, error); _initerr(); switch (val) { case ROAR_VS_TRUE: case ROAR_VS_FALSE: if ( roar_stream_set_flags(vss->con, &(vss->stream), flag, val == ROAR_VS_TRUE ? ROAR_SET_FLAG : ROAR_RESET_FLAG) == -1 ) { _seterrre(); return -1; } return old; break; case ROAR_VS_TOGGLE: return roar_vs_flag(vss, flag, old == ROAR_VS_TRUE ? ROAR_VS_FALSE : ROAR_VS_TRUE, error); break; case ROAR_VS_ASK: if ( roar_stream_get_info(vss->con, &(vss->stream), &info) == -1 ) { _seterrre(); return -1; } return info.flags & flag ? ROAR_VS_TRUE : ROAR_VS_FALSE; break; } _seterr(ROAR_ERROR_INVAL); return -1; } int roar_vs_pause(roar_vs_t * vss, int val, int * error) { return roar_vs_flag(vss, ROAR_FLAG_PAUSE, val, error); } int roar_vs_mute (roar_vs_t * vss, int val, int * error) { return roar_vs_flag(vss, ROAR_FLAG_MUTE, val, error); } static int roar_vs_volume (roar_vs_t * vss, float * c, size_t channels, int * error) { struct roar_mixer_settings mixer; size_t i; register float s, max_s = -100.0, scale = 65535.0; int oldchannels; int mode = ROAR_SET_VOL_ALL; _ckvss(-1); _ckasync(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( channels > ROAR_MAX_CHANNELS ) { _seterr(ROAR_ERROR_INVAL); return -1; } _initerr(); if ( roar_get_vol(vss->con, roar_stream_get_id(&(vss->stream)), &mixer, &oldchannels) == -1 ) { _seterrre(); return -1; } if ( vss->flags & FLAG_FREE_VOL ) { for (i = 0; i < channels; i++) { if ( c[i] > max_s ) { max_s = c[i]; } else if ( c[i] < -0.01 ) { _seterr(ROAR_ERROR_RANGE); return -1; } } if ( max_s > 1.00 ) { scale = 65535.0 / max_s; } } for (i = 0; i < channels; i++) { if ( vss->flags & FLAG_FREE_VOL ) { s = c[i] * scale; if ( s < 0.0 ) s = 0.0; } else { s = c[i] * 65535.0; if ( s > 66190.0 || s < -655.0 ) { _seterr(ROAR_ERROR_RANGE); return -1; } else if ( s > 65535.0 ) { s = 65535.0; } else if ( s < 0.0 ) { s = 0.0; } } mixer.mixer[i] = s; } if ( vss->flags & FLAG_FREE_VOL ) { mixer.scale = scale; } else { mixer.scale = 65535; } if ( channels != (size_t)oldchannels ) mode = ROAR_SET_VOL_UNMAPPED; if ( roar_set_vol(vss->con, roar_stream_get_id(&(vss->stream)), &mixer, channels, mode) == 0 ) return 0; if ( mode == ROAR_SET_VOL_ALL ) { _seterrre(); return -1; } if ( roar_conv_volume(&mixer, &mixer, oldchannels, channels) == -1 ) { _seterrre(); return -1; } channels = oldchannels; mode = ROAR_SET_VOL_ALL; if ( roar_set_vol(vss->con, roar_stream_get_id(&(vss->stream)), &mixer, channels, mode) == -1 ) { _seterrre(); return -1; } return 0; } int roar_vs_volume_mono (roar_vs_t * vss, float c, int * error) { return roar_vs_volume(vss, &c, 1, error); } int roar_vs_volume_stereo (roar_vs_t * vss, float l, float r, int * error) { float c[2] = {l, r}; return roar_vs_volume(vss, c, 2, error); } int roar_vs_volume_get (roar_vs_t * vss, float * l, float * r, int * error) { struct roar_mixer_settings mixer; int channels; if ( vss == NULL || l == NULL || r == NULL ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } _ckasync(-1); _initerr(); if ( roar_get_vol(vss->con, roar_stream_get_id(&(vss->stream)), &mixer, &channels) == -1 ) { _seterrre(); return -1; } if ( channels == 1 ) mixer.mixer[1] = mixer.mixer[0]; *l = mixer.mixer[0] / (float)mixer.scale; *r = mixer.mixer[1] / (float)mixer.scale; return 0; } int roar_vs_meta (roar_vs_t * vss, struct roar_keyval * kv, size_t len, int * error) { struct roar_meta meta; size_t i; int type; int ret = 0; _ckvss(-1); _ckasync(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } meta.type = ROAR_META_TYPE_NONE; meta.key[0] = 0; meta.value = NULL; _initerr(); if ( roar_stream_meta_set(vss->con, &(vss->stream), ROAR_META_MODE_CLEAR, &meta) == -1 ) { _seterrre(); ret = -1; } for (i = 0; i < len; i++) { type = roar_meta_inttype(kv[i].key); meta.type = type; meta.value = kv[i].value; if ( roar_stream_meta_set(vss->con, &(vss->stream), ROAR_META_MODE_ADD, &meta) == -1 ) { _seterrre(); ret = -1; } } meta.type = ROAR_META_TYPE_NONE; meta.key[0] = 0; meta.value = NULL; if ( roar_stream_meta_set(vss->con, &(vss->stream), ROAR_META_MODE_FINALIZE, &meta) == -1 ) { _seterrre(); ret = -1; } return ret; } int roar_vs_role (roar_vs_t * vss, int role, int * error) { _ckvss(-1); _ckasync(-1); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return -1; } _initerr(); if ( roar_stream_set_role(vss->con, &(vss->stream), role) == -1 ) { _seterrre(); return -1; } return 0; } int roar_vs_iterate (roar_vs_t * vss, int wait, int * error) { struct roar_vio_select vios[3]; struct roar_vio_selecttv rtv = {.sec = 0, .nsec = 1}; size_t len = 0; size_t i; ssize_t ret; int can_read = 0, can_write = 0; int can_flush_stream = 0, can_flush_file = 0; int is_eof = 0; void * data; size_t tmp; // TODO: fix error handling below. ROAR_DBG("roar_vs_iterate(vss=%p, wait=%i, error=%p) = ?", vss, wait, error); _ckvss(-1); if ( wait != ROAR_VS_WAIT && wait != ROAR_VS_NOWAIT ) { _seterr(ROAR_ERROR_INVAL); return -1; } ROAR_VIO_SELECT_SETVIO(&(vios[len]), vss->vio_ptr, ((vss->flags & FLAG_DIR_IN ? ROAR_VIO_SELECT_READ : 0) | (vss->flags & FLAG_DIR_OUT ? ROAR_VIO_SELECT_WRITE : 0))); vios[len].ud.vp = vss->vio_ptr; len++; ROAR_VIO_SELECT_SETVIO(&(vios[len]), roar_get_connection_vio2(vss->con), ROAR_VIO_SELECT_READ); vios[len].ud.vp = vss->con; len++; // TODO: FIXME: need to do two select()s so we can sleep more efficently and test for both directions. // for the moment we disable file direction and hope it will not block anyway... /* if ( vss->file != NULL ) { ROAR_VIO_SELECT_SETVIO(&(vios[len]), vss->file, ((vss->flags & FLAG_DIR_IN ? ROAR_VIO_SELECT_WRITE : 0) | (vss->flags & FLAG_DIR_OUT ? ROAR_VIO_SELECT_READ : 0))); vios[len].ud.vp = vss->file; len++; } */ ret = roar_vio_select(vios, len, (wait == ROAR_VS_NOWAIT ? &rtv : NULL), NULL); // part 2 of above hack: // emulate read handle. if ( vss->file != NULL ) { vios[len].ud.vp = vss->file; vios[len].eventsa = ROAR_VIO_SELECT_WRITE|ROAR_VIO_SELECT_READ; len++; } // no error here nor EOF. if ( ret == 0 ) return 1; for (i = 0; i < len; i++) { if ( !vios[i].eventsa ) continue; if ( vios[i].ud.vp == vss->vio_ptr ) { if ( vios[i].eventsa & ROAR_VIO_SELECT_READ ) can_read++; if ( vios[i].eventsa & ROAR_VIO_SELECT_WRITE ) { can_write++; can_flush_stream = 1; } } else if ( vios[i].ud.vp == vss->con ) { if ( vss->async.qlen ) { _handle_async_req(vss, NULL); } else { roar_sync(vss->con); } } else if ( vss->file != NULL && vios[i].ud.vp == vss->file ) { if ( vios[i].eventsa & ROAR_VIO_SELECT_READ ) can_write++; if ( vios[i].eventsa & ROAR_VIO_SELECT_WRITE ) { can_read++; can_flush_file = 1; } } } if ( vss->flags & FLAG_BUFFERED ) { if ( roar_buffer_ring_avail(vss->readring, NULL, &tmp) != -1 ) if ( tmp > 0 ) can_read++; // no check here to just let the read return zero and we do EOF handling. /* if ( roar_buffer_ring_avail(vss->writering, &tmp, NULL) != -1 ) if ( tmp > 0 ) */ can_write++; } ROAR_DBG("roar_vs_iterate(vss=%p, wait=%i, error=%p): can_read=%i, can_write=%i", vss, wait, error, can_read, can_write); // TODO: FIXME: Need to correct error handling here! if ( can_flush_stream && vss->writebuffer != NULL ) { if ( roar_buffer_get_data(vss->writebuffer, &data) == -1 ) return -1; if ( roar_buffer_get_len(vss->writebuffer, &len) == -1 ) return -1; ret = roar_vs_write_direct(vss, data, len, error); if ( ret == -1 ) { return -1; } else if ( ret == (ssize_t)len ) { roar_buffer_free(vss->writebuffer); vss->writebuffer = NULL; } else { if ( roar_buffer_set_offset(vss->writebuffer, ret) == -1 ) return -1; } } if ( can_flush_file && vss->readbuffer != NULL ) { if ( roar_buffer_get_data(vss->readbuffer, &data) == -1 ) return -1; if ( roar_buffer_get_len(vss->readbuffer, &len) == -1 ) return -1; ret = roar_vio_write(vss->file, data, len); if ( ret == -1 ) { return -1; } else if ( ret == (ssize_t)len ) { roar_buffer_free(vss->readbuffer); vss->readbuffer = NULL; } else { if ( roar_buffer_set_offset(vss->readbuffer, ret) == -1 ) return -1; } } #define _READ_SIZE 1024 if ( can_read == 2 && vss->readbuffer == NULL ) { if ( roar_buffer_new_data(&(vss->readbuffer), (len = _READ_SIZE), &data) == -1 ) return -1; ret = roar_vs_read(vss, data, len, error); if ( ret == -1 ) { roar_buffer_free(vss->readbuffer); vss->readbuffer = NULL; return -1; } else if ( ret == 0 ) { is_eof = 1; roar_buffer_free(vss->readbuffer); vss->readbuffer = NULL; } else { len = ret; if ( roar_buffer_set_len(vss->readbuffer, len) == -1 ) return -1; if ( vss->flags & FLAG_BUFFERED ) { tmp = len; if ( roar_buffer_ring_write(vss->readring, data, &tmp) == -1 ) { ret = -1; } else { ret = tmp; } } else { ret = roar_vio_write(vss->file, data, len); } if ( ret == -1 ) { return -1; } else if ( ret == (ssize_t)len ) { roar_buffer_free(vss->readbuffer); vss->readbuffer = NULL; } else { if ( roar_buffer_set_offset(vss->readbuffer, ret) == -1 ) return -1; } } } if ( can_write == 2 && vss->writebuffer == NULL ) { if ( roar_buffer_new_data(&(vss->writebuffer), (len = _READ_SIZE), &data) == -1 ) return -1; if ( vss->flags & FLAG_BUFFERED ) { tmp = len; if ( roar_buffer_ring_read(vss->writering, data, &tmp) == -1 ) { ret = -1; } else { ret = tmp; } } else { ret = roar_vio_read(vss->file, data, len); } ROAR_DBG("roar_vs_iterate(vss=%p, wait=%i, error=%p): ret=%lli", vss, wait, error, (long long int)ret); if ( ret == -1 ) { ROAR_DBG("roar_vs_iterate(vss=%p, wait=%i, error=%p) = ?", vss, wait, error); roar_buffer_free(vss->writebuffer); vss->writebuffer = NULL; return -1; } else if ( ret == 0 ) { ROAR_DBG("roar_vs_iterate(vss=%p, wait=%i, error=%p) = ?", vss, wait, error); is_eof = 1; roar_buffer_free(vss->writebuffer); vss->writebuffer = NULL; } else { ROAR_DBG("roar_vs_iterate(vss=%p, wait=%i, error=%p) = ?", vss, wait, error); if ( (ssize_t)len != ret ) { len = ret; if ( roar_buffer_set_len(vss->writebuffer, len) == -1 ) return -1; } ROAR_DBG("roar_vs_iterate(vss=%p, wait=%i, error=%p) = ?", vss, wait, error); ret = roar_vs_write_direct(vss, data, len, error); if ( ret == -1 ) { return -1; } else if ( ret == (ssize_t)len ) { roar_buffer_free(vss->writebuffer); vss->writebuffer = NULL; } else { if ( roar_buffer_set_offset(vss->writebuffer, ret) == -1 ) return -1; } } } if ( vss->async.level == ROAR_VS_ASYNCLEVEL_AUTO && !vss->async.lock && vss->async.read_latency && !vss->async.qlen ) { _LIBROAR_IGNORE_RET(roar_vs_latency(vss, vss->async.last_backend < 0 ? ROAR_VS_BACKEND_NONE : vss->async.last_backend, ROAR_VS_ASYNC, NULL)); } return is_eof ? 0 : 2; } int roar_vs_run (roar_vs_t * vss, int * error) { int ret; _ckvss(-1); while ((ret = roar_vs_iterate(vss, ROAR_VS_WAIT, error)) > 0); ROAR_DBG("roar_vs_run(vss=%p, error=%p): ret=%i", vss, error, ret); if ( ret == 0 ) { // flush buffers: roar_vs_iterate(vss, ROAR_VS_WAIT, error); } if ( roar_vs_sync(vss, ROAR_VS_WAIT, error) == -1 ) return -1; return ret; } ssize_t roar_vs_get_avail_read(roar_vs_t * vss, int * error) { size_t len; _ckvss(-1); if ( !(vss->flags & FLAG_BUFFERED) ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( roar_buffer_ring_avail(vss->readring, &len, NULL) == -1 ) { _seterrre(); return -1; } return len; } ssize_t roar_vs_get_avail_write(roar_vs_t * vss, int * error) { size_t len; _ckvss(-1); if ( !(vss->flags & FLAG_BUFFERED) ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( roar_buffer_ring_avail(vss->writering, NULL, &len) == -1 ) { _seterrre(); return -1; } return len; } int roar_vs_reset_buffer(roar_vs_t * vss, int writering, int readring, int * error) { _ckvss(-1); if ( !(vss->flags & FLAG_BUFFERED) ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( writering != ROAR_VS_TRUE || writering != ROAR_VS_FALSE || readring != ROAR_VS_TRUE || readring != ROAR_VS_FALSE ) { _seterr(ROAR_ERROR_INVAL); return -1; } if ( writering ) { if ( roar_buffer_ring_reset(vss->writering) == -1 ) { _seterrre(); return -1; } } if ( readring ) { if ( roar_buffer_ring_reset(vss->readring) == -1 ) { _seterrre(); return -1; } } return 0; } int roar_vs_ctl (roar_vs_t * vss, roar_vs_ctlcmd cmd, void * argp, int * error) { _ckvss(-1); switch (cmd) { case ROAR_VS_CMD_NOOP: break; case ROAR_VS_CMD_SET_MIXER: vss->mixerid = *(int*)argp; break; case ROAR_VS_CMD_GET_MIXER: *(int*)argp = vss->mixerid; break; case ROAR_VS_CMD_SET_FIRST_PRIM: vss->first_primid = *(int*)argp; break; case ROAR_VS_CMD_GET_FIRST_PRIM: *(int*)argp = vss->first_primid; break; #ifdef _HAVE_SOCKOPT case ROAR_VS_CMD_SET_LATC_P: vss->latc.p = *(float*)argp; break; case ROAR_VS_CMD_GET_LATC_P: *(float*)argp = vss->latc.p; break; case ROAR_VS_CMD_SET_LATC_TARGET: vss->latc.target = *(float*)argp; break; case ROAR_VS_CMD_GET_LATC_TARGET: *(float*)argp = vss->latc.target; break; case ROAR_VS_CMD_SET_LATC_WINDOW: vss->latc.window = *(float*)argp; break; case ROAR_VS_CMD_GET_LATC_WINDOW: *(float*)argp = vss->latc.window; break; case ROAR_VS_CMD_SET_LATC_MINLAG: vss->latc.minlag = *(float*)argp; break; case ROAR_VS_CMD_GET_LATC_MINLAG: *(float*)argp = vss->latc.minlag; break; #endif case ROAR_VS_CMD_SET_FREE_VOLUME: switch (*(int*)argp) { case ROAR_VS_TRUE: vss->flags |= FLAG_FREE_VOL; break; case ROAR_VS_FALSE: vss->flags |= FLAG_FREE_VOL; vss->flags -= FLAG_FREE_VOL; break; case ROAR_VS_TOGGLE: if ( vss->flags & FLAG_FREE_VOL ) { vss->flags -= FLAG_FREE_VOL; } else { vss->flags |= FLAG_FREE_VOL; } break; default: _seterr(ROAR_ERROR_INVAL); return -1; break; } break; case ROAR_VS_CMD_GET_FREE_VOLUME: *(int*)argp = vss->flags & FLAG_FREE_VOL ? ROAR_VS_TRUE : ROAR_VS_FALSE; break; case ROAR_VS_CMD_SET_DEFAULT_PAUSED: switch (*(int*)argp) { case ROAR_VS_TRUE: vss->flags |= FLAG_DEF_PAUSE; break; case ROAR_VS_FALSE: vss->flags |= FLAG_DEF_PAUSE; vss->flags -= FLAG_DEF_PAUSE; break; case ROAR_VS_TOGGLE: if ( vss->flags & FLAG_DEF_PAUSE ) { vss->flags -= FLAG_DEF_PAUSE; } else { vss->flags |= FLAG_DEF_PAUSE; } break; default: _seterr(ROAR_ERROR_INVAL); return -1; break; } break; case ROAR_VS_CMD_GET_DEFAULT_PAUSED: *(int*)argp = vss->flags & FLAG_DEF_PAUSE ? ROAR_VS_TRUE : ROAR_VS_FALSE; break; case ROAR_VS_CMD_SET_ASYNC: vss->async.level = *(int*)argp; break; case ROAR_VS_CMD_GET_ASYNC: *(int*)argp = vss->async.level; break; case ROAR_VS_CMD_LOCK_ASYNC: _ckasync(-1); if ( argp == NULL ) { vss->async.lock++; } else { vss->async.lock -= *(int*)argp; } break; case ROAR_VS_CMD_UNLOCK_ASYNC: if ( argp == NULL ) { if ( !vss->async.lock ) { _seterr(ROAR_ERROR_LOSTSYNC); return -1; } else { vss->async.lock--; } } else { if ( vss->async.lock < (size_t)*(int*)argp ) { _seterr(ROAR_ERROR_LOSTSYNC); return -1; } else { vss->async.lock -= *(int*)argp; } } break; // use ifndef here so warnings of unhandled enum values will be shown in DEBUG mode. #ifndef DEBUG default: _seterr(ROAR_ERROR_BADRQC); return -1; break; #endif } return 0; } struct roar_connection * roar_vs_connection_obj(roar_vs_t * vss, int * error) { _ckvss(NULL); return vss->con; } struct roar_stream * roar_vs_stream_obj (roar_vs_t * vss, int * error) { _ckvss(NULL); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return NULL; } return &(vss->stream); } struct roar_vio_calls * roar_vs_vio_obj (roar_vs_t * vss, int * error) { _ckvss(NULL); if ( !(vss->flags & FLAG_STREAM) ) { _seterr(ROAR_ERROR_INVAL); return NULL; } return vss->vio_ptr; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroar/watchdog.c��������������������������������������������������������������0000644�0001750�0001750�00000013151�12264733554�016071� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//watchdog.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroar.h" #define _CONF_DEFAULT ROAR_WATCHDOG_CONF_STOPPABLE|ROAR_WATCHDOG_CONF_CLOCK_INTERNAL; static int _config = _CONF_DEFAULT; static int _triggered = 0; static int _running = 0; static int_least32_t _timeout = 10000; // 10 sec. static int (*_callback)(enum roar_watchdog_event event) = NULL; static pid_t _starter_pid = 0; #ifdef ROAR_HAVE_ALARM static void _on_sig_alarm (int signum) { (void)signum; signal(SIGALRM, _on_sig_alarm); alarm(_timeout/1000); roar_watchdog_tick(); } #endif static int __event_handler(enum roar_watchdog_event event) { int ret; if ( event == ROAR_WATCHDOG_DOUBLETIMEOUT ) { ROAR_ERR("Watchdog event: DoubleTimeOut. Bad. Terminating program."); // panic... roar_panic(ROAR_FATAL_ERROR_WATCHDOG, NULL); } else if ( event == ROAR_WATCHDOG_TIMEOUT ) { ROAR_ERR("Watchdog event: TimeOut. Cleaning Up."); } if ( _callback != NULL ) { if ( (_config & ROAR_WATCHDOG_CONF_EVENTS_ALSO_MINOR) || event == ROAR_WATCHDOG_TIMEOUT || event == ROAR_WATCHDOG_START || event == ROAR_WATCHDOG_STOP ) { ret = _callback(event); if ( ret == -1 && event == ROAR_WATCHDOG_TIMEOUT ) __event_handler(ROAR_WATCHDOG_DOUBLETIMEOUT); } } if ( event == ROAR_WATCHDOG_TIMEOUT ) { ROAR_ERR("Watchdog event: TimeOut. Terminating program."); roar_panic(ROAR_FATAL_ERROR_WATCHDOG, NULL); } return 0; } // start the watchdog. // timeout is in ms. int roar_watchdog_start(int config, int_least32_t timeout, int (*callback)(enum roar_watchdog_event event)) { int ret = -1; if ( config == ROAR_WATCHDOG_CONF_DEFAULTS ) { config = _CONF_DEFAULT; } else if ( config == ROAR_WATCHDOG_CONF_RESTART ) { config = _config; if ( timeout == -1 ) timeout = _timeout; if ( callback == NULL ) callback = _callback; } if ( timeout < 1 ) { roar_err_set(ROAR_ERROR_CAUSALITY); return -1; } if ( _running ) { if ( _config & ROAR_WATCHDOG_CONF_STOPPABLE ) { if ( roar_watchdog_stop() == -1 ) return -1; } else { roar_err_set(ROAR_ERROR_BUSY); return -1; } } if ( !(config & ROAR_WATCHDOG_CONF_CLOCK_EXTERNAL) ) { #ifdef ROAR_HAVE_ALARM if ( config & ROAR_WATCHDOG_CONF_CLOCK_ROUND_UP ) { if ( timeout % 1000 ) timeout += 1000; } timeout /= 1000; if ( timeout == 0 ) timeout = 1; timeout *= 1000; #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } _config = config; _timeout = timeout; _callback = callback; if ( config & ROAR_WATCHDOG_CONF_CLOCK_EXTERNAL ) { ret = __event_handler(ROAR_WATCHDOG_START); #ifdef ROAR_HAVE_ALARM } else { signal(SIGALRM, _on_sig_alarm); alarm(_timeout/1000); ret = 0; #endif } if ( ret == -1 ) return -1; _running = 1; _starter_pid = getpid(); return 0; } // Get timeout for watchdog. // This may be diffrent from the requested time. int_least32_t roar_watchdog_gettime(void) { if ( !_running ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } return _timeout; } // stop it, if stopping is enabled. int roar_watchdog_stop(void) { int ret; if ( !_running ) return 0; // test if we are allowed to stop the watchdog. // In addition always allow to stop it in childs. if ( !(_config & ROAR_WATCHDOG_CONF_STOPPABLE) && _starter_pid == getpid() ) { ROAR_WARN("roar_watchdog_stop(void): Software tries to stop watchdog but is not allowed to."); roar_err_set(ROAR_ERROR_PERM); return -1; } #ifdef ROAR_HAVE_ALARM if ( !(_config & ROAR_WATCHDOG_CONF_CLOCK_EXTERNAL) ) { alarm(0); _running = 0; } #endif ret = __event_handler(ROAR_WATCHDOG_STOP); if ( ret != -1 ) _running = 0; return ret; } // Trigger the watchdog to show that we are still alive. int roar_watchdog_trigger(void) { if ( !_running ) return 0; _triggered = 1; return __event_handler(ROAR_WATCHDOG_TRIGGER); } // Trigger the watchdog clock. This is only used if configured to run with external clock source. int roar_watchdog_tick(void) { int ret = 0; ROAR_DBG("roar_watchdog_tick(void) = ?"); if ( !_running ) return 0; if ( _triggered == 0 ) { _triggered = -1; ret = __event_handler(ROAR_WATCHDOG_TIMEOUT); } else if ( _triggered == -1 ) { ret = __event_handler(ROAR_WATCHDOG_DOUBLETIMEOUT); } else { _triggered = 0; } return ret; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroararts/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553174�015017� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroararts/Makefile������������������������������������������������������������0000644�0001750�0001750�00000001450�12072575523�016453� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc #TARGETS=libartsc$(SHARED_SUFFIX) libroarartsc$(SHARED_SUFFIX) TARGETS=libroarartsc$(SHARED_SUFFIX) OBJS=libartsc.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroarpulse CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(Wextra) $(LDPATH) -L../lib/ LIBS = $(LIBROAR) all: ${TARGETS} cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all #libartsc$(SHARED_SUFFIX): libroarartsc$(SHARED_SUFFIX) # cp libroarartsc$(SHARED_SUFFIX) libartsc$(SHARED_SUFFIX) libroarartsc$(SHARED_SUFFIX): ${OBJS} ${CC} ${LDFLAGS} $(SHARED) -Wl,-soname,libroarartsc$(SHARED_SUFFIX).$(COMMON_SOVERSION) -o libroarartsc$(SHARED_SUFFIX) ${OBJS} ${LIBS} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroararts/libartsc.c����������������������������������������������������������0000644�0001750�0001750�00000017716�12264733554�017001� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libartsc.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libarts*. They are mostly copyrighted by: * Stefan Westerfeld <stefan@space.twc.de> * * This file is part of libroararts a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <roaraudio.h> #include <kde/artsc/artsc.h> static struct roar_connection _libroarartsc_connection[1]; struct _libroarartsc_stream { roar_vs_t * vss; int block_size; int dir; }; int arts_init(void) { return roar_simple_connect(_libroarartsc_connection, NULL, "libroarartsc client"); } void arts_free(void) { roar_disconnect(_libroarartsc_connection); } /** * asks aRtsd to free the DSP device and return 1 if it was successful, * 0 if there were active non-suspendable modules */ int arts_suspend(void) { return roar_set_standby(_libroarartsc_connection, ROAR_STANDBY_ACTIVE) == 0 ? 1 : 0; } /** * asks aRtsd if the DSP device is free and return 1 if it is, * 0 if not */ int arts_suspended(void) { return roar_get_standby(_libroarartsc_connection) == ROAR_STANDBY_ACTIVE; } /** * converts an error code to a human readable error message * * @param errorcode the errorcode (from another arts function that failed) * @returns a text string with the error message */ const char *arts_error_text(int errorcode) { return roar_vs_strerr(errorcode); } static arts_stream_t _arts_stream(int rate, int bits, int channels, const char *name, int dir) { struct _libroarartsc_stream * s = roar_mm_malloc(sizeof(struct _libroarartsc_stream)); struct roar_stream * stream; struct roar_audio_info auinfo; struct roar_stream_info info; struct roar_keyval kv[1]; int err = ROAR_ERROR_NONE; if ( s == NULL ) return NULL; if ( (s->vss = roar_vs_new_from_con(_libroarartsc_connection, &err)) == NULL ) { roar_mm_free(s); return NULL; } memset(&auinfo, 0, sizeof(auinfo)); auinfo.rate = rate; auinfo.channels = channels; auinfo.bits = bits; auinfo.codec = ROAR_CODEC_DEFAULT; if ( roar_vs_stream(s->vss, &auinfo, dir, &err) == -1 ) { roar_vs_close(s->vss, ROAR_VS_TRUE, &err); roar_mm_free(s); return NULL; } s->dir = dir; stream = roar_vs_stream_obj(s->vss, &err); if ( roar_stream_get_info(_libroarartsc_connection, stream, &info) != -1 ) { s->block_size = info.block_size; } else { ROAR_WARN("_arts_stream(*): Can not get stream block size from server, assuming 1024 Byte."); s->block_size = 1024; } if ( name != NULL && *name ) { kv[0].key = "description"; kv[0].value = (char*)name; roar_vs_meta(s->vss, kv, 1, &err); } return (arts_stream_t) s; } /** * open a stream for playing * * @param rate the sampling rate (something like 44100) * @param bits how many bits each sample has (8 or 16) * @param channels how many channels, 1 is mono, 2 is stereo * @param name the name of the stream (these will be used so that the user can * assign streams to effects/mixer channels and similar) * * @return a stream */ arts_stream_t arts_play_stream(int rate, int bits, int channels, const char *name) { return _arts_stream(rate, bits, channels, name, ROAR_DIR_PLAY); } /** * open a stream for recording * * @param rate the sampling rate (something like 44100) * @param bits how many bits each sample has (8 or 16) * @param channels how many channels, 1 is mono, 2 is stereo * @param name the name of the stream (these will be used so that the user can * assign streams to effects/mixer channels and similar) * * @return a stream */ arts_stream_t arts_record_stream(int rate, int bits, int channels, const char *name) { return _arts_stream(rate, bits, channels, name, ROAR_DIR_RECORD); } /** * close a stream */ void arts_close_stream(arts_stream_t stream) { struct _libroarartsc_stream * s = (struct _libroarartsc_stream *) stream; if ( stream == NULL ) return; roar_vs_close(s->vss, ROAR_VS_TRUE, NULL); roar_mm_free(stream); } /** * read samples from stream * * @param stream a previously opened record stream * @param buffer a buffer with sample data * @param count the number of bytes contained in the buffer * * @returns number of read bytes on success or error code */ int arts_read(arts_stream_t stream, void *buffer, int count) { struct _libroarartsc_stream * s = (struct _libroarartsc_stream *) stream; if ( stream == NULL ) return -1; return roar_vs_read(s->vss, buffer, count, NULL); } /** * write samples to to stream * * @param stream a previously opened play stream * @param buffer a buffer with sample data * @param count the number of bytes contained in the buffer * * @returns number of written bytes on success or error code */ int arts_write(arts_stream_t stream, const void *buffer, int count) { struct _libroarartsc_stream * s = (struct _libroarartsc_stream *) stream; if ( !stream ) return -1; return roar_vs_write(s->vss, buffer, count, NULL); } /** * configure a parameter of a stream * * @param stream an opened record or play stream * @param parameter the parameter you want to modify * @param value the new value * * @returns the new value of the parameter (which may or may not be the value * you wanted to have), or an error code if something went wrong */ int arts_stream_set(arts_stream_t stream, arts_parameter_t param, int value) { struct _libroarartsc_stream * s = (struct _libroarartsc_stream *) stream; if ( stream == NULL ) return -1; if ( param == ARTS_P_BLOCKING ) { if ( roar_vs_blocking(s->vss, value ? ROAR_VS_TRUE : ROAR_VS_FALSE, NULL) == -1 ) return -1; return arts_stream_get(stream, param); } return arts_stream_get(stream, param); } /** * query a parameter of a stream * * @param stream an opened record or play stream * @param parameter the parameter you want to query * * @returns the value of the parameter, or an error code */ int arts_stream_get(arts_stream_t stream, arts_parameter_t param) { struct _libroarartsc_stream * s = (struct _libroarartsc_stream *) stream; struct roar_vio_select vios; struct roar_vio_selecttv rtv; int events; if ( stream == NULL ) return -1; if ( param == ARTS_P_PACKET_SIZE ) { return s->block_size; } else if ( param == ARTS_P_BUFFER_SPACE ) { rtv.sec = 0; rtv.nsec = 1000; events = s->dir == ROAR_DIR_PLAY ? ROAR_VIO_SELECT_WRITE : ROAR_VIO_SELECT_READ; ROAR_VIO_SELECT_SETVIO(&vios, roar_vs_vio_obj(s->vss, NULL), events); if ( roar_vio_select(&vios, 1, &rtv, NULL) == 1 ) return s->block_size; return 0; } else if ( param == ARTS_P_BUFFER_SIZE ) { return s->block_size*2; } else if ( param == ARTS_P_PACKET_COUNT ) { return 1; } else if ( param == ARTS_P_BLOCKING ) { return roar_vs_blocking(s->vss, ROAR_VS_ASK, NULL) == ROAR_VS_TRUE ? 1 : 0; } return -1; } //ll ��������������������������������������������������roaraudio-1.0beta11/libroardsp/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�014631� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/Makefile�������������������������������������������������������������0000644�0001750�0001750�00000002443�12072565214�016267� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroardsp SLIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) OBJS=libroardsp.o convert.o midside.o poly.o filter.o filterchain.o remove.o transcode.o vio_transcode.o rms.o fader.o mixer.o amp.o interleave.o channels.o resampler_poly3.o float.o dtmf.o OLDROAR=midi.o FILTER=filter_lowp.o filter_highp.o filter_amp.o filter_quantify.o filter_add.o filter_clip.o filter_downmix.o filter_dcblock.o filter_swap.o filter_agc.o filter_speex_prep.o filter_responsecurve.o filter_goertzel.o MIDI=synth.o CODECS=alaw.o mulaw.o TRANSCODERS=transcode_mualaw.o transcode_celt.o transcode_speex.o ALLOBJS=$(OBJS) $(FILTER) $(TRANSCODERS) $(OLDROAR) $(MIDI) $(CODECS) #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroardsp CFLAGS += $(DEBUG_g) $(Wall) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) -L../lib/ $(LDPATH) LIBS = $(LIBROARDSP_NS) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): $(ALLOBJS) ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(LIBROARDSP_V) -o $(SLIB) $(ALLOBJS) $(LIBS) $(ALIB): $(ALLOBJS) ${AR} cru $(ALIB) $(ALLOBJS) ${RANLIB} $(ALIB) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/alaw.c���������������������������������������������������������������0000644�0001750�0001750�00000160616�12264733554�015735� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//alaw.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* * In addition to the above copyright statement codec marked with * '-------- SUN --------' is under the following license as it is extracted * from SoX 12.17.9: * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #include "libroardsp.h" #ifdef ROAR_SUPPORT_ALAW static const int16_t _roardsp_alaw2pcm16[] = { /* -------- SUN -------- */ -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 /* -------- /SUN -------- */ }; #ifdef ROAR_SUPPORT_ALAW_RW static const int8_t _roardsp_pcm132alaw[] = { /* -------- SUN -------- */ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x73, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x4a, 0x4a, 0x4b, 0x4b, 0x48, 0x48, 0x49, 0x49, 0x4e, 0x4e, 0x4f, 0x4f, 0x4c, 0x4c, 0x4d, 0x4d, 0x42, 0x42, 0x43, 0x43, 0x40, 0x40, 0x41, 0x41, 0x46, 0x46, 0x47, 0x47, 0x44, 0x44, 0x45, 0x45, 0x5a, 0x5a, 0x5b, 0x5b, 0x58, 0x58, 0x59, 0x59, 0x5e, 0x5e, 0x5f, 0x5f, 0x5c, 0x5c, 0x5d, 0x5d, 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0x55, 0xd5, 0xd5, 0xd4, 0xd4, 0xd7, 0xd7, 0xd6, 0xd6, 0xd1, 0xd1, 0xd0, 0xd0, 0xd3, 0xd3, 0xd2, 0xd2, 0xdd, 0xdd, 0xdc, 0xdc, 0xdf, 0xdf, 0xde, 0xde, 0xd9, 0xd9, 0xd8, 0xd8, 0xdb, 0xdb, 0xda, 0xda, 0xc5, 0xc5, 0xc4, 0xc4, 0xc7, 0xc7, 0xc6, 0xc6, 0xc1, 0xc1, 0xc0, 0xc0, 0xc3, 0xc3, 0xc2, 0xc2, 0xcd, 0xcd, 0xcc, 0xcc, 0xcf, 0xcf, 0xce, 0xce, 0xc9, 0xc9, 0xc8, 0xc8, 0xcb, 0xcb, 0xca, 0xca, 0xf5, 0xf5, 0xf5, 0xf5, 0xf4, 0xf4, 0xf4, 0xf4, 0xf7, 0xf7, 0xf7, 0xf7, 0xf6, 0xf6, 0xf6, 0xf6, 0xf1, 0xf1, 0xf1, 0xf1, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, 0xf3, 0xf3, 0xf3, 0xf2, 0xf2, 0xf2, 0xf2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xf9, 0xf9, 0xf9, 0xf9, 0xf8, 0xf8, 0xf8, 0xf8, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa /* -------- /SUN -------- */ }; #endif #endif int roardsp_conv_alaw2pcm16 (int16_t * out, char * in, size_t len) { #ifdef ROAR_SUPPORT_ALAW unsigned char * inp = (unsigned char *) in; ssize_t i; for (i = len-1; i > -1; i--) { out[i] = _roardsp_alaw2pcm16[inp[i]]; } return 0; #else return -1; #endif } int roardsp_conv_pcm162alaw (char * out, int16_t * in, size_t len) { #ifdef ROAR_SUPPORT_ALAW_RW unsigned int i; for (i = 0; i < len; i++) { out[i] = _roardsp_pcm132alaw[(in[i] + 32768) >> 3]; } return 0; #else return -1; #endif } int roardsp_conv_autlaw2pcm32 (int32_t * out, int16_t * in, size_t len) { #ifdef ROAR_SUPPORT_ALAW uint16_t inp; register unsigned char alaw, extra; register int bits; uint32_t op; int i; for (i = len-1; i > -1; i--) { inp = ROAR_NET2HOST16(in[i]); alaw = (inp & 0xFF00) >> 8; extra = inp & 0x00FF; // printf("Balaw=%u\n", (unsigned)alaw); bits = (alaw & 0x70) >> 4; if ( bits == 0 ) bits = 1; op = (uint32_t)_roardsp_alaw2pcm16[(int)alaw] << 16; // out[i] |= extra << (11 + bits); out[i] = op; } return 0; #else return -1; #endif } int roardsp_conv_pcm322autlaw (int16_t * out, int32_t * in, size_t len) { #ifdef ROAR_SUPPORT_ALAW_RW register unsigned int i; register uint16_t upper, r; register unsigned char alaw; register int bits; for (i = 0; i < len; i++) { upper = (uint32_t)((in[i] & 0xFFFF0000L) >> 16); alaw = _roardsp_pcm132alaw[(upper + 32768) >> 3]; // printf("Aalaw=%u\n", (unsigned)alaw); bits = (alaw & 0x70) >> 4; if ( bits == 0 ) bits = 1; r = ((in[i] << (6 + bits)) & 0xFF000000) >> 24; r |= alaw << 8; out[i] = ROAR_HOST2NET16(r); } return 0; #else return -1; #endif } //ll ������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/amp.c����������������������������������������������������������������0000644�0001750�0001750�00000006017�12264733554�015560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//amp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roar_amp_pcm(void * output, int bits, void * input, size_t samples, int channels, struct roar_mixer_settings * set) { switch (bits) { case 8: return roar_amp_pcm_8bit (output, input, samples, channels, set); break; case 16: return roar_amp_pcm_16bit(output, input, samples, channels, set); break; case 32: return roar_amp_pcm_32bit(output, input, samples, channels, set); break; default: return -1; } } int roar_amp_pcm_8bit (int8_t * output, int8_t * input, size_t samples, int channels, struct roar_mixer_settings * set) { size_t i; register int s; if ( !(input && output) ) return -1; if (set->rpg_mul == set->rpg_div) { for (i = 0; i < samples; i++) { s = input[i]; s *= set->mixer[i % channels]; s /= set->scale; output[i] = s; } } else { for (i = 0; i < samples; i++) { s = input[i]; s *= (set->mixer[i % channels] * set->rpg_mul) / set->rpg_div; s /= set->scale; output[i] = s; } } return 0; } int roar_amp_pcm_16bit (int16_t * output, int16_t * input, size_t samples, int channels, struct roar_mixer_settings * set) { size_t i; register int s; if ( !(input && output) ) return -1; if (set->rpg_mul == set->rpg_div) { for (i = 0; i < samples; i++) { s = input[i]; s *= set->mixer[i % channels]; s /= set->scale; output[i] = s; } } else { for (i = 0; i < samples; i++) { s = input[i]; s *= (set->mixer[i % channels] * set->rpg_mul) / set->rpg_div; s /= set->scale; output[i] = s; } } return 0; } int roar_amp_pcm_32bit (int32_t * output, int32_t * input, size_t samples, int channels, struct roar_mixer_settings * set) { #ifdef ROAR_NATIVE_INT64 size_t i; ROAR_NATIVE_INT64 s; if ( !(input && output) ) return -1; if (set->rpg_mul == set->rpg_div) { for (i = 0; i < samples; i++) { s = input[i]; s *= set->mixer[i % channels]; s /= set->scale; output[i] = s; } } else { for (i = 0; i < samples; i++) { s = input[i]; s *= (set->mixer[i % channels] * set->rpg_mul) / set->rpg_div; s /= set->scale; output[i] = s; } } return 0; #else return -1; #endif } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/channels.c�����������������������������������������������������������0000644�0001750�0001750�00000034334�12264733555�016602� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//channels.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #include "roaraudio/units.h" static struct { int id; char * name; char * sn; } _g_chans[] = { // general: {ROARDSP_CHAN_NONE, "NONE", "NONE" }, // waveform: {ROARDSP_CHAN_FRONT_LEFT, "FRONT_LEFT", "FL" }, {ROARDSP_CHAN_FRONT_RIGHT, "FRONT_RIGHT", "FR" }, {ROARDSP_CHAN_SIDE_LEFT, "SIDE_LEFT", "SL" }, {ROARDSP_CHAN_SIDE_RIGHT, "SIDE_RIGHT", "SR" }, {ROARDSP_CHAN_BACK_LEFT, "BACK_LEFT", "BL" }, {ROARDSP_CHAN_BACK_RIGHT, "BACK_RIGHT", "BR" }, {ROARDSP_CHAN_FRONT_CENTER, "FRONT_CENTER", "FC" }, {ROARDSP_CHAN_SIDE_CENTER, "SIDE_CENTER", "SC" }, {ROARDSP_CHAN_BACK_CENTER, "BACK_CENTER", "BC" }, {ROARDSP_CHAN_LEFT, "LEFT", "L" }, // alias {ROARDSP_CHAN_RIGHT, "RIGHT", "R" }, // alias {ROARDSP_CHAN_CENTER, "CENTER", "C" }, // alias {ROARDSP_CHAN_MONO, "MONO", "M" }, // alias {ROARDSP_CHAN_MS_MID, "MS_MID", "MID" }, {ROARDSP_CHAN_MS_SIDE, "MS_SIDE", "SIDE" }, {ROARDSP_CHAN_LFE, "LFE", "LFE" }, // midi: {ROARDSP_CHAN_MIDI0, "MIDI0", NULL }, {ROARDSP_CHAN_MIDI1, "MIDI1", NULL }, {ROARDSP_CHAN_MIDI2, "MIDI2", NULL }, {ROARDSP_CHAN_MIDI3, "MIDI3", NULL }, {ROARDSP_CHAN_MIDI4, "MIDI4", NULL }, {ROARDSP_CHAN_MIDI5, "MIDI5", NULL }, {ROARDSP_CHAN_MIDI6, "MIDI6", NULL }, {ROARDSP_CHAN_MIDI7, "MIDI7", NULL }, {ROARDSP_CHAN_MIDI8, "MIDI8", NULL }, {ROARDSP_CHAN_MIDI9, "MIDI9", NULL }, {ROARDSP_CHAN_MIDI10, "MIDI10", NULL }, {ROARDSP_CHAN_MIDI11, "MIDI11", NULL }, {ROARDSP_CHAN_MIDI12, "MIDI12", NULL }, {ROARDSP_CHAN_MIDI13, "MIDI13", NULL }, {ROARDSP_CHAN_MIDI14, "MIDI14", NULL }, {ROARDSP_CHAN_MIDI15, "MIDI15", NULL }, {ROARDSP_CHAN_EOL, NULL, NULL} }; char * roardsp_chan2str (int chan) { int i; for (i = 0; _g_chans[i].id != ROARDSP_CHAN_EOL; i++) if ( _g_chans[i].id == chan ) return _g_chans[i].name; return NULL; } int roardsp_str2chan(char * str) { int i; for (i = 0; _g_chans[i].id != ROARDSP_CHAN_EOL; i++) if ( !strcasecmp(_g_chans[i].name, str) || (_g_chans[i].sn != NULL && !strcasecmp(_g_chans[i].sn, str)) ) return _g_chans[i].id; return -1; } int roardsp_chanlist2str(char * list, size_t len, char * str, size_t strlen) { size_t i; char * name; if ( list == NULL && len > 0 ) return -1; if ( (str == NULL || strlen == 0) && len > 0 ) return -1; if ( len == 0 ) { if ( str != NULL && strlen > 0 ) *str = 0; return 0; } *str = 0; for (i = 0; i < len; i++) { if ( i != 0 ) roar_mm_strlcat(str, ",", strlen); name = roardsp_chan2str(list[i]); if ( name == NULL ) { roar_mm_strlcat(str, "<<<INVALID>>>", strlen); } else { roar_mm_strlcat(str, name, strlen); } } return 0; } int roardsp_chanlist_init(char * list, int channels, int map) { int i; if ( channels == 0 ) return 0; if ( list == NULL ) return -1; if ( channels > ROAR_MAX_CHANNELS ) return -1; if ( map == ROARDSP_CHANLIST_MAP_MIDI ) { for (i = 0; i < channels; i++) { list[i] = i+ROARDSP_CHAN_MIDI0; } } // test for common maps: if ( channels == 1 ) { list[0] = ROARDSP_CHAN_MONO; return 0; } if ( channels == 2 ) { list[0] = ROARDSP_CHAN_LEFT; list[1] = ROARDSP_CHAN_RIGHT; return 0; } // test for specific maps: switch (map) { case ROARDSP_CHANLIST_MAP_ROARAUDIO: case ROARDSP_CHANLIST_MAP_FLAC: if ( map == ROARDSP_CHANLIST_MAP_FLAC && channels > 6 ) { // FLAC only has a fixed mapping for up to 6 channels. return -1; } switch (channels) { // FLAC or RoarAudio: case 3: list[0] = ROARDSP_CHAN_LEFT; list[1] = ROARDSP_CHAN_RIGHT; list[2] = ROARDSP_CHAN_CENTER; break; case 4: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_FRONT_RIGHT; list[2] = ROARDSP_CHAN_BACK_LEFT; list[3] = ROARDSP_CHAN_BACK_RIGHT; break; case 5: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_FRONT_RIGHT; list[2] = ROARDSP_CHAN_CENTER; list[3] = ROARDSP_CHAN_BACK_LEFT; list[4] = ROARDSP_CHAN_BACK_RIGHT; break; case 6: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_FRONT_RIGHT; list[2] = ROARDSP_CHAN_CENTER; list[3] = ROARDSP_CHAN_LFE; list[4] = ROARDSP_CHAN_BACK_LEFT; list[5] = ROARDSP_CHAN_BACK_RIGHT; break; // RoarAudio: case 7: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_FRONT_RIGHT; list[2] = ROARDSP_CHAN_CENTER; list[3] = ROARDSP_CHAN_LFE; list[4] = ROARDSP_CHAN_SIDE_LEFT; list[5] = ROARDSP_CHAN_SIDE_RIGHT; list[6] = ROARDSP_CHAN_BACK_CENTER; break; case 8: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_FRONT_RIGHT; list[2] = ROARDSP_CHAN_CENTER; list[3] = ROARDSP_CHAN_LFE; list[4] = ROARDSP_CHAN_SIDE_LEFT; list[5] = ROARDSP_CHAN_SIDE_RIGHT; list[6] = ROARDSP_CHAN_BACK_LEFT; list[7] = ROARDSP_CHAN_BACK_RIGHT; break; default: return -1; break; } break; case ROARDSP_CHANLIST_MAP_VORBIS: switch (channels) { case 3: list[0] = ROARDSP_CHAN_LEFT; list[1] = ROARDSP_CHAN_CENTER; list[2] = ROARDSP_CHAN_RIGHT; break; case 4: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_FRONT_RIGHT; list[2] = ROARDSP_CHAN_BACK_LEFT; list[3] = ROARDSP_CHAN_BACK_RIGHT; break; case 5: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_CENTER; list[2] = ROARDSP_CHAN_FRONT_RIGHT; list[3] = ROARDSP_CHAN_BACK_LEFT; list[4] = ROARDSP_CHAN_BACK_RIGHT; break; case 6: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_CENTER; list[2] = ROARDSP_CHAN_FRONT_RIGHT; list[3] = ROARDSP_CHAN_BACK_LEFT; list[4] = ROARDSP_CHAN_BACK_RIGHT; list[5] = ROARDSP_CHAN_LFE; break; case 7: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_CENTER; list[2] = ROARDSP_CHAN_FRONT_RIGHT; list[3] = ROARDSP_CHAN_SIDE_LEFT; list[4] = ROARDSP_CHAN_SIDE_RIGHT; list[5] = ROARDSP_CHAN_BACK_CENTER; list[6] = ROARDSP_CHAN_LFE; break; case 8: list[0] = ROARDSP_CHAN_FRONT_LEFT; list[1] = ROARDSP_CHAN_CENTER; list[2] = ROARDSP_CHAN_FRONT_RIGHT; list[3] = ROARDSP_CHAN_SIDE_LEFT; list[4] = ROARDSP_CHAN_SIDE_RIGHT; list[5] = ROARDSP_CHAN_BACK_LEFT; list[6] = ROARDSP_CHAN_BACK_RIGHT; list[7] = ROARDSP_CHAN_LFE; break; default: return -1; break; } break; case ROARDSP_CHANLIST_MAP_OSS: switch (channels) { case 8: list[7] = ROARDSP_CHAN_BACK_RIGHT; case 7: list[6] = ROARDSP_CHAN_BACK_LEFT; case 6: list[5] = ROARDSP_CHAN_SIDE_RIGHT; case 5: list[4] = ROARDSP_CHAN_SIDE_LEFT; case 4: list[3] = ROARDSP_CHAN_LFE; case 3: list[2] = ROARDSP_CHAN_CENTER; list[1] = ROARDSP_CHAN_RIGHT; list[0] = ROARDSP_CHAN_LEFT; break; default: return -1; break; } break; case ROARDSP_CHANLIST_MAP_ALSA: // we guess: L,R,BL,BR,C,LFE,SL,SR (really, just guessing, see ALSA plugin of libao) switch (channels) { case 8: list[7] = ROARDSP_CHAN_BACK_RIGHT; case 7: list[6] = ROARDSP_CHAN_BACK_LEFT; case 6: list[5] = ROARDSP_CHAN_LFE; case 5: list[4] = ROARDSP_CHAN_CENTER; case 4: list[3] = ROARDSP_CHAN_BACK_RIGHT; case 3: list[2] = ROARDSP_CHAN_BACK_LEFT; list[1] = ROARDSP_CHAN_RIGHT; list[0] = ROARDSP_CHAN_LEFT; break; default: return -1; break; } break; case ROARDSP_CHANLIST_MAP_RIFF_WAVE: // here we are again, guessing: L,R,C,LFE,BL,BR,CL,CR,BC,SL,SR // strange, C, LFE on 4 channel file? // return -1 to be sure.... switch (channels) { default: return -1; break; } break; default: return -1; break; } return 0; } int roardsp_chanmap_calc(struct roardsp_chanmap * map, int what, int err_on_none) { int a, b; if ( map == NULL ) return -1; switch (what) { case ROARDSP_CHANMAP_MAP: memset(map->map, (char)-1, sizeof(map->map)); for (a = 0; a < ROAR_MAX_CHANNELS; a++) { if ( map->in[a] == ROARDSP_CHAN_NONE ) continue; for (b = 0; b < ROAR_MAX_CHANNELS; b++) { if ( map->in[a] == map->out[b] ) { map->map[a] = b; break; } } if ( b == ROAR_MAX_CHANNELS ) { // src not found in dest if ( err_on_none ) return -1; map->map[a] = -1; } } break; case ROARDSP_CHANMAP_INVMAP: memset(map->map, (char)-1, sizeof(map->map)); for (a = 0; a < ROAR_MAX_CHANNELS; a++) { if ( map->out[a] == ROARDSP_CHAN_NONE ) continue; for (b = 0; b < ROAR_MAX_CHANNELS; b++) { if ( map->out[a] == map->in[b] ) { map->map[a] = b; break; } } if ( b == ROAR_MAX_CHANNELS ) { // src not found in dest if ( err_on_none ) return -1; map->map[a] = -1; } } break; case ROARDSP_CHANMAP_IN: case ROARDSP_CHANMAP_OUT: default: return -1; break; } return 0; } int roardsp_chanmap_mappcm8 (char * out, char * in, size_t len, size_t chans, struct roardsp_chanmap * map) { char buf[ROAR_MAX_CHANNELS]; size_t frame; size_t c; if ( len == 0 ) return 0; if ( out == NULL || in == NULL || map == NULL ) return -1; if ( chans > ROAR_MAX_CHANNELS ) return -1; if ( in == out ) { for (frame = 0; frame < len/(chans*_8BIT); frame++) { memset(buf, 0, sizeof(buf)); for (c = 0; c < chans; c++) { buf[(int)map->map[c]] = in[c]; } memcpy(out, buf, chans*_8BIT); in += chans; out += chans; } } else { memset(out, 0, len); // silance channels we do not use for (frame = 0; frame < len/(chans*_8BIT); frame++) { for (c = 0; c < chans; c++) { out[(int)map->map[c]] = in[c]; } in += chans; out += chans; } } return 0; } int roardsp_chanmap_mappcm16(int16_t * out, int16_t * in, size_t len, size_t chans, struct roardsp_chanmap * map) { int16_t buf[ROAR_MAX_CHANNELS]; size_t frame; size_t c; if ( len == 0 ) return 0; if ( out == NULL || in == NULL || map == NULL ) return -1; if ( chans > ROAR_MAX_CHANNELS ) return -1; if ( in == out ) { for (frame = 0; frame < len/(chans*_16BIT); frame++) { memset(buf, 0, sizeof(buf)); for (c = 0; c < chans; c++) { buf[(int)map->map[c]] = in[c]; } memcpy(out, buf, chans*_16BIT); in += chans; out += chans; } } else { memset(out, 0, len); // silance channels we do not use for (frame = 0; frame < len/(chans*_16BIT); frame++) { for (c = 0; c < chans; c++) { out[(int)map->map[c]] = in[c]; } in += chans; out += chans; } } return 0; } int roardsp_chanmap_mappcm24(void * out, void * in, size_t len, size_t chans, struct roardsp_chanmap * map) { return -1; } int roardsp_chanmap_mappcm32(int32_t * out, int32_t * in, size_t len, size_t chans, struct roardsp_chanmap * map) { int32_t buf[ROAR_MAX_CHANNELS]; size_t frame; size_t c; if ( len == 0 ) return 0; if ( out == NULL || in == NULL || map == NULL ) return -1; if ( chans > ROAR_MAX_CHANNELS ) return -1; if ( in == out ) { for (frame = 0; frame < len/(chans*_32BIT); frame++) { memset(buf, 0, sizeof(buf)); for (c = 0; c < chans; c++) { buf[(int)map->map[c]] = in[c]; } memcpy(out, buf, chans*_32BIT); in += chans; out += chans; } } else { memset(out, 0, len); // silance channels we do not use for (frame = 0; frame < len/(chans*_32BIT); frame++) { for (c = 0; c < chans; c++) { out[(int)map->map[c]] = in[c]; } in += chans; out += chans; } } return 0; } int roardsp_chanmap_mappcm (void * out, void * in, size_t len, size_t chans, struct roardsp_chanmap * map, int bits) { if ( len == 0 ) return 0; if ( out == NULL || in == NULL || map == NULL ) return -1; if ( chans > ROAR_MAX_CHANNELS ) return -1; #if 0 { int i; printf("---- BEGIN MAP ----\n"); for (i = 0; i < chans; i++) { printf("MAP: %i->%i\n", i, map[i]); } printf("---- END MAP ----\n"); } #endif switch (bits) { case 8: return roardsp_chanmap_mappcm8(out, in, len, chans, map); break; case 16: return roardsp_chanmap_mappcm16(out, in, len, chans, map); break; case 24: return roardsp_chanmap_mappcm24(out, in, len, chans, map); break; case 32: return roardsp_chanmap_mappcm32(out, in, len, chans, map); break; default: return -1; break; } } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/convert.c������������������������������������������������������������0000644�0001750�0001750�00000075217�12264733556�016475� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//convert.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroardsp.h" //#define free(p) {ROAR_WARN("free(%p) = ?", (p)); free((p)); ROAR_WARN("free(%p): OK", (p));} int roar_conv_bits (void * out, void * in, int samples, int from, int to) { int format; if ( from == to ) { if ( in == out ) return 0; memcpy(out, in, samples * from / 8); return 0; } format = ((from / 8) << 4) + (to / 8); switch (format) { case 0x12: return roar_conv_bits_8to16( out, in, samples); case 0x14: return roar_conv_bits_8to32( out, in, samples); case 0x21: return roar_conv_bits_16to8( out, in, samples); case 0x24: return roar_conv_bits_16to32(out, in, samples); case 0x34: return roar_conv_bits_24to32(out, in, samples); case 0x41: return roar_conv_bits_32to8( out, in, samples); case 0x42: return roar_conv_bits_32to16(out, in, samples); default: errno = ENOSYS; return -1; } return -1; } int roar_conv_bits_8to16 (void * out, void * in, int samples) { char * ip = (char *)in; int16_t * op = (int16_t*)out; int i; for (i = samples - 1; i >= 0; i--) op[i] = ip[i] << 8; return 0; } int roar_conv_bits_8to32 (void * out, void * in, int samples) { char * ip = (char *)in; int32_t * op = (int32_t*)out; int i; for (i = samples - 1; i >= 0; i--) op[i] = (int32_t) ip[i] << 24; return 0; } int roar_conv_bits_16to8 (void * out, void * in, int samples) { int16_t * ip = (int16_t*)in; char * op = (char *)out; int i; ROAR_DBG("roar_conv_bits_16to8(out=%p, in=%p, samples=%i) = ?", out, in, samples); for (i = 0; i < samples; i++) op[i] = ip[i] >> 8; return 0; } int roar_conv_bits_16to32 (void * out, void * in, int samples) { int16_t * ip = (int16_t*)in; int32_t * op = (int32_t*)out; int i; for (i = samples - 1; i >= 0; i--) op[i] = (int32_t) ip[i] << 16; return 0; } int roar_conv_bits_24to32 (void * out, void * in, int samples) { uint8_t * ip = (uint8_t*)in; int32_t * op = (int32_t*)out; int i; union { int32_t i; uint8_t c[4]; } t; ROAR_DBG("roar_conv_bits_24to32(out=%p, in=%p, samples=%i) = ?", out, in, samples); #if (BYTE_ORDER == BIG_ENDIAN) || (BYTE_ORDER == LITTLE_ENDIAN) t.i = 0; #else ROAR_DBG("roar_conv_bits_24to32(out=%p, in=%p, samples=%i) = -1", out, in, samples); return -1; #endif samples--; ip += 3 * samples; for (i = samples; i >= 0; i--) { #if BYTE_ORDER == BIG_ENDIAN t.c[0] = *(ip--); t.c[1] = *(ip--); t.c[2] = *(ip--); #elif BYTE_ORDER == LITTLE_ENDIAN t.c[2] = *(ip--); t.c[3] = *(ip--); t.c[1] = *(ip--); #endif ROAR_DBG("roar_conv_bits_24to32(*): i=%i, t.i=0x%.8X", i, t.i); op[i] = t.i; } ROAR_DBG("roar_conv_bits_24to32(out=%p, in=%p, samples=%i) = 0", out, in, samples); return 0; } int roar_conv_bits_32to8 (void * out, void * in, int samples) { int32_t * ip = (int32_t*)in; char * op = (char *)out; int i; for (i = 0; i < samples; i++) op[i] = ip[i] >> 24; return 0; } int roar_conv_bits_32to16 (void * out, void * in, int samples) { int32_t * ip = (int32_t*)in; int16_t * op = (int16_t*)out; int i; for (i = 0; i < samples; i++) op[i] = ip[i] >> 16; return 0; } int roar_conv_chans (void * out, void * in, int samples, int from, int to, int bits) { if ( from == to ) { if ( in == out ) return 0; memcpy(out, in, samples * from * bits / 8); return 0; } switch (bits) { case 8: switch (from) { case 1: switch (to) { case 2: return roar_conv_chans_1to28(out, in, samples); default: return roar_conv_chans_1ton8(out, in, samples, to); } break; case 2: switch (to) { case 1: return roar_conv_chans_2to18(out, in, samples); default: return -1; } break; default: switch (to) { case 1: return roar_conv_chans_nto18(out, in, samples, from); default: return -1; } } break; case 16: switch (from) { case 1: switch (to) { case 2: return roar_conv_chans_1to216(out, in, samples); default: return roar_conv_chans_1ton16(out, in, samples, to); } break; case 2: switch (to) { case 1: return roar_conv_chans_2to116(out, in, samples); case 3: return roar_conv_chans_2to316(out, in, samples); case 4: return roar_conv_chans_2to416(out, in, samples); case 5: return roar_conv_chans_2to516(out, in, samples); case 6: return roar_conv_chans_2to616(out, in, samples); default: return -1; } break; case 4: switch (to) { case 1: return roar_conv_chans_nto116(out, in, samples, 4); case 2: return roar_conv_chans_4to216(out, in, samples); default: return -1; } break; default: switch (to) { case 1: return roar_conv_chans_nto116(out, in, samples, from); default: return -1; } } break; case 32: switch (from) { case 1: switch (to) { default: return roar_conv_chans_1ton32(out, in, samples, to); } break; default: switch (to) { case 1: return roar_conv_chans_nto132(out, in, samples, from); default: return -1; } } break; default: return -1; } return -1; } int roar_conv_chans_1ton8 (void * out, void * in, int samples, int to) { char * ip = (char*) in, * op = (char*) out; int i; int c; for (i = samples - 1; i >= 0; i--) for (c = to - 1; c >= 0; c--) op[i*to + c] = ip[i]; return 0; } int roar_conv_chans_1to28 (void * out, void * in, int samples) { char * ip = (char*) in, * op = (char*) out; int i, h; samples--; for (i = (h = samples) * 2; i >= 0; i -= 2, h--) { op[i + 0] = ip[h]; op[i + 1] = ip[h]; } return 0; } int roar_conv_chans_1ton16 (void * out, void * in, int samples, int to) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i; int c; for (i = samples - 1; i >= 0; i--) for (c = to - 1; c >= 0; c--) op[i*to + c] = ip[i]; return 0; } int roar_conv_chans_1ton32 (void * out, void * in, int samples, int to) { int32_t * ip = (int32_t*) in, * op = (int32_t*) out; int i; int c; for (i = samples - 1; i >= 0; i--) for (c = to - 1; c >= 0; c--) op[i*to + c] = ip[i]; return 0; } int roar_conv_chans_1to216 (void * out, void * in, int samples) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i, h; samples--; for (i = (h = samples) * 2; i >= 0; i -= 2, h--) { op[i + 0] = ip[h]; op[i + 1] = ip[h]; } return 0; } int roar_conv_chans_nto18 (void * out, void * in, int samples, int from) { int8_t * ip = (int8_t*) in, * op = (int8_t*) out; int i; int c; register int s; samples /= from; for (i = 0; i < samples; i++) { s = 0; for (c = 0; c < from; c++) s += ip[i*from + c]; s /= from; op[i] = s; } return 0; } int roar_conv_chans_2to18 (void * out, void * in, int samples) { int8_t * ip = (int8_t*) in, * op = (int8_t*) out; int i, h; for (h = i = 0; i < samples; i += 2, h++) op[h] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2; return 0; } int roar_conv_chans_nto116 (void * out, void * in, int samples, int from) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i; int c; register int s; samples /= from; for (i = 0; i < samples; i++) { s = 0; for (c = 0; c < from; c++) s += ip[i*from + c]; s /= from; op[i] = s; } return 0; } int roar_conv_chans_nto132 (void * out, void * in, int samples, int from) { int32_t * ip = (int32_t*) in, * op = (int32_t*) out; int i; int c; register int s; samples /= from; for (i = 0; i < samples; i++) { s = 0; for (c = 0; c < from; c++) s += ip[i*from + c]; s /= from; op[i] = s; } return 0; } int roar_conv_chans_2to116 (void * out, void * in, int samples) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i, h; ROAR_DBG("roar_conv_chans_2to116(out=%p, in=%p, samples=%i) = ?", out, in, samples); for (h = i = 0; i < samples; i += 2, h++) { ROAR_DBG("roar_conv_chans_2to116(out=%p, in=%p, samples=%i): op[%i] = (ip[%i] + ip[%i])/2", out, in, samples, h, i, i+1); op[h] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2; } return 0; } int roar_conv_chans_2to38 (void * out, void * in, int samples); int roar_conv_chans_2to316 (void * out, void * in, int samples) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i, h; samples -= 2; i = samples; h = (samples / 2) * 3; for (; i >= 0; i -= 2, h -= 3) { op[h+0] = ip[i+0]; op[h+1] = ip[i+1]; op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2; } return 0; } int roar_conv_chans_2to48 (void * out, void * in, int samples); int roar_conv_chans_2to416 (void * out, void * in, int samples) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i, h; samples -= 2; i = samples; h = (samples / 2) * 4; for (; i >= 0; i -= 2, h -= 4) { op[h+0] = ip[i+0]; op[h+1] = ip[i+1]; op[h+2] = ip[i+0]; op[h+3] = ip[i+1]; } return 0; } int roar_conv_chans_2to58 (void * out, void * in, int samples); int roar_conv_chans_2to516 (void * out, void * in, int samples) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i, h; samples -= 2; i = samples; h = (samples / 2) * 5; for (; i >= 0; i -= 2, h -= 5) { op[h+0] = ip[i+0]; op[h+1] = ip[i+1]; op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2; op[h+3] = ip[i+0]; op[h+4] = ip[i+1]; } return 0; } int roar_conv_chans_2to68 (void * out, void * in, int samples); int roar_conv_chans_2to616 (void * out, void * in, int samples) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i, h; samples -= 2; i = samples; h = (samples / 2) * 6; for (; i >= 0; i -= 2, h -= 6) { op[h+0] = ip[i+0]; op[h+1] = ip[i+1]; op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2; op[h+3] = op[h+2]; op[h+4] = ip[i+0]; op[h+5] = ip[i+1]; } return 0; } int roar_conv_chans_3to28 (void * out, void * in, int samples); int roar_conv_chans_3to216 (void * out, void * in, int samples); int roar_conv_chans_4to28 (void * out, void * in, int samples); int roar_conv_chans_4to216 (void * out, void * in, int samples) { int16_t * ip = (int16_t*) in, * op = (int16_t*) out; int i, h; samples -= 4; for (i = h = 0; i < samples; i += 4, h += 2) { op[h+0] = ((int)ip[i + 0] + (int)ip[i + 2]) / 2; op[h+1] = ((int)ip[i + 1] + (int)ip[i + 3]) / 2; } return 0; } int roar_conv_chans_5to28 (void * out, void * in, int samples); int roar_conv_chans_5to216 (void * out, void * in, int samples); int roar_conv_chans_6to28 (void * out, void * in, int samples); int roar_conv_chans_6to216 (void * out, void * in, int samples); int roar_conv_rate (void * out, void * in, int samples, int from, int to, int bits, int channels) { #ifdef ROAR_HAVE_LIBSAMPLERATE return roar_conv_rate_SRC(out, in, samples, from, to, bits, channels); #else if ( bits == 8 ) return roar_conv_rate_8(out, in, samples, from, to, channels); if ( bits == 16 ) return roar_conv_rate_16(out, in, samples, from, to, channels); return -1; #endif } int roar_conv_rate_8 (void * out, void * in, int samples, int from, int to, int channels) { return -1; } int roar_conv_rate_16 (void * out, void * in, int samples, int from, int to, int channels) { if ( from > to ) { switch (channels) { case 1: return roar_conv_rate_161zoh(out, in, samples, from, to); case 2: return roar_conv_rate_162zoh(out, in, samples, from, to); default: return -1; } } else { if ( channels == 1 ) { printf("roar_conv_rate_16(): samples=%i -> %i, rate=%i -> %i\n", samples*from/to, samples, from, to); return roar_conv_poly4_16s((int16_t*) out, (int16_t*) in, samples, samples*from/to, (float)from/to); // return roar_conv_poly4_16((int16_t*) out, (int16_t*) in, samples*to/from, samples); } } return -1; } int roar_conv_rate_161zoh(void * out, void * in, int samples, int from, int to) { int16_t * ip = in; int16_t * op = out; float t = 0; float step = (float)to/from; int i; for (i= 0; i < samples; i++) { op[(int)t] = ip[i]; t += step; } return 0; } int roar_conv_rate_162zoh(void * out, void * in, int samples, int from, int to) { int16_t * ip = in; int16_t * op = out; float t = 0; float step = (float)to/from; int i; ROAR_DBG("roar_conv_rate_162zoh(*): samples=%i", samples); samples /= 2; // samples -= 1; ROAR_DBG("roar_conv_rate_162zoh(*): samples=%i", samples); for (i= 0; i < samples; i++) { ROAR_DBG("roar_conv_rate_162zoh(*): t=%f, i=%i // op[%i] = ip[%i]", t, i, 2*(int)t, 2*i); op[2*(int)t ] = ip[2*i ]; op[2*(int)t + 1] = ip[2*i + 1]; t += step; } return 0; } int roar_conv_rate_SRC (void * out, void * in, int samples, int from, int to, int bits, int channels) { #ifdef ROAR_HAVE_LIBSAMPLERATE double radio = (double) to / (double) from; int outsamples = radio * samples; float * inf = roar_mm_malloc(samples*sizeof(float)); float * outf = roar_mm_malloc(outsamples*sizeof(float)); int i; SRC_DATA srcdata; ROAR_DBG("roar_conv_rate_SRC(*): radio=%lf, samples=%i, outsamples=%i", radio, samples, outsamples); if ( inf == NULL ) { if ( outf != NULL ) roar_mm_free(outf); return -1; } if ( outf == NULL ) { if ( inf != NULL ) roar_mm_free(inf); return -1; } switch (bits) { case 8: for (i = 0; i < samples; i++) inf[i] = *(((int8_t *)in)+i) / 128.0; break; case 16: for (i = 0; i < samples; i++) inf[i] = *(((int16_t*)in)+i) / 32768.0; break; case 32: for (i = 0; i < samples; i++) inf[i] = *(((int32_t*)in)+i) / 2147483648.0; break; default: roar_mm_free(outf); roar_mm_free(inf); return -1; } srcdata.data_in = inf; srcdata.data_out = outf; srcdata.input_frames = samples/channels; srcdata.output_frames = outsamples/channels; srcdata.src_ratio = radio; if ( src_simple(&srcdata, SRC_ZERO_ORDER_HOLD, channels) != 0 ) { roar_mm_free(outf); roar_mm_free(inf); return -1; } switch (bits) { case 8: for (i = 0; i < outsamples; i++) *(((int8_t *)out)+i) = outf[i] * 128.0; break; case 16: for (i = 0; i < outsamples; i++) *(((int16_t*)out)+i) = outf[i] * 32768.0; break; case 32: for (i = 0; i < outsamples; i++) *(((int32_t*)out)+i) = outf[i] * 2147483648.0; break; // no errors here, they are handled above } roar_mm_free(outf); roar_mm_free(inf); return 0; #else return -1; #endif } int roar_conv_rate2 (void * out, void * in, int outsamples, int samples, int bits, int channels) { ROAR_DBG("roar_conv_rate2(out=%p, in=%p, samples=%i, outsamples=%i, bits=%i, channels=%i) = ?", out, in, samples, outsamples, bits, channels); switch (bits) { case 8: return roar_conv_poly3_8(out, in, outsamples, samples, channels); break; case 16: return roar_conv_poly3_16(out, in, outsamples, samples, channels); break; case 32: return roar_conv_poly3_32(out, in, outsamples, samples, channels); break; } return -1; } int roar_conv_signedness (void * out, void * in, int samples, int from, int to, int bits) { if ( from != to ) { if ( from && !to ) { switch (bits) { case 8: roar_conv_codec_s2u8( out, in, samples); break; case 16: roar_conv_codec_s2u16(out, in, samples); break; case 32: roar_conv_codec_s2u32(out, in, samples); break; default: errno = ENOSYS; return -1; } } else if ( !from && to ) { switch (bits) { case 8: roar_conv_codec_u2s8( out, in, samples); break; case 16: roar_conv_codec_u2s16(out, in, samples); break; case 32: roar_conv_codec_u2s32(out, in, samples); break; default: errno = ENOSYS; return -1; } } else { return -1; } } else { if ( out == in ) return 0; memcpy(out, in, samples * bits / 8); return 0; } return 0; } int roar_conv_codec (void * out, void * in, int samples, int from, int to, int bits) { int inbo = ROAR_CODEC_BYTE_ORDER(from), outbo = ROAR_CODEC_BYTE_ORDER(to); int ins = ROAR_CODEC_IS_SIGNED(from), outs = ROAR_CODEC_IS_SIGNED(to); void * nin = in; ROAR_DBG("roar_conv_codec(out=%p, in=%p, samples=%i, from=%i(%s), to=%i(%s), bits=%i) = ?", out, in, samples, from, roar_codec2str(from), to, roar_codec2str(to), bits); roar_conv_endian(out, in, samples, inbo, outbo, bits); nin = out; return roar_conv_signedness(out, in, samples, ins, outs, bits); } int roar_conv_codec_s2u8 (void * out, void * in, int samples) { char * ip = in; unsigned char * op = out; int i; for(i = 0; i < samples; i++) op[i] = ip[i] + 128; return 0; } int roar_conv_codec_s2u16 (void * out, void * in, int samples) { int16_t * ip = in; uint16_t * op = out; int i; for(i = 0; i < samples; i++) op[i] = ip[i] + 32768; return 0; } int roar_conv_codec_s2u32 (void * out, void * in, int samples) { int32_t * ip = in; uint32_t * op = out; int i; for(i = 0; i < samples; i++) op[i] = ip[i] + 2147483648U; return 0; } int roar_conv_codec_u2s8 (void * out, void * in, int samples) { unsigned char * ip = in; char * op = out; int i; for(i = 0; i < samples; i++) op[i] = ip[i] - 128; return 0; } int roar_conv_codec_u2s16 (void * out, void * in, int samples) { uint16_t * ip = in; int16_t * op = out; int i; for(i = 0; i < samples; i++) op[i] = ip[i] - 32768; return 0; } int roar_conv_codec_u2s32 (void * out, void * in, int samples) { uint32_t * ip = in; int32_t * op = out; int i; for(i = 0; i < samples; i++) op[i] = ip[i] - 2147483648U; return 0; } int roar_conv_endian (void * out, void * in, int samples, int from, int to, int bits) { if ( bits == 8 ) { from = to = ROAR_CODEC_NATIVE_ENDIAN; } else if ( bits == 16 ) { if ( from == ROAR_CODEC_PDP ) from = ROAR_CODEC_LE; if ( to == ROAR_CODEC_PDP ) to = ROAR_CODEC_LE; } ROAR_DBG("roar_conv_endian(out=%p, in=%p, samples=%i, from=%i, to=%i, bits=%i) = ?", out, in, samples, from, to, bits); if ( from == to ) { if ( in != out ) { memcpy(out, in, samples * bits / 8); } return 0; } else { switch (bits) { case 16: // in this case we can only have LE vs. BE, so, only need to swap: ROAR_DBG("roar_conv_endian(*): Doing 16 bit byteswap"); return roar_conv_endian_16(out, in, samples); break; case 24: if ( (from == ROAR_CODEC_LE || from == ROAR_CODEC_BE) && (to == ROAR_CODEC_LE || to == ROAR_CODEC_BE) ) { return roar_conv_endian_24(out, in, samples); } else { // what the hell is PDP eddines in 24 bit mode? return -1; } break; case 32: if ( (from == ROAR_CODEC_LE || from == ROAR_CODEC_BE) && (to == ROAR_CODEC_LE || to == ROAR_CODEC_BE) ) { return roar_conv_endian_32(out, in, samples); } else { // need to handle 32 PDP eddines here? if ( from == ROAR_CODEC_BE ) if ( roar_conv_endian_32(out, in, samples) == -1 ) return -1; if ( roar_conv_endian_16(out, in, samples*2) == -1 ) return -1; if ( to == ROAR_CODEC_BE ) if ( roar_conv_endian_32(out, in, samples) == -1 ) return -1; return 0; } break; default: return -1; break; } } return -1; } int roar_conv_endian_16 (void * out, void * in, int samples) { char * ip = in; char * op = out; register char c; int i; samples *= 2; if ( out != in ) { // printf("out != in\n"); for(i = 0; i < samples; i += 2) { // printf("op[%i] = ip[%i]\nop[%i] = ip[%i]\n", i, i+1, i+1, i); op[i ] = ip[i+1]; op[i+1] = ip[i ]; } } else { // printf("out == in\n"); for(i = 0; i < samples; i += 2) { c = ip[i+1]; op[i+1] = ip[i ]; op[i ] = c; } } return 0; } int roar_conv_endian_24 (void * out, void * in, int samples) { char * ip = in; char * op = out; register char c; int i; samples *= 3; if ( out != in ) { // printf("out != in\n"); for(i = 0; i < samples; i += 3) { // printf("op[%i] = ip[%i]\nop[%i] = ip[%i]\n", i, i+1, i+1, i); op[i ] = ip[i+2]; op[i+2] = ip[i ]; } } else { // printf("out == in\n"); for(i = 0; i < samples; i += 3) { c = ip[i+2]; op[i+2] = ip[i ]; op[i ] = c; } } return 0; } int roar_conv_endian_32 (void * out, void * in, int samples) { int32_t * ip = in; int32_t * op = out; union { int32_t val; char data[4]; } c, h; int i; // may the holly optimizer save our souls! ROAR_DBG("roar_conv_endian_32(out=%p, in=%p, samples=%i) = ?", out, in, samples); for (i = 0; i < samples; i++) { c.val = ip[i]; h.data[0] = c.data[3]; h.data[1] = c.data[2]; h.data[2] = c.data[1]; h.data[3] = c.data[0]; op[i] = h.val; } return 0; } int roar_conv (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) { void * ip = in; void * real_out = NULL; size_t from_size, to_size; // TODO: decide how to work around both in and out beeing to small to hold all // data between the steps. // for the moment: guess out >= in from_size = (from->bits * samples) / 8; to_size = ( to->bits * samples * to->rate * to->channels) / (8 * from->rate * from->channels); ROAR_DBG("roar_conv(*): size: %i->%i", from_size, to_size); if ( to_size < from_size ) { real_out = out; if ( (out = roar_mm_malloc(from_size)) == NULL ) return -1; ROAR_DBG("roar_conv(*): roar_mm_malloc(%i)=%p", (int)from_size, out); } ROAR_DBG("roar_conv(*): bo conv: %i->%i(native)", ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN); if ( ROAR_CODEC_BYTE_ORDER(from->codec) != ROAR_CODEC_NATIVE_ENDIAN ) { ROAR_DBG("roar_conv(*): doing bo input conv"); if ( roar_conv_endian(out, ip, samples, ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN, from->bits) == -1 ) { if ( to_size < from_size ) roar_mm_free(out); return -1; } else { ip = out; } } if ( from->bits != to->bits ) { if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 ) { if ( to_size < from_size ) roar_mm_free(out); return -1; } else { ip = out; } } if ( ROAR_CODEC_IS_SIGNED(from->codec) != ROAR_CODEC_IS_SIGNED(to->codec) ) { if ( roar_conv_signedness(out, ip, samples, ROAR_CODEC_IS_SIGNED(from->codec), ROAR_CODEC_IS_SIGNED(to->codec), to->bits) == -1 ) { if ( to_size < from_size ) roar_mm_free(out); return -1; } else { ip = out; } } /* if ( from->codec != to->codec ) { if ( roar_conv_codec (out, ip, samples, from->codec, to->codec, to->bits) == -1 ) return -1; else ip = out; } */ if ( from->rate != to->rate ) { if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 ) { ROAR_DBG("roar_conv(*): failed to convert rate %i->%i (%ich%ibits)", from->rate, to->rate, to->bits, from->channels); if ( to_size < from_size ) roar_mm_free(out); return -1; } else { ip = out; samples = (samples * to->rate) / from->rate; } } if ( from->channels != to->channels ) { if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 ) { if ( to_size < from_size ) roar_mm_free(out); return -1; } else { ip = out; } } if ( ROAR_CODEC_BYTE_ORDER(to->codec) != ROAR_CODEC_NATIVE_ENDIAN ) { if ( roar_conv_endian(out, ip, samples, ROAR_CODEC_NATIVE_ENDIAN, ROAR_CODEC_BYTE_ORDER(to->codec), to->bits) == -1 ) { if ( to_size < from_size ) roar_mm_free(out); return -1; } else { ip = out; } } if ( to_size < from_size ) { ROAR_DBG("roar_conv(*): memcpy(%p, %p, %i) = ?", real_out, out, (int)to_size); memcpy(real_out, out, to_size); roar_mm_free(out); ROAR_DBG("roar_conv(*): free(%p): OK!", out); } return 0; } int roar_conv2(void * out, void * in, size_t inlen, struct roar_audio_info * from, struct roar_audio_info * to, size_t bufsize) { size_t samples; // size_t needed_buffer; void * cin = in; struct roar_audio_info cinfo; int need_signed = 0; size_t outsamples; memcpy(&cinfo, from, sizeof(cinfo)); ROAR_DBG("roar_conv2(out=%p, in=%p, inlen=%lu, from=%p{...}, to=%p{...}, bufsize=%lu", out, in, (unsigned long int)inlen, from, to, (unsigned long int)bufsize); /* if ( in != out ) { memset(out, 0xA0, bufsize); } else { ROAR_WARN("roar_conv2(*): in==out!"); memset(out+inlen, 0xA0, bufsize-inlen); } */ // calculate number of input samples: samples = (inlen * 8) / (from->bits); ROAR_DBG("roar_conv2(*): input samples: %i", samples); #if 0 // calculate size per frame needed_buffer = ROAR_MAX(from->channels, to->channels) * ROAR_MAX(from->bits, to->bits) / 8; needed_buffer *= samples; needed_buffer /= from->channels; if ( from->rate < to->rate ) needed_buffer *= (float)to->rate/(float)from->rate; ROAR_DBG("roar_conv2(*): needed_buffer=%u, bufsize=%u", needed_buffer, bufsize); // check if we have enogth RAM to convert if ( needed_buffer > bufsize ) return -1; #endif if ( from->rate != to->rate || from->channels != to->channels ) need_signed = 1; ROAR_DBG("roar_conv2(*): need_signed=%i", need_signed); if ( ROAR_CODEC_BYTE_ORDER(from->codec) != ROAR_CODEC_NATIVE_ENDIAN ) { ROAR_DBG("roar_conv2(*): doing bo input conv"); if ( roar_conv_endian(out, cin, samples, ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN, from->bits) == -1 ) { return -1; } cin = out; } if ( to->bits > from->bits ) { ROAR_DBG("roar_conv2(*): bits: %i->%i", from->bits, to->bits); if ( roar_conv_bits(out, cin, samples, from->bits, to->bits) == -1 ) return -1; cin = out; cinfo.bits = to->bits; } if ( need_signed && ! ROAR_CODEC_IS_SIGNED(from->codec) ) { ROAR_DBG("roar_conv2(*): sign: unsigned->signed"); if ( roar_conv_signedness(out, cin, samples, ROAR_CODEC_IS_SIGNED(from->codec), ROAR_CODEC_IS_SIGNED(to->codec), cinfo.bits) == -1 ) return -1; cin = out; cinfo.codec = ROAR_CODEC_PCM_S_LE; // just a signed PCM, which is of no intrest } if ( to->channels > from->channels ) { ROAR_DBG("roar_conv2(*): channels: %i->%i", from->channels, to->channels); if ( roar_conv_chans(out, cin, samples, from->channels, to->channels, cinfo.bits) == -1 ) return -1; cin = out; samples = (samples * to->channels) / cinfo.channels; cinfo.channels = to->channels; } //--// if ( from->rate != to->rate ) { outsamples = bufsize; ROAR_DBG("roar_conv2(*): outsamples=%llu", (long long unsigned int)outsamples); if ( cinfo.channels != to->channels ) { outsamples *= cinfo.channels; outsamples /= to->channels; } if ( cinfo.bits != to->bits ) { outsamples *= cinfo.bits; outsamples /= to->bits; } outsamples /= cinfo.bits/8; ROAR_DBG("roar_conv2(*): outsamples=%llu", (long long unsigned int)outsamples); if ( roar_conv_rate2(out, cin, outsamples, samples, cinfo.bits, cinfo.channels) == -1 ) return -1; cin = out; samples = outsamples; cinfo.rate = to->rate; } if ( cinfo.channels != to->channels ) { ROAR_DBG("roar_conv2(*): channels: %i->%i", cinfo.channels, to->channels); if ( roar_conv_chans(out, cin, samples, cinfo.channels, to->channels, cinfo.bits) == -1 ) return -1; cin = out; samples = (samples * to->channels) / cinfo.channels; cinfo.channels = to->channels; } if ( ROAR_CODEC_IS_SIGNED(cinfo.codec) != ROAR_CODEC_IS_SIGNED(to->codec) ) { ROAR_DBG("roar_conv2(*): sign: ?(%i)->?(%i)", ROAR_CODEC_IS_SIGNED(cinfo.codec), ROAR_CODEC_IS_SIGNED(to->codec)); if ( roar_conv_signedness(out, cin, samples, ROAR_CODEC_IS_SIGNED(cinfo.codec), ROAR_CODEC_IS_SIGNED(to->codec), cinfo.bits) == -1 ) return -1; cin = out; cinfo.codec = to->codec; } if ( cinfo.bits != to->bits ) { ROAR_DBG("roar_conv2(*): bits: %i->%i", cinfo.bits, to->bits); if ( roar_conv_bits(out, cin, samples, cinfo.bits, to->bits) == -1 ) return -1; cin = out; cinfo.bits = to->bits; } if ( ROAR_CODEC_BYTE_ORDER(to->codec) != ROAR_CODEC_NATIVE_ENDIAN ) { ROAR_DBG("roar_conv2(*): doing bo output conv"); if ( roar_conv_endian(out, cin, samples, ROAR_CODEC_NATIVE_ENDIAN, ROAR_CODEC_BYTE_ORDER(to->codec), to->bits) == -1 ) { return -1; } cin = out; } ROAR_DBG("roar_conv2(*): samples=%llu", (long long unsigned int)samples); ROAR_DBG("roar_conv2(*) = 0"); return 0; } int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) { return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen); } int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) { float poly[4]; float data[4]; float t = 0; int16_t * ci = in; int io, ii = 0; int i; // printf("step=%f\n", step); // we can not make a poly4 with less than 4 points ;) if ( ilen < 4 ) return -1; for (i = 0; i < 4; i++) data[i] = ci[i]; roar_math_mkpoly_4x4(poly, data); /* printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n", data[0], data[1], data[2], data[3], poly[0], poly[1], poly[2], poly[3] ); */ //0 1 2 3 for (io = 0; io < olen; io++) { // printf("t=%f\n", t); out[io] = roar_math_cvpoly_4x4(poly, t); t += step; if ( t > 2 ) { // we need a new ploynome // printf("t > 2, need new data\n"); if ( (ii + 4) < ilen ) { // else: end of block. t -= 1; // printf("new data: ii=%i\n", ii); ii++; ci++; for (i = 0; i < 4; i++) data[i] = ci[i]; roar_math_mkpoly_4x4(poly, data); /* printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n", data[0], data[1], data[2], data[3], poly[0], poly[1], poly[2], poly[3] ); */ } } } // printf("io=%i\n", io); return 0; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/dtmf.c���������������������������������������������������������������0000644�0001750�0001750�00000015666�12264733557�015752� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//dtmf.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "libroardsp.h" ssize_t roar_dtmf_mus2samples(const int_least32_t t, const uint32_t rate) { int64_t ret = t; if ( t < 0 || rate == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } ret *= (int64_t)rate; ret /= (int64_t)1000000; return ret; } int roar_dtmf_break(int16_t * samples, const size_t len, const uint32_t rate, const int options) { (void)rate, (void)options; ROAR_DBG("roar_dtmf_break(samples=%p, len=%llu, rate=%lu, options=%i) = ?", samples, (long long unsigned int)len, (long unsigned int)rate, options); if ( samples == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(samples, 0, len*sizeof(int16_t)); return 0; } #define _FQL0 697 #define _FQL1 770 #define _FQL2 852 #define _FQL3 941 #define _FQH0 1209 #define _FQH1 1336 #define _FQH2 1477 #define _FQH3 1633 #define _FRL0 571 #define _FRL1 631 #define _FRL2 _FQL0 #define _FRL3 _FQL1 #define _FRL4 _FQL2 #define _FRL5 _FQL3 #define _FRL6 1040 #define _FRH0 _FQH0 #define _FRH1 _FQH1 #define _FRH2 _FQH2 #define _FRH3 _FQH3 #define _FRH4 1805 #define _FRH5 1995 #define _FRH6 2205 static const struct tone { const uint16_t c; const float f0; const float f1; } _roardsp_tones[] = { {ROAR_DTMF_CHAR_DTMF('1'), _FQL0, _FQH0}, {ROAR_DTMF_CHAR_DTMF('2'), _FQL0, _FQH1}, {ROAR_DTMF_CHAR_DTMF('3'), _FQL0, _FQH2}, {ROAR_DTMF_CHAR_DTMF('A'), _FQL0, _FQH3}, {ROAR_DTMF_CHAR_DTMF('4'), _FQL1, _FQH0}, {ROAR_DTMF_CHAR_DTMF('5'), _FQL1, _FQH1}, {ROAR_DTMF_CHAR_DTMF('6'), _FQL1, _FQH2}, {ROAR_DTMF_CHAR_DTMF('B'), _FQL1, _FQH3}, {ROAR_DTMF_CHAR_DTMF('7'), _FQL2, _FQH0}, {ROAR_DTMF_CHAR_DTMF('8'), _FQL2, _FQH1}, {ROAR_DTMF_CHAR_DTMF('9'), _FQL2, _FQH2}, {ROAR_DTMF_CHAR_DTMF('C'), _FQL2, _FQH3}, {ROAR_DTMF_CHAR_DTMF('*'), _FQL3, _FQH0}, {ROAR_DTMF_CHAR_DTMF('0'), _FQL3, _FQH1}, {ROAR_DTMF_CHAR_DTMF('#'), _FQL3, _FQH2}, {ROAR_DTMF_CHAR_DTMF('D'), _FQL3, _FQH3}, {ROAR_DTMF_CHAR_NOOP, _FRL0, _FRH0}, {ROAR_DTMF_CHAR_ESCAPE, _FRL0, _FRH1}, {ROAR_DTMF_CHAR_ROAR('"'), _FRL0, _FRH2}, {ROAR_DTMF_CHAR_ROAR(' '), _FRL0, _FRH3}, {ROAR_DTMF_CHAR_ROAR('F'), _FRL0, _FRH4}, {ROAR_DTMF_CHAR_ROAR('M'), _FRL0, _FRH5}, {ROAR_DTMF_CHAR_ROAR('T'), _FRL0, _FRH6}, {ROAR_DTMF_CHAR_ROAR('.'), _FRL1, _FRH0}, {ROAR_DTMF_CHAR_ROAR('?'), _FRL1, _FRH1}, {ROAR_DTMF_CHAR_ROAR('!'), _FRL1, _FRH2}, {ROAR_DTMF_CHAR_ROAR(','), _FRL1, _FRH3}, {ROAR_DTMF_CHAR_ROAR('G'), _FRL1, _FRH4}, {ROAR_DTMF_CHAR_ROAR('N'), _FRL1, _FRH5}, {ROAR_DTMF_CHAR_ROAR('U'), _FRL1, _FRH6}, {ROAR_DTMF_CHAR_ROAR('1'), _FRL2, _FRH0}, {ROAR_DTMF_CHAR_ROAR('2'), _FRL2, _FRH1}, {ROAR_DTMF_CHAR_ROAR('3'), _FRL2, _FRH2}, {ROAR_DTMF_CHAR_ROAR('A'), _FRL2, _FRH3}, {ROAR_DTMF_CHAR_ROAR('H'), _FRL2, _FRH4}, {ROAR_DTMF_CHAR_ROAR('O'), _FRL2, _FRH5}, {ROAR_DTMF_CHAR_ROAR('V'), _FRL2, _FRH6}, {ROAR_DTMF_CHAR_ROAR('4'), _FRL3, _FRH0}, {ROAR_DTMF_CHAR_ROAR('5'), _FRL3, _FRH1}, {ROAR_DTMF_CHAR_ROAR('6'), _FRL3, _FRH2}, {ROAR_DTMF_CHAR_ROAR('B'), _FRL3, _FRH3}, {ROAR_DTMF_CHAR_ROAR('I'), _FRL3, _FRH4}, {ROAR_DTMF_CHAR_ROAR('P'), _FRL3, _FRH5}, {ROAR_DTMF_CHAR_ROAR('W'), _FRL3, _FRH6}, {ROAR_DTMF_CHAR_ROAR('7'), _FRL4, _FRH0}, {ROAR_DTMF_CHAR_ROAR('8'), _FRL4, _FRH1}, {ROAR_DTMF_CHAR_ROAR('9'), _FRL4, _FRH2}, {ROAR_DTMF_CHAR_ROAR('C'), _FRL4, _FRH3}, {ROAR_DTMF_CHAR_ROAR('J'), _FRL4, _FRH4}, {ROAR_DTMF_CHAR_ROAR('Q'), _FRL4, _FRH5}, {ROAR_DTMF_CHAR_ROAR('X'), _FRL4, _FRH6}, {ROAR_DTMF_CHAR_ROAR('*'), _FRL5, _FRH0}, {ROAR_DTMF_CHAR_ROAR('0'), _FRL5, _FRH1}, {ROAR_DTMF_CHAR_ROAR('#'), _FRL5, _FRH2}, {ROAR_DTMF_CHAR_ROAR('D'), _FRL5, _FRH3}, {ROAR_DTMF_CHAR_ROAR('K'), _FRL5, _FRH4}, {ROAR_DTMF_CHAR_ROAR('R'), _FRL5, _FRH5}, {ROAR_DTMF_CHAR_ROAR('Y'), _FRL5, _FRH6}, {ROAR_DTMF_CHAR_ROAR('@'), _FRL6, _FRH0}, {ROAR_DTMF_CHAR_ROAR('+'), _FRL6, _FRH1}, {ROAR_DTMF_CHAR_ROAR('-'), _FRL6, _FRH2}, {ROAR_DTMF_CHAR_ROAR('E'), _FRL6, _FRH3}, {ROAR_DTMF_CHAR_ROAR('L'), _FRL6, _FRH4}, {ROAR_DTMF_CHAR_ROAR('S'), _FRL6, _FRH5}, {ROAR_DTMF_CHAR_ROAR('Z'), _FRL6, _FRH6}, {0, -1, -1} }; static const struct tone * __lookup_tone_by_char(const int options, uint16_t c) { size_t i; (void)options; if ( (c >= ROAR_DTMF_CHAR_DTMF('a') && c <= ROAR_DTMF_CHAR_DTMF('z')) || (c >= ROAR_DTMF_CHAR_ROAR('a') && c <= ROAR_DTMF_CHAR_ROAR('z')) ) c -= 'a' - 'A'; for (i = 0; _roardsp_tones[i].c != 0; i++) { if ( _roardsp_tones[i].c == c ) { return &(_roardsp_tones[i]); } } roar_err_set(ROAR_ERROR_NOENT); return NULL; } static const struct tone * __lookup_tone_by_freq(const int options, float f0, float f1) { const struct tone * ct; size_t i; float tmp; (void)options; if ( f0 > f1 ) { tmp = f0; f0 = f1; f1 = tmp; } for (i = 0; _roardsp_tones[i].c != 0; i++) { ct = &(_roardsp_tones[i]); // allow 3.5% freq error as defined in ITU-T Q.23 and Q.24. if ( ct->f0 < f0*.965 || ct->f0 > f0*1.035 ) continue; if ( ct->f1 < f1*.965 || ct->f1 > f1*1.035 ) continue; return ct; } roar_err_set(ROAR_ERROR_NOENT); return NULL; } int roar_dtmf_tone (int16_t * samples, const size_t len, const uint32_t rate, const int options, const uint16_t c) { const struct tone * ct = NULL; #ifdef ROAR_HAVE_LIBM size_t i; float t; float t_inc = 1./rate; float fc0, fc1; #endif ROAR_DBG("roar_dtmf_tone(samples=%p, len=%llu, rate=%lu, options=%i, c=%i) = ?", samples, (long long unsigned int)len, (long unsigned int)rate, options, (int)c); if ( samples == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( c == ROAR_DTMF_CHAR_BREAK ) return roar_dtmf_break(samples, len, rate, options); ct = __lookup_tone_by_char(options, c); if ( ct == NULL ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } #ifdef ROAR_HAVE_LIBM fc0 = 2. * M_PI * ct->f0; fc1 = 2. * M_PI * ct->f1; // memset(samples, 0, len); for (i = 0, t = 0.; i < len; t += t_inc, i++) { samples[i] = (sinf(fc0*t) + sinf(fc1*t))*8192.0; } #else roar_err_set(ROAR_ERROR_NOTSUP); return -1; #endif return 0; } uint16_t roar_dtmf_freqs2char(const int options, float f0, float f1) { const struct tone * ct = __lookup_tone_by_freq(options, f0, f1); if ( ct == NULL ) return ROAR_DTMF_CHAR_BREAK; return ct->c; } //ll ��������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/fader.c��������������������������������������������������������������0000644�0001750�0001750�00000006742�12264733557�016074� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//fader.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #define _CHECK_BASIC() if ( state == NULL ) return -1 #define _CHECK_CALCPCM() _CHECK_BASIC(); if ( frames == 0 ) return 0; if ( data == NULL ) return -1; int roar_fader_init (struct roar_fader_state * state, const float * poly, int coeff) { _CHECK_BASIC(); if ( poly == NULL ) return -1; if ( coeff < 2 ) return -1; if ( coeff > ROAR_FADER_MAX_COEFF ) return -1; memset(state, 0, sizeof(struct roar_fader_state)); state->rate = -1; state->coeff = coeff; state->start = -1; state->stop = -1; memcpy(state->poly, poly, sizeof(float)*coeff); return 0; } int roar_fader_set_rate (struct roar_fader_state * state, int rate) { _CHECK_BASIC(); state->rate = rate; return 0; } int roar_fader_set_startstop(struct roar_fader_state * state, ssize_t start, ssize_t stop) { _CHECK_BASIC(); if ( start >= 0 ) state->start = start; if ( stop >= 0 ) state->stop = stop; return 0; } int roar_fader_has_started (struct roar_fader_state * state) { if ( state == NULL ) return -1; if ( state->start == -1 ) return 0; if ( state->start <= state->pcmoffset ) return 1; return 0; } int roar_fader_has_ended (struct roar_fader_state * state) { if ( state == NULL ) return -1; if ( state->stop == -1 ) return 0; if ( state->stop > state->pcmoffset ) return 1; return 0; } int roar_fader_calcpcm_i16n(struct roar_fader_state * state, int16_t * data, size_t frames, int channels) { _CHECK_CALCPCM(); switch (channels) { case 1: return roar_fader_calcpcm_i161(state, data, frames); } return -1; } int roar_fader_calcpcm_i161(struct roar_fader_state * state, int16_t * data, size_t frames) { size_t start, stop, cur; int i, i_s, i_e; float t_cur, t_step; float g_cur; _CHECK_BASIC(); if ( state->start == -1 ) { start = state->pcmoffset; } else { start = state->start; } if ( state->stop == -1 ) { stop = state->pcmoffset + frames; } else { stop = state->stop; } cur = state->pcmoffset; i_s = 0; i_e = frames; if ( start > cur ) i_s = start - cur; if ( stop < (cur + frames) ) i_e = stop - cur; t_step = (float)(state->coeff - 1)/(float)(stop - start); if ( start < cur ) { t_cur = (cur - start)*t_step; } else { t_cur = 0; } ROAR_DBG("roar_fader_calcpcm_i161(*): i_s->i_e: %i->%i", i_s, i_e); for (i = i_s; i < i_e; i++, cur++) { t_cur += t_step; g_cur = roar_math_cvpoly(state->poly, t_cur, state->coeff); // ROAR_DBG("roar_fader_calcpcm_i161(*): i=%i, g_cur=%f", i, g_cur); data[i] = (float)data[i] * g_cur; } state->pcmoffset = cur; return -1; } //ll ������������������������������roaraudio-1.0beta11/libroardsp/filter.c�������������������������������������������������������������0000644�0001750�0001750�00000022353�12264733557�016274� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" static struct _roardsp_filterlist { int id; char * name; int (* init )(struct roardsp_filter * filter, struct roar_stream * stream, int id); int (*uninit )(struct roardsp_filter * filter); int (*ctl )(struct roardsp_filter * filter, int cmd, void * data); int (*reset )(struct roardsp_filter * filter, int what); int (*calc [5][3])(struct roardsp_filter * filter, void * data, size_t samples); } _roardsp_filterlist[] = { {ROARDSP_FILTER_AMP, "AMP", roardsp_amp_init, roardsp_amp_uninit, roardsp_amp_ctl, roardsp_amp_reset, { {NULL, NULL, NULL},{roardsp_amp_calc8, NULL, NULL},{roardsp_amp_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_amp_calc32, NULL, NULL}}}, {ROARDSP_FILTER_ADD, "Add", roardsp_amp_init, roardsp_amp_uninit, roardsp_amp_ctl, roardsp_add_reset, { {NULL, NULL, NULL},{roardsp_add_calc8, NULL, NULL},{roardsp_add_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_add_calc32, NULL, NULL}}}, #ifdef ROAR_HAVE_LIBM {ROARDSP_FILTER_LOWP, "Lowpass", roardsp_lowp_init, roardsp_lowp_uninit, roardsp_lowp_ctl, roardsp_lowp_reset, { {NULL, NULL, NULL},{roardsp_lowp_calc8, NULL, NULL},{roardsp_lowp_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_lowp_calc32, NULL, NULL}}}, {ROARDSP_FILTER_HIGHP, "Highpass", roardsp_highp_init, roardsp_highp_uninit, roardsp_highp_ctl, roardsp_highp_reset, { {NULL, NULL, NULL},{roardsp_highp_calc8, NULL, NULL},{roardsp_highp_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_highp_calc32, NULL, NULL}}}, #endif {ROARDSP_FILTER_QUANTIFY, "Quantifier", roardsp_quantify_init, NULL, roardsp_quantify_ctl, roardsp_quantify_reset, { {NULL, NULL, NULL},{roardsp_quantify_calc8, NULL, NULL},{roardsp_quantify_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_quantify_calc32, NULL, NULL}}}, {ROARDSP_FILTER_CLIP, "Clip", roardsp_clip_init, roardsp_clip_uninit, roardsp_clip_ctl, roardsp_clip_reset, { {NULL, NULL, NULL},{roardsp_clip_calc8, NULL, NULL},{roardsp_clip_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_clip_calc32, NULL, NULL}}}, {ROARDSP_FILTER_DOWNMIX, "downmix", roardsp_quantify_init, NULL, roardsp_downmix_ctl, roardsp_downmix_reset, { {NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, roardsp_downmix_calc162},{NULL, NULL, NULL},{NULL, NULL, NULL}}}, {ROARDSP_FILTER_DCBLOCK, "DCBlock", roardsp_dcblock_init, NULL, NULL, roardsp_dcblock_reset, { {NULL, NULL, NULL},{NULL, NULL, NULL},{roardsp_dcblock_calc16, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL}}}, {ROARDSP_FILTER_SWAP, "Swap", roardsp_swap_init, roardsp_swap_uninit, roardsp_swap_ctl, roardsp_swap_reset, { {NULL, NULL, NULL},{NULL, NULL, roardsp_swap_calc82},{NULL, NULL, roardsp_swap_calc162}, {NULL, NULL, NULL},{NULL, NULL, roardsp_swap_calc322}}}, {ROARDSP_FILTER_AGC, "AGC", roardsp_agc_init, roardsp_agc_uninit, roardsp_agc_ctl, roardsp_agc_reset, { {NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL}}}, #ifdef ROAR_HAVE_SPEEX_FILTER {ROARDSP_FILTER_SPEEX_PREP, "SpeexPrep", roardsp_speex_prep_init, roardsp_speex_prep_uninit, roardsp_speex_prep_ctl, roardsp_speex_prep_reset, { {NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, roardsp_speex_prep_calc161, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL}}}, #endif #ifdef ROAR_HAVE_LIBM {ROARDSP_FILTER_RESPONSE_CURVE, "ResponseCurve", roardsp_responsecurve_init, roardsp_responsecurve_uninit, roardsp_responsecurve_ctl, roardsp_responsecurve_reset, { {NULL, NULL, NULL},{roardsp_responsecurve_calc8, NULL, NULL},{roardsp_responsecurve_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_responsecurve_calc32, NULL, NULL} }}, {ROARDSP_FILTER_GOERTZEL, "Goertzel", roardsp_goertzel_init, roardsp_goertzel_uninit, roardsp_goertzel_ctl, roardsp_goertzel_reset, { {NULL, NULL, NULL},{roardsp_goertzel_calc8, NULL, NULL},{roardsp_goertzel_calc16, NULL, NULL}, {NULL, NULL, NULL},{roardsp_goertzel_calc32, NULL, NULL} }}, #endif {-1, NULL, NULL, NULL, NULL, NULL, { // ? 8Bit 16Bit 24Bit 32Bit // 0B:n 1 2 1B:n 1 2 2B:n 1 2 3B:n 1 2 4B:n 1 2 {NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL},{NULL, NULL, NULL}}} }; int roardsp_filter_str2id(const char * str) { struct _roardsp_filterlist * l = _roardsp_filterlist; while ( l->id != -1 ) { if ( strcasecmp(l->name, str) == 0 ) return l->id; l++; } roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roardsp_filter_id2str(const int id) { struct _roardsp_filterlist * l = _roardsp_filterlist; while ( l->id != -1 ) { if ( l->id == id ) return l->name; l++; } roar_err_set(ROAR_ERROR_NOENT); return NULL; } int roardsp_filter_new (struct roardsp_filter ** filter, struct roar_stream * stream, int id) { struct roardsp_filter * n; int ret; int error; if ( filter == NULL || stream == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } *filter = NULL; // just to be sure n = roar_mm_malloc(sizeof(struct roardsp_filter)); if ( n == NULL ) return -1; if ( (ret = roardsp_filter_init(n, stream, id)) == -1 ) { error = roar_error; roar_mm_free(n); roar_err_set(error); return -1; } n->flags |= ROARDSP_FFLAG_FREE; *filter = n; return ret; } int roardsp_filter_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct _roardsp_filterlist * l = _roardsp_filterlist; int bytes; int (*calc)(struct roardsp_filter * filter, void * data, size_t samples) = NULL; if ( filter == NULL || stream == NULL ) { ROAR_DBG("roardsp_filter_init(*) = -1 // filter or stream is NULL"); roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( id < 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } ROAR_DBG("roardsp_filter_init(filter=%p, stream=%p, id=%i) = ?", filter, stream, id); memset(filter, 0, sizeof(struct roardsp_filter)); filter->channels = stream->info.channels; filter->bits = stream->info.bits; filter->rate = stream->info.rate; bytes = stream->info.bits / 8; while ( l->id != id ) { if ( l->id == -1 ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } l++; } filter->uninit = l->uninit; filter->ctl = l->ctl; filter->reset = l->reset; ROAR_DBG("roardsp_filter_init(filter=%p, stream=%p, id=%i): bytes=%i", filter, stream, id, bytes); if ( filter->channels < 3 ) calc = l->calc[bytes][filter->channels]; if ( calc == NULL ) calc = l->calc[bytes][0]; // for n channels if ( calc == NULL ) { ROAR_DBG("roardsp_filter_init(*) = -1 // no calc code"); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } filter->calc = calc; if ( l->init != NULL ) { ROAR_DBG("roardsp_filter_init(*) = ? // execing init"); return l->init(filter, stream, id); } ROAR_DBG("roardsp_filter_init(*) = 0 // no init"); return 0; } int roardsp_filter_uninit(struct roardsp_filter * filter) { int ret = 0; if ( filter == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( filter->uninit != NULL ) ret = filter->uninit(filter); if ( filter->flags & ROARDSP_FFLAG_FREE ) { roar_mm_free(filter); } else { memset(filter, 0, sizeof(struct roardsp_filter)); } return ret; } int roardsp_filter_calc (struct roardsp_filter * filter, void * data, size_t len) { int ret = 0; if ( filter == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( data == NULL && len != 0 ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( filter->calc != NULL ) ret = filter->calc(filter, data, len); return ret; } int roardsp_filter_ctl (struct roardsp_filter * filter, int cmd, void * data) { if ( filter == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( filter->ctl != NULL ) return filter->ctl(filter, cmd, data); roar_err_set(ROAR_ERROR_NOSYS); return -1; } int roardsp_filter_reset (struct roardsp_filter * filter, int what) { if ( filter == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( filter->reset != NULL ) return filter->reset(filter, what); roar_err_set(ROAR_ERROR_NOSYS); return -1; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_add.c���������������������������������������������������������0000644�0001750�0001750�00000003361�12264733560�017074� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_add.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #define _calcX(bits) \ int roardsp_add_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_amp * self = (struct roardsp_amp *) filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ size_t i; \ \ for (i = 0; i < samples; i++) { \ samp[i] += self->mul / self->div; \ }; \ \ return 0; \ } _calcX(8) _calcX(16) _calcX(32) int roardsp_add_reset (struct roardsp_filter * filter, int what) { struct roardsp_amp * self; if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; self = filter->inst; switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: self->mul = 0; self->div = 1; return 0; break; default: return -1; } return -1; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_agc.c���������������������������������������������������������0000644�0001750�0001750�00000004560�12264733560�017100� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_agc.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_agc_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_agc * self = roar_mm_malloc(sizeof(struct roardsp_agc)); (void)id; if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_agc)); if ( roardsp_filter_new(&(self->amp), stream, ROARDSP_FILTER_AMP) == -1 ) { roar_mm_free(self); return -1; } filter->inst = (void*) self; if ( roardsp_filter_reset(filter, ROARDSP_RESET_FULL) == -1 ) { roardsp_agc_uninit(filter); return -1; } return 0; } int roardsp_agc_uninit (struct roardsp_filter * filter) { struct roardsp_agc * self = filter->inst; roardsp_filter_free(self->amp); roar_mm_free(self); return 0; } int roardsp_agc_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_agc * self = filter->inst; (void)self; return -1; } int roardsp_agc_reset (struct roardsp_filter * filter, int what) { struct roardsp_agc * self = filter->inst; switch (what) { case ROARDSP_RESET_NONE: return 0; break; case ROARDSP_RESET_FULL: if ( filter->bits < 4 ) return -1; self->target_amp = 1 << (filter->bits - 3); if ( roardsp_filter_reset(self->amp, ROARDSP_RESET_FULL) == -1 ) return -1; return -1; break; case ROARDSP_RESET_STATE: if ( roardsp_filter_reset(self->amp, ROARDSP_RESET_STATE) == -1 ) return -1; return -1; break; default: return -1; } return 0; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_amp.c���������������������������������������������������������0000644�0001750�0001750�00000005337�12264733560�017126� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_amp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_amp_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_amp * self = roar_mm_malloc(sizeof(struct roardsp_amp)); (void)stream, (void)id; if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_amp)); filter->inst = (void*) self; roardsp_filter_reset(filter, ROARDSP_RESET_FULL); return 0; } int roardsp_amp_uninit(struct roardsp_filter * filter) { roar_mm_free(filter->inst); return 0; } #define _calcX(bits,twobits) \ int roardsp_amp_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_amp * self = (struct roardsp_amp *) filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ register int##twobits##_t s; \ size_t i; \ \ for (i = 0; i < samples; i++) { \ s = samp[i]; \ s *= self->mul; \ s /= self->div; \ samp[i] = s; \ }; \ \ return 0; \ } _calcX(8,16) _calcX(16,32) _calcX(32,64) int roardsp_amp_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_amp * self = (struct roardsp_amp *) filter->inst; int32_t old; if ( cmd == ROARDSP_FCTL_MUL ) { old = self->div; self->mul = *(int32_t*)data; *(int32_t*)data = old; } else if ( cmd == ROARDSP_FCTL_DIV ) { old = self->div; self->div = *(int32_t*)data; *(int32_t*)data = old; } else { return -1; } return 0; } int roardsp_amp_reset (struct roardsp_filter * filter, int what) { struct roardsp_amp * self; if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; self = filter->inst; switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: self->mul = 1; self->div = 1; return 0; break; default: return -1; } return -1; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_clip.c��������������������������������������������������������0000644�0001750�0001750�00000007426�12264733561�017302� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_clip.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_clip_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { (void)stream, (void)id; if ( (filter->inst = roar_mm_malloc(sizeof(struct roardsp_clip))) == NULL ) return -1; return roardsp_filter_reset(filter, ROARDSP_RESET_FULL); } int roardsp_clip_uninit(struct roardsp_filter * filter) { roar_mm_free(filter->inst); return 0; } #define _clipX(bits) \ static inline int##bits##_t _clip##bits (int##bits##_t s, struct roardsp_clip * self) { \ switch (self->mode) { \ case ROARDSP_CLIP_MODE_LIMIT: \ return s > 0 ? self->limit : -self->limit; \ break; \ case ROARDSP_CLIP_MODE_ZERO: \ return 0; \ break; \ case ROARDSP_CLIP_MODE_WARP: \ if ( s > 0 ) { \ return s - 2*self->limit; \ } else { \ return s + 2*self->limit; \ } \ break; \ case ROARDSP_CLIP_MODE_NOISE: \ return (s > 0 ? 1 : -1) * (self->limit - (roar_random_uint16() & 0xFF)); \ break; \ } \ \ ROAR_WARN("_clip16(s=%i, self=%p{.mode=%i, ...}) = 0 // ERROR: Bad mode", (int)s, self, (int)self->mode); \ return 0; \ } #define _calcX(bits) \ int roardsp_clip_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_clip * self = filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ register int32_t s = self->limit; \ size_t i; \ \ for (i = 0; i < samples; i++) { \ if ( samp[i] > s ) { \ samp[i] = _clip##bits (samp[i], self); \ } else if ( -samp[i] > s ) { \ samp[i] = _clip##bits (samp[i], self); \ } \ } \ \ ROAR_DBG("roardsp_quantify_calc16(*) = 0"); \ return 0; \ } #define _setX(bits) \ _clipX(bits) \ _calcX(bits) _setX(8) _setX(16) _setX(32) int roardsp_clip_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_clip * self = filter->inst; int32_t old; switch (cmd) { case ROARDSP_FCTL_LIMIT: old = self->limit; self->limit = labs(*(int32_t*)data); *(int32_t*)data = old; break; case ROARDSP_FCTL_MODE: old = self->mode; self->mode = *(int32_t*)data; *(int32_t*)data = old; break; default: ROAR_DBG("roardsp_clip_ctl(*) = -1"); return -1; break; } ROAR_DBG("roardsp_clip_ctl(*) = 0"); return 0; } int roardsp_clip_reset (struct roardsp_filter * filter, int what) { int32_t mode = ROARDSP_CLIP_MODE_LIMIT; int32_t n; if ( filter == NULL ) return -1; switch (filter->bits) { case 8: n = 64L; break; case 16: n = 16384L; break; case 32: n = 1073741824L; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: roardsp_clip_ctl(filter, ROARDSP_FCTL_LIMIT, &n); roardsp_clip_ctl(filter, ROARDSP_FCTL_MODE, &mode); return 0; break; default: return -1; } return -1; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_dcblock.c�����������������������������������������������������0000644�0001750�0001750�00000006410�12264733561�017744� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_dcblock.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_dcblock_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_dcblock * inst = roar_mm_malloc(sizeof(struct roardsp_dcblock)); // roardsp_downmix_ctl(filter, ROARDSP_FCTL_MODE, &mode); (void)stream, (void)id; if ( inst == NULL ) { ROAR_ERR("roardsp_dcblock_init(*): Can not alloc memory for filter dcblock: %s", strerror(errno)); filter->inst = NULL; return -1; } memset(inst, 0, sizeof(struct roardsp_dcblock)); filter->inst = inst; return 0; } int roardsp_dcblock_uninit (struct roardsp_filter * filter) { if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; roar_mm_free(filter->inst); return 0; } int roardsp_dcblock_reset (struct roardsp_filter * filter, int what) { if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; ROAR_DBG("roardsp_dcblock_reset(filter=%p, what=%i) = ?", filter, what); switch (what) { case ROARDSP_RESET_NONE: return 0; break; case ROARDSP_RESET_FULL: memset(filter->inst, 0, sizeof(struct roardsp_dcblock)); return 0; break; case ROARDSP_RESET_STATE: memset(((struct roardsp_dcblock*)filter->inst)->dc, 0, sizeof(int32_t)*ROARDSP_DCBLOCK_NUMBLOCKS); ((struct roardsp_dcblock*)filter->inst)->cur = 0; return 0; break; default: return -1; } return -1; } int roardsp_dcblock_calc16 (struct roardsp_filter * filter, void * data, size_t samples) { struct roardsp_dcblock * inst = filter->inst; int16_t * samp = (int16_t *) data; register int64_t s = 0; size_t i; for (i = 0; i < samples; i++) { // ROAR_WARN("roardsp_dcblock_calc16(*): s=%i, samp[i=%i]=%i", s, i, samp[i]); s += samp[i]; } ROAR_DBG("roardsp_dcblock_calc16(*): s=%li (current block of %lu samples)", (long int)s, (unsigned long int)samples); s = (float)(s / samples); ROAR_DBG("roardsp_dcblock_calc16(*): inst=%p, inst->cur=%i", inst, inst->cur); inst->dc[(inst->cur)++] = s; if ( inst->cur == ROARDSP_DCBLOCK_NUMBLOCKS ) inst->cur = 0; s = 0; for (i = 0; i < ROARDSP_DCBLOCK_NUMBLOCKS; i++) s += inst->dc[i]; s /= ROARDSP_DCBLOCK_NUMBLOCKS; // s += (ROAR_INSTINT)filter->inst; ROAR_DBG("roardsp_dcblock_calc16(*): new DC value: %li", (long int)s); for (i = 0; i < samples; i++) samp[i] -= s; ROAR_DBG("roardsp_downmix_calc16(*) = 0"); return 0; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_downmix.c�����������������������������������������������������0000644�0001750�0001750�00000006202�12264733561�020027� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_downmix.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_downmix_calc162 (struct roardsp_filter * filter, void * data, size_t samples) { int16_t * samp = (int16_t *) data; register int32_t mode = (ROAR_INSTINT)filter->inst; register union { // int16_t i16; int32_t i32; int64_t i64; } s; size_t i; ROAR_DBG("roardsp_downmix_calc162(*): mode=%i", mode); switch (mode) { case ROARDSP_DOWNMIX_LEFT: for (i = 0; i < samples; i += 2) samp[i+1] = samp[i]; break; case ROARDSP_DOWNMIX_RIGHT: for (i = 0; i < samples; i += 2) samp[i] = samp[i+1]; break; case ROARDSP_DOWNMIX_ARITHMETIC: for (i = 0; i < samples; i += 2) { s.i32 = (samp[i] + samp[i+1])/2; samp[i ] = s.i32; samp[i+1] = s.i32; } break; case ROARDSP_DOWNMIX_ARITHMETIC_INVERSE: for (i = 0; i < samples; i += 2) { s.i32 = (float)(samp[i] + samp[i+1])/2.1; samp[i ] = s.i32; samp[i+1] = -s.i32; } break; #ifdef ROAR_HAVE_LIBM case ROARDSP_DOWNMIX_RMS: for (i = 0; i < samples; i += 2) { s.i64 = (int64_t)samp[i]*samp[i] + (int64_t)samp[i+1]*samp[i+1]; #ifdef ROAR_HAVE_SQRTL s.i64 = sqrtl((long double)s.i64/2.0); #else s.i64 = sqrt((double)s.i64/2.0); #endif // s.i64 /= 2; if ( (samp[i] + samp[i+1]) < 0 ) s.i64 *= -1; samp[i ] = s.i64; samp[i+1] = s.i64; } break; #endif default: ROAR_DBG("roardsp_downmix_calc162(*) = -1 // unknown mode"); return -1; break; } ROAR_DBG("roardsp_downmix_calc162(*) = 0"); return 0; } int roardsp_downmix_ctl (struct roardsp_filter * filter, int cmd, void * data) { int32_t old; if ( cmd == ROARDSP_FCTL_MODE ) { old = (ROAR_INSTINT)filter->inst; filter->inst = (void*)(ROAR_INSTINT)*(int32_t*)data; *(int32_t*)data = old; } else { return -1; } return 0; } int roardsp_downmix_reset (struct roardsp_filter * filter, int what) { int32_t mode = ROARDSP_DOWNMIX_ARITHMETIC; if ( filter == NULL ) return -1; switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: roardsp_downmix_ctl(filter, ROARDSP_FCTL_MODE, &mode); return 0; break; default: return -1; } return -1; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_goertzel.c����������������������������������������������������0000644�0001750�0001750�00000010225�12264733562�020176� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_goertzel.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBM #define DEFAULT_FREQ 1000.0 struct roardsp_goertzel { float freq; int32_t coeff; int32_t old[ROAR_MAX_CHANNELS][2]; }; int roardsp_goertzel_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_goertzel * self = roar_mm_malloc(sizeof(struct roardsp_goertzel)); (void)stream, (void)id; if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_goertzel)); filter->inst = (void*) self; roardsp_goertzel_reset(filter, ROARDSP_RESET_FULL); return 0; } int roardsp_goertzel_uninit(struct roardsp_filter * filter) { roar_mm_free(filter->inst); return 0; } #define _calcX(bits,twobits,limit) \ int roardsp_goertzel_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_goertzel * self = (struct roardsp_goertzel *) filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ /*register int##twobits##_t s, g, h;*/ \ register float s, g, h; \ /*register int64_t s, g, h;*/ \ int channel; \ size_t i; \ \ roardsp_goertzel_reset(filter, ROARDSP_RESET_STATE); \ \ for (i = 0, channel = 0; i < samples; i++, channel = channel == (filter->channels - 1) ? 0 : channel + 1) { \ g = self->old[channel][0]; \ g *= self->coeff; \ g /= 32767; \ s = samp[i]; \ ROAR_DBG("roardsp_goertzel_calc*(*): channel=%i, g=%f, s=%f, old[0]=%li, old[1]=%li", channel, g, s, (long int)self->old[channel][0], (long int)self->old[channel][1]); \ s += g; \ s -= self->old[channel][1]; \ self->old[channel][1] = self->old[channel][0]; \ self->old[channel][0] = s; \ /* samp[i] = s; */ \ g = s; \ g *= self->old[channel][1]; \ g *= self->coeff; \ g /= 32767; \ h = self->old[channel][1]; \ h *= self->old[channel][1]; \ s *= s; \ s += h; \ s -= g; \ s *= 0.0001; \ s /= (float)((i+1)*(i+1)); \ if ( s > (limit) ) \ s = (limit); \ samp[i] = s; \ } \ \ return 0; \ } _calcX(8,16,127.) _calcX(16,32,32767.) _calcX(32,64,2147483647.) int roardsp_goertzel_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_goertzel * self = (struct roardsp_goertzel *) filter->inst; float old; switch (cmd) { case ROARDSP_FCTL_FREQ: old = self->freq; self->freq = *(float*)data; *(float*)data = old; old = 2.*cos(2.*M_PI*self->freq/(float)filter->rate); self->coeff = old*32767.; ROAR_DBG("roardsp_goertzel_ctl(filter=%p, cmd=%i, data=%p): self->coeff=%li (%f)", filter, cmd, data, (long int)self->coeff, old); break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } return 0; } int roardsp_goertzel_reset (struct roardsp_filter * filter, int what) { struct roardsp_goertzel * self; float freq; if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; self = filter->inst; switch (what) { case ROARDSP_RESET_NONE: return 0; break; case ROARDSP_RESET_FULL: freq = self->freq = DEFAULT_FREQ; roardsp_goertzel_ctl(filter, ROARDSP_FCTL_FREQ, &freq); case ROARDSP_RESET_STATE: memset(self->old, 0, sizeof(self->old)); return 0; break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } return -1; } #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_highp.c�������������������������������������������������������0000644�0001750�0001750�00000007447�12264733562�017456� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_highp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBM int roardsp_highp_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_highp * self = roar_mm_malloc(sizeof(struct roardsp_highp)); (void)stream, (void)id; if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_highp)); filter->inst = (void*) self; return roardsp_filter_reset(filter, ROARDSP_RESET_FULL); } int roardsp_highp_uninit(struct roardsp_filter * filter) { roar_mm_free(filter->inst); return 0; } #define _calcX(bits,twobits) \ int roardsp_highp_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_highp * self = (struct roardsp_highp *) filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ register int##twobits##_t s, h; \ size_t i, c; \ size_t channels = filter->channels; \ \ if ( channels > ROAR_MAX_CHANNELS ) \ return -1; \ \ samples /= channels; \ \ ROAR_DBG("roardsp_highp_calc16(*): filtering %i frames of %i channels...", samples, channels); \ \ /* * output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1] */ \ \ \ for (i = 0; i < samples; i++) { \ for (c = 0; c < channels; c++) { \ h = samp[i*channels + c]; \ s = (int##twobits##_t)samp[i*channels + c] * self->a + (int##twobits##_t)self->oldin[c] * self->b + (int##twobits##_t)self->oldout[c] * self->c; \ \ s /= 65536; \ \ self->oldin[ c] = h; \ samp[i*channels + c] = s; \ self->oldout[ c] = s; \ } \ } \ \ return 0; \ } _calcX(8,32) /* we need 32 bit not 16 bit here as we multiplay with 65536 internally */ _calcX(16,32) _calcX(32,64) int roardsp_highp_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_highp * self = (struct roardsp_highp *) filter->inst; float lp; float oldfreq; float newfreq; if ( cmd != ROARDSP_FCTL_FREQ ) return -1; newfreq = *(float*)data; lp = exp(-2.0 * M_PI * newfreq / (float) filter->rate) * 65536.; self->a = (65536 + lp)/2.0; self->b = -(65536 + lp)/2.0; self->c = lp; oldfreq = self->freq / 1000; self->freq = newfreq * 1000; *(float*)data = oldfreq; ROAR_DBG("roardsp_highp_ctl(*): oldfreq=%f, newfreq=%f", oldfreq, newfreq); ROAR_DBG("roardsp_highp_ctl(*): a=%i, b=%i, c=%i", self->a, self->b, self->c); return 0; } int roardsp_highp_reset (struct roardsp_filter * filter, int what) { struct roardsp_highp * self; float freq = 25.; if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; self = filter->inst; switch (what) { case ROARDSP_RESET_NONE: return 0; break; case ROARDSP_RESET_FULL: roardsp_highp_ctl(filter, ROARDSP_FCTL_FREQ, &freq); case ROARDSP_RESET_STATE: memset(self->oldin, 0, sizeof(int32_t)*ROAR_MAX_CHANNELS); memset(self->oldout, 0, sizeof(int32_t)*ROAR_MAX_CHANNELS); return 0; break; default: return -1; } return -1; } #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_lowp.c��������������������������������������������������������0000644�0001750�0001750�00000007100�12264733563�017323� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_lowp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBM int roardsp_lowp_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_lowp * self = roar_mm_malloc(sizeof(struct roardsp_lowp)); (void)stream, (void)id; ROAR_DBG("roardsp_lowp_init(*): self=%p", self); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_lowp)); filter->inst = (void*) self; return roardsp_filter_reset(filter, ROARDSP_RESET_FULL); } int roardsp_lowp_uninit(struct roardsp_filter * filter) { roar_mm_free(filter->inst); return 0; } #define _calcX(bits,twobits) \ int roardsp_lowp_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_lowp * self = (struct roardsp_lowp *) filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ register int##twobits##_t s; \ size_t i, c; \ size_t channels = filter->channels; \ \ if ( channels > ROAR_MAX_CHANNELS ) \ return -1; \ \ samples /= channels; \ \ ROAR_DBG("roardsp_lowp_calc16(*): filtering %i frames of %i channels...", samples, channels); \ \ /* * output[N] = input[N] * A + output[N-1] * B */ \ \ for (i = 0; i < samples; i++) { \ for (c = 0; c < channels; c++) { \ s = (int##twobits##_t)samp[i*channels + c] * self->a + (int##twobits##_t)self->old[c] * self->b; \ \ s /= 65536; \ \ samp[i*channels + c] = s; \ self->old[ c] = s; \ } \ } \ \ return 0; \ } _calcX(8,32) /* we need 32 bit not 16 bit here as we multiplay with 65536 internally */ _calcX(16,32) _calcX(32,64) int roardsp_lowp_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_lowp * self = (struct roardsp_lowp *) filter->inst; float lp; float oldfreq; float newfreq; if ( cmd != ROARDSP_FCTL_FREQ ) { roar_err_set(ROAR_ERROR_BADRQC); return -1; } newfreq = *(float*)data; lp = exp(-2.0 * M_PI * newfreq / (float) filter->rate) * 65536.; self->b = lp; self->a = 65536. - lp; oldfreq = self->freq / 1000.; self->freq = newfreq * 1000.; *(float*)data = oldfreq; ROAR_DBG("roardsp_lowp_ctl(*): oldfreq=%f, newfreq=%f", oldfreq, newfreq); return 0; } int roardsp_lowp_reset (struct roardsp_filter * filter, int what) { struct roardsp_lowp * self; float freq; if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; self = filter->inst; freq = filter->rate/2.45; switch (what) { case ROARDSP_RESET_NONE: return 0; break; case ROARDSP_RESET_FULL: roardsp_lowp_ctl(filter, ROARDSP_FCTL_FREQ, &freq); case ROARDSP_RESET_STATE: memset(self->old, 0, sizeof(int32_t)*ROAR_MAX_CHANNELS); return 0; break; default: return -1; } return -1; } #endif //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_quantify.c����������������������������������������������������0000644�0001750�0001750�00000005177�12264733563�020216� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_quantify.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_quantify_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { (void)stream, (void)id; roardsp_filter_reset(filter, ROARDSP_RESET_FULL); return 0; } static inline int16_t _calc(int16_t val, void * inst) { register float s = val; s /= 32768; s *= (ROAR_INSTINT)inst; s = (int16_t)s; s /= (ROAR_INSTINT)inst; s *= 32768; return s; } #define _calcX(bits,rshift,lshift,ibits) \ /* this code is buggy for 8 bit filters */ \ int roardsp_quantify_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ int##bits##_t * samp = (int##bits##_t *) data; \ size_t i; \ \ for (i = 0; i < samples; i++) { \ samp[i] = (int##ibits##_t)_calc((int##ibits##_t)samp[i] rshift, filter->inst) lshift; \ } \ \ ROAR_DBG("roardsp_quantify_calc%i(*) = 0", bits); \ return 0; \ } /* look at our nice parameters ;) */ _calcX(8,<< 8,>> 8,16) _calcX(16,,,16) _calcX(32,>> 16,<< 16,32) int roardsp_quantify_ctl (struct roardsp_filter * filter, int cmd, void * data) { int32_t old; if ( cmd == ROARDSP_FCTL_N ) { old = (ROAR_INSTINT)filter->inst; filter->inst = (void*)(ROAR_INSTINT)*(int32_t*)data; *(int32_t*)data = old; } else { ROAR_DBG("roardsp_quantify_ctl(*) = -1"); return -1; } ROAR_DBG("roardsp_quantify_ctl(*) = 0"); return 0; } int roardsp_quantify_reset (struct roardsp_filter * filter, int what) { int n = 64; if ( filter == NULL ) return -1; switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: roardsp_quantify_ctl(filter, ROARDSP_FCTL_N, &n); return 0; break; default: return -1; } return -1; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_responsecurve.c�����������������������������������������������0000644�0001750�0001750�00000011367�12264733564�021260� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_amp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBM int roardsp_responsecurve_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_responsecurve * self = roar_mm_malloc(sizeof(struct roardsp_responsecurve)); (void)stream, (void)id; ROAR_DBG("roardsp_responsecurve_init(filter=%p, stream=%p, id=%i) = ?", filter, stream, id); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_responsecurve)); filter->inst = (void*) self; roardsp_filter_reset(filter, ROARDSP_RESET_FULL); return 0; } int roardsp_responsecurve_uninit(struct roardsp_filter * filter) { roar_mm_free(filter->inst); return 0; } static double __func_pass(double i, double N) { (void)N; return i; } static double __func_linear(double i, double N) { return -pow(1. - i, N + 1.) + 1.; } static double __func_ilinear(double i, double N) { return pow(i, N + 1.); } static double __func_sin(double i, double N) { return pow(sin(M_PI_2 * i), N); } static double __func_isin(double i, double N) { return 1. - pow(sin((1. - i) * M_PI_2), N); } static double __func_cos(double i, double N) { (void)N; return 0.5 - cos(i * M_PI)/2.; } static double __func_icos(double i, double N) { (void)N; return 2.*i - 0.5 + cos(i * M_PI)/2.; } static inline double _oddify(double x, double N, double (*func)(double, double)) { if ( x < 0. ) { return -func(0. - x, N); } else { return func(x, N); } } static inline double _calc(double x, struct roardsp_responsecurve * self, double N) { double (*func)(double, double) = NULL; enum roardsp_responsecurve_mode mode; if ( x > 0. ) { mode = self->mode_pos; } else { mode = self->mode_neg; } switch (mode) { case ROARDSP_RESPONSECURVE_MODE_PASS: func = __func_pass; break; case ROARDSP_RESPONSECURVE_MODE_LIN: func = __func_linear; break; case ROARDSP_RESPONSECURVE_MODE_ILIN: func = __func_ilinear; break; case ROARDSP_RESPONSECURVE_MODE_SIN: func = __func_sin; break; case ROARDSP_RESPONSECURVE_MODE_ISIN: func = __func_isin; break; case ROARDSP_RESPONSECURVE_MODE_COS: func = __func_cos; break; case ROARDSP_RESPONSECURVE_MODE_ICOS: func = __func_icos; break; default: func = __func_linear; break; } return _oddify(x, N, func); } #define _calcX(bits,fact) \ int roardsp_responsecurve_calc##bits (struct roardsp_filter * filter, void * data, size_t samples) { \ struct roardsp_responsecurve * self = (struct roardsp_responsecurve *) filter->inst; \ int##bits##_t * samp = (int##bits##_t *) data; \ register double s; \ size_t i; \ \ for (i = 0; i < samples; i++) { \ s = samp[i]; \ s /= (double)(fact); \ s = _calc(s, self, self->N); \ s *= (double)(fact); \ samp[i] = s; \ }; \ \ return 0; \ } _calcX(8,128.) _calcX(16,32768.) _calcX(32,2147483648.) int roardsp_responsecurve_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_responsecurve * self = (struct roardsp_responsecurve *) filter->inst; int32_t old; if ( cmd == ROARDSP_FCTL_N ) { old = self->N; self->N = *(int32_t*)data; *(int32_t*)data = old; } else if ( cmd == ROARDSP_FCTL_MODE ) { old = self->mode_pos; self->mode_pos = *(int32_t*)data; *(int32_t*)data = old; } else if ( cmd == ROARDSP_FCTL_Q ) { old = self->mode_neg; self->mode_neg = *(int32_t*)data; *(int32_t*)data = old; } else { return -1; } return 0; } int roardsp_responsecurve_reset (struct roardsp_filter * filter, int what) { struct roardsp_responsecurve * self; if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; self = filter->inst; switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: self->mode_pos = self->mode_neg = ROARDSP_RESPONSECURVE_MODE_LIN; self->N = 1; return 0; break; default: return -1; } return -1; } #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_speex_prep.c��������������������������������������������������0000644�0001750�0001750�00000011455�12264733564�020525� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_speex_prep.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef _SPEEX_TYPES_H #if defined(ROAR_HAVE_LIBSPEEX) && !defined(ROAR_HAVE_LIBSPEEXDSP) #define _SPEEX_API_OLD #define _SPEEX_INT int #elif defined(ROAR_HAVE_LIBSPEEX) && defined(ROAR_HAVE_LIBSPEEXDSP) #define _SPEEX_API_NEW #define _SPEEX_INT spx_int32_t #endif #define _on 1 #define _off 2 #define _CBVM(opt) (ROARDSP_SPEEX_PREP_CBV((opt), ROARDSP_SPEEX_PREP_MASK)) // TODO: check parameters we allready know: int roardsp_speex_prep_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_speex_prep * self; if ( filter->channels != 1 ) return -1; if ( filter->bits != 16 ) return -1; self = roar_mm_malloc(sizeof(struct roardsp_speex_prep)); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roardsp_speex_prep)); filter->inst = self; return 0; } int roardsp_speex_prep_uninit (struct roardsp_filter * filter) { struct roardsp_speex_prep * self = filter->inst; if ( self->preprocess != NULL ) speex_preprocess_state_destroy(self->preprocess); roar_mm_free(self); return 0; } int roardsp_speex_prep_calc161(struct roardsp_filter * filter, void * data, size_t samples) { struct roardsp_speex_prep * self = filter->inst; if ( self->preprocess == NULL ) return -1; if ( samples != ((self->frame_size * filter->bits) / 8) ) return -1; #ifdef _SPEEX_API_OLD speex_preprocess(self->preprocess, data, NULL); #elif defined(_SPEEX_API_NEW) speex_preprocess_run(self->preprocess, data); #else return -1; #endif return 0; } int roardsp_speex_prep_ctl (struct roardsp_filter * filter, int cmd, void * data) { struct roardsp_speex_prep * self = filter->inst; union { size_t size; int32_t i32; } * val = data; _SPEEX_INT si; switch (cmd) { case ROARDSP_FCTL_MODE: if ( self->preprocess == NULL ) return -1; ROAR_DBG("roardsp_speex_prep_ctl(*): val->i32 = 0x%.8x", val->i32); ROAR_DBG("roardsp_speex_prep_ctl(*): _CBVM(ROARDSP_SPEEX_PREP_DENOISE) = 0x%.8x", _CBVM(ROARDSP_SPEEX_PREP_DENOISE)); if ( val->i32 & _CBVM(ROARDSP_SPEEX_PREP_DENOISE) ) { ROAR_DBG("roardsp_speex_prep_ctl(*): ROARDSP_SPEEX_PREP_CTB(ROARDSP_SPEEX_PREP_DENOISE, val->i32) = 0x%.8x", ROARDSP_SPEEX_PREP_CTB(ROARDSP_SPEEX_PREP_DENOISE, val->i32)); switch (ROARDSP_SPEEX_PREP_CTB(ROARDSP_SPEEX_PREP_DENOISE, val->i32)) { case ROARDSP_SPEEX_PREP_ON: si = _on; break; case ROARDSP_SPEEX_PREP_OFF: si = _off; break; default: return -1; } speex_preprocess_ctl(self->preprocess, SPEEX_PREPROCESS_SET_DENOISE, &si); val->i32 -= val->i32 & _CBVM(ROARDSP_SPEEX_PREP_DENOISE); } if ( val->i32 & _CBVM(ROARDSP_SPEEX_PREP_AGC) ) { switch (ROARDSP_SPEEX_PREP_CTB(ROARDSP_SPEEX_PREP_DENOISE, val->i32)) { case ROARDSP_SPEEX_PREP_ON: si = _on; break; case ROARDSP_SPEEX_PREP_OFF: si = _off; break; default: return -1; } speex_preprocess_ctl(self->preprocess, SPEEX_PREPROCESS_SET_AGC, &si); val->i32 -= val->i32 & _CBVM(ROARDSP_SPEEX_PREP_AGC); } if ( val->i32 & _CBVM(ROARDSP_SPEEX_PREP_VAD) ) { switch (ROARDSP_SPEEX_PREP_CTB(ROARDSP_SPEEX_PREP_DENOISE, val->i32)) { case ROARDSP_SPEEX_PREP_ON: si = _on; break; case ROARDSP_SPEEX_PREP_OFF: si = _off; break; default: return -1; } speex_preprocess_ctl(self->preprocess, SPEEX_PREPROCESS_SET_VAD, &si); val->i32 -= val->i32 & _CBVM(ROARDSP_SPEEX_PREP_VAD); } // any other options left? error: if ( val->i32 ) return -1; return 0; break; case ROARDSP_FCTL_PACKET_SIZE: self->frame_size = val->size; self->preprocess = speex_preprocess_state_init(self->frame_size, filter->rate); if ( self->preprocess == NULL ) return -1; return 0; break; } return -1; } int roardsp_speex_prep_reset (struct roardsp_filter * filter, int what) { if ( what == ROARDSP_RESET_NONE ) return 0; return -1; } #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filter_swap.c��������������������������������������������������������0000644�0001750�0001750�00000005365�12264733565�017331� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filter_swap.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_swap_init (struct roardsp_filter * filter, struct roar_stream * stream, int id) { struct roardsp_swap * inst = roar_mm_malloc(sizeof(struct roardsp_swap)); (void)stream, (void)id; ROAR_DBG("roardsp_swap_init(*): inst=%p", inst); if ( inst == NULL ) { ROAR_ERR("roardsp_swap_init(*): Can not alloc memory for filter swap: %s", strerror(errno)); filter->inst = NULL; return -1; } filter->inst = inst; return roardsp_swap_reset(filter, ROARDSP_RESET_FULL); } int roardsp_swap_uninit (struct roardsp_filter * filter) { if ( filter == NULL ) return -1; if ( filter->inst == NULL ) return -1; roar_mm_free(filter->inst); return 0; } #define _calcX2(bits) \ int roardsp_swap_calc##bits##2(struct roardsp_filter * filter, void * data, size_t samples) { \ int##bits##_t * d = data; \ register int##bits##_t s; \ size_t i; \ \ (void)filter; \ \ for (i = 0; i < samples; i += 2) { \ ROAR_DBG("roardsp_swap_calc*2(*): d[i]=%i, d[i+1]=%i", d[i], d[i+1]); \ s = d[i]; \ d[i] = d[i+1]; \ d[i+1] = s; \ } \ \ return 0; \ } _calcX2(8) _calcX2(16) _calcX2(32) int roardsp_swap_ctl (struct roardsp_filter * filter, int cmd, void * data) { (void)filter, (void)cmd, (void)data; roar_err_set(ROAR_ERROR_NOSYS); return -1; } int roardsp_swap_reset (struct roardsp_filter * filter, int what) { struct roardsp_swap * inst = NULL; int i; if ( filter == NULL ) return -1; if ( (inst = filter->inst) == NULL ) return -1; switch (what) { case ROARDSP_RESET_NONE: case ROARDSP_RESET_STATE: return 0; break; case ROARDSP_RESET_FULL: memset(inst, 0, sizeof(struct roardsp_swap)); for (i = 0; i < ROAR_MAX_CHANNELS; i++) inst->map[i] = i; inst->map[0] = 1; inst->map[1] = 0; return 0; break; default: return -1; } return -1; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/filterchain.c��������������������������������������������������������0000644�0001750�0001750�00000005162�12264733565�017275� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//filterchain.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roardsp_fchain_init (struct roardsp_filterchain * chain) { if ( chain == NULL ) return -1; memset((void*)chain, 0, sizeof(struct roardsp_filterchain)); return 0; } int roardsp_fchain_uninit(struct roardsp_filterchain * chain) { int i; int ret = 0; if ( chain == NULL ) return -1; for (i = 0; i < chain->filters; i++) { if ( roardsp_filter_uninit(chain->filter[i]) == -1 ) ret = -1; } if ( roardsp_fchain_init(chain) == -1 ) ret = -1; return ret; } int roardsp_fchain_add (struct roardsp_filterchain * chain, struct roardsp_filter * filter) { if ( chain == NULL ) return -1; if ( chain->filters < ROARDSP_MAX_FILTERS_PER_CHAIN ) { chain->filter[chain->filters++] = filter; return 0; } return -1; } int roardsp_fchain_calc (struct roardsp_filterchain * chain, void * data, size_t len) { int i; int ret = 0; if ( chain == NULL ) return -1; for (i = 0; i < chain->filters; i++) { if ( roardsp_filter_calc(chain->filter[i], data, len) == -1 ) ret = -1; } return ret; } int roardsp_fchain_reset (struct roardsp_filterchain * chain, int what) { int i; int ret = 0; /* struct roardsp_filterchain backup[1]; */ if ( chain == NULL ) return -1; /* if ( what == ROARDSP_RESET_FULL ) { if ( roardsp_fchain_init(backup) == -1 ) return -1; if ( roardsp_fchain_uninit(chain) == -1 ) return -1; if ( roardsp_fchain_init(chain) == -1 ) return -1; } else { */ for (i = 0; i < chain->filters; i++) { if ( roardsp_filter_reset(chain->filter[i], what) == -1 ) ret = -1; } /* } */ return ret; } int roardsp_fchain_num (struct roardsp_filterchain * chain) { if ( chain == NULL ) return -1; return chain->filters; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/float.c��������������������������������������������������������������0000644�0001750�0001750�00000006451�12264733565�016114� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//float.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "libroardsp.h" static inline float _si32_to_float (int32_t src) { if ( src > 0 ) { return (float)src / 2147483647.f; } else { return (float)src / 2147483648.f; } } static inline int32_t _float_to_si32 (float src) { if ( src > 0 ) { return (src * 2147483647.f); } else { return (src * 2147483648.f); } } int roar_conv_int32_float(float * dst, const int32_t * src, size_t len) { size_t i; if ( len == 0 ) return 0; if ( dst == NULL || src == NULL ) return -1; for (i = 0; i < len; i++) dst[i] = _si32_to_float(src[i]); return 0; } int roar_conv_float_int32(int32_t * dst, const float * src, size_t len) { size_t i; if ( len == 0 ) return 0; if ( dst == NULL || src == NULL ) return -1; for (i = 0; i < len; i++) dst[i] = _float_to_si32(src[i]); return 0; } int roar_conv_int32_float_deint(float ** dst, const int32_t * src, size_t len, size_t channels) { register size_t i, c, o; ROAR_DBG("roar_conv_int32_float_deint(*) = ?"); if ( len == 0 ) return 0; ROAR_DBG("roar_conv_int32_float_deint(*) = ?"); if ( dst == NULL || src == NULL ) return -1; ROAR_DBG("roar_conv_int32_float_deint(*) = ?"); // check if len is a multiple of channels: if ( (len % channels) != 0 ) return -1; ROAR_DBG("roar_conv_int32_float_deint(*) = ?"); for (c = 0; c < channels; c++) if ( dst[c] == NULL ) return -1; ROAR_DBG("roar_conv_int32_float_deint(*) = ?"); switch (channels) { case 1: return roar_conv_int32_float(dst[0], src, len); break; case 2: for (i = o = 0; i < len; i += 2, o += 1) { dst[0][o] = _si32_to_float(src[i+0]); dst[1][o] = _si32_to_float(src[i+1]); } break; default: for (i = c = o = 0; i < len; i++) { dst[c][o] = _si32_to_float(src[i]); c++; if ( c == channels ) { c = 0; o++; } } break; } return 0; } int roar_conv_float_int32_enint(int32_t * dst, const float ** src, size_t len, size_t channels) { size_t i, c, o; if ( len == 0 ) return 0; if ( dst == NULL || src == NULL ) return -1; // check if len is a multiple of channels: if ( (len % channels) != 0 ) return -1; for (c = 0; c < channels; c++) if ( src[c] == NULL ) return -1; switch (channels) { default: for (i = c = o = 0; o < len; o++) { dst[o] = _float_to_si32(src[c][i]); c++; if ( c == channels ) { c = 0; i++; } } break; } return 0; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/interleave.c���������������������������������������������������������0000644�0001750�0001750�00000006237�12264733565�017147� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//interleave.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roar_interl_init (struct roar_interleave * state, size_t channels, size_t bits) { if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } // we can currently only hanle full bytes: if ( bits % 8 ) return -1; // currently we have a channel limit if ( channels > ROAR_INTERLEAVE_MAX_CHANNELS ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } memset(state, 0, sizeof(struct roar_interleave)); state->channels = channels; state->bits = bits; return 0; } int roar_interl_uninit(struct roar_interleave * state) { if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } memset(state, 0, sizeof(struct roar_interleave)); return 0; } int roar_interl_ctl (struct roar_interleave * state, int cmd, void * data) { if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } (void)state, (void)cmd, (void)data; roar_err_set(ROAR_ERROR_NOSYS); return -1; } int roar_interl_encode_ext(struct roar_interleave * state, void ** in, void * out, size_t len) { size_t chan = 0; size_t oc; size_t bc = 0; // bit counter char * ip[ROAR_INTERLEAVE_MAX_CHANNELS]; // output pointer if ( state == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( in == NULL || out == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( len == 0 ) return 0; memcpy(ip, in, sizeof(void*)*state->channels); for (oc = 0; oc < len; oc++) { ((char*)out)[oc] = *(ip[chan]); ip[chan]++; bc += 8; if ( bc == state->bits ) { bc = 0; chan++; if ( chan == state->channels ) chan = 0; } } return -1; } int roar_interl_decode_ext(struct roar_interleave * state, void * in, void ** out, size_t len) { size_t chan = 0; size_t ic; // input counter size_t bc = 0; // bit counter char * op[ROAR_INTERLEAVE_MAX_CHANNELS]; // output pointer if ( state == NULL ) return -1; if ( in == NULL || out == NULL ) return -1; if ( len == 0 ) return 0; memcpy(op, out, sizeof(void*)*state->channels); for (ic = 0; ic < len; ic++) { // get char and copy it *(op[chan]) = ((char*)in)[ic]; op[chan]++; bc += 8; if ( bc == state->bits ) { bc = 0; chan++; if ( chan == state->channels ) chan = 0; } } return -1; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/libroardsp.c���������������������������������������������������������0000644�0001750�0001750�00000001706�12264733566�017147� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroardsp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" //ll ����������������������������������������������������������roaraudio-1.0beta11/libroardsp/midi.c���������������������������������������������������������������0000644�0001750�0001750�00000012401�12264733566�015722� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//midi.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" struct { uint16_t id; unsigned char midiid; float freq; char * name; } _libroar_notes[] = { {ROAR_MIDI_NOTE_C , 60, 261.625565, "C" }, {ROAR_MIDI_NOTE_Cs, 61, 277.182631, "C#"}, {ROAR_MIDI_NOTE_D , 62, 293.664768, "D" }, {ROAR_MIDI_NOTE_Ds, 63, 311.126984, "D#"}, {ROAR_MIDI_NOTE_E , 64, 329.627557, "E" }, {ROAR_MIDI_NOTE_F , 65, 349.228231, "F" }, {ROAR_MIDI_NOTE_Fs, 66, 369.994423, "F#"}, {ROAR_MIDI_NOTE_G , 67, 391.995436, "G" }, {ROAR_MIDI_NOTE_Gs, 68, 415.304698, "G#"}, {ROAR_MIDI_NOTE_A , 69, 440.000000, "A" }, {ROAR_MIDI_NOTE_As, 70, 466.163762, "A#"}, {ROAR_MIDI_NOTE_B , 71, 493.883301, "B" }, {0, 0, 0, NULL} }; char * roar_midi_note2name (uint16_t note) { int i; for (i = 0; _libroar_notes[i].name != NULL; i++) if ( _libroar_notes[i].id == note ) return _libroar_notes[i].name; return NULL; } uint16_t roar_midi_name2note (char * note) { int i; for (i = 0; _libroar_notes[i].name != NULL; i++) if ( strcasecmp(_libroar_notes[i].name, note) == 0 ) return _libroar_notes[i].id; return ROAR_MIDI_NOTE_NONE; } uint16_t roar_midi_midi2note (unsigned char midiid) { int i; for (i = 0; _libroar_notes[i].name != NULL; i++) if ( _libroar_notes[i].midiid == midiid ) return _libroar_notes[i].id; return ROAR_MIDI_NOTE_NONE; } float roar_midi_note2freq (uint16_t note) { int i; for (i = 0; _libroar_notes[i].name != NULL; i++) if ( _libroar_notes[i].id == note ) return _libroar_notes[i].freq; return -1; } int roar_midi_note_from_midiid(struct roar_note_octave * note, unsigned char midiid) { int oct; if ( note == NULL || midiid > 127 ) return -1; memset(note, 0, sizeof(struct roar_note_octave)); note->octave = ((int) midiid/12) - 5; note->note = roar_midi_midi2note((midiid % 12) + 60); oct = 1 << abs(note->octave); note->freq = roar_midi_note2freq(note->note); if ( note->octave < 0 ) { note->freq /= oct; } else { note->freq *= oct; } return 0; } int roar_midi_find_octave (char * note); int roar_midi_add_octave (struct roar_note_octave * note) { note->name[0] = 0; return -1; } int roar_midi_notefill (struct roar_note_octave * note) { int oct; if ( !note ) return -1; if ( note->note && note->name[0] == 0 ) { roar_midi_add_octave(note); } else if ( !note->note && note->name[0] != 0 ) { return -1; } oct = 1 << abs(note->octave); note->freq = roar_midi_note2freq(note->note); // TODO: fix this: freq is freq*2^octave if ( note->octave < 0 ) { note->freq /= oct; } else { note->freq *= oct; } return 0; } int roar_midi_gen_tone (struct roar_note_octave * note, int16_t * samples, float t, int rate, int channels, int type, void * opts) { #ifdef ROAR_HAVE_LIBM int i, c; float ct; float step = 1.0/rate; int16_t s; float (*op)(float x) = NULL; /* rate: 1/s t : 1s freq: 1/s rew : 1s */ if ( type == ROAR_MIDI_TYPE_SINE ) { op = sinf; } else { return -1; } if ( op == NULL ) return -1; ROAR_DBG("roar_midi_gen_tone(*): t=%f", t); for (ct = 0, i = 0; ct <= t; ct += step, i += channels) { s = 32767*op(2.0*M_PI*note->freq*ct); // ROAR_DBG("roar_midi_gen_tone(*): t=%f, ct=%f, i=%i", t, ct, i); for (c = 0; c < channels; c++) samples[i+c] = s; } ROAR_DBG("roar_midi_gen_tone(*): t=%f, ct=%f, i=%i", t, ct, i); return 0; #else return -1; #endif } int roar_midi_play_note (struct roar_stream * stream, struct roar_note_octave * note, float len) { return -1; } int roar_midi_basic_init (struct roar_midi_basic_state * state) { if (!state) return -1; state->len.mul = 1; state->len.div = 60; state->note.note = ROAR_MIDI_NOTE_NONE; state->note.octave = 0; return 0; } int roar_midi_basic_play (struct roar_stream * stream, struct roar_midi_basic_state * state, char * notes) { struct roar_midi_basic_state is; #if 0 char cn[ROAR_MIDI_MAX_NOTENAME_LEN+1] = {0}; int i; #endif int have = 0; struct roar_note_octave * n; if ( !notes ) return -1; if ( state == NULL ) { state = &is; roar_midi_basic_init(state); } n = &(state->note); for (; *notes != 0; notes++) { if ( *notes == '>' ) { n->octave++; } else if ( *notes == '<' ) { n->octave--; } else if ( *notes != ' ' ) { have++; } if (have) { roar_midi_play_note(stream, n, 60 * state->len.mul / state->len.div); have = 0; } } return 0; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/midside.c������������������������������������������������������������0000644�0001750�0001750�00000005451�12264733566�016425� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//midside.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roar_conv_s2ms_8 (void * out, void * in, int samples) { char * ip = in; char * op = out; register int i; register char mid; register char side; for (i = 0; i < samples; i += 2) { mid = (ip[i] + ip[i+1])/2; side = (ip[i] - ip[i+1])/2; op[i ] = mid; op[i+1] = side; } return 0; } int roar_conv_s2ms_16 (void * out, void * in, int samples) { int16_t * ip = in; int16_t * op = out; register int i; register int16_t mid; register int16_t side; for (i = 0; i < samples; i += 2) { mid = (ip[i] + ip[i+1])/2; side = (ip[i] - ip[i+1])/2; op[i ] = mid; op[i+1] = side; } return 0; } int roar_conv_s2ms_32 (void * out, void * in, int samples) { int32_t * ip = in; int32_t * op = out; register int i; register int32_t mid; register int32_t side; for (i = 0; i < samples; i += 2) { mid = (ip[i] + ip[i+1])/2; side = (ip[i] - ip[i+1])/2; op[i ] = mid; op[i+1] = side; } return 0; } int roar_conv_ms2s_8 (void * out, void * in, int samples) { char * ip = in; char * op = out; register int i; register char mid; register char side; for (i = 0; i < samples; i += 2) { mid = ip[i]; side = ip[i+1]; op[i ] = mid + side; op[i+1] = mid - side; } return 0; } int roar_conv_ms2s_16 (void * out, void * in, int samples) { int16_t * ip = in; int16_t * op = out; register int i; register int16_t mid; register int16_t side; for (i = 0; i < samples; i += 2) { mid = ip[i]; side = ip[i+1]; op[i ] = mid + side; op[i+1] = mid - side; } return 0; } int roar_conv_ms2s_32 (void * out, void * in, int samples) { int32_t * ip = in; int32_t * op = out; register int i; register int32_t mid; register int32_t side; for (i = 0; i < samples; i += 2) { mid = ip[i]; side = ip[i+1]; op[i ] = mid + side; op[i+1] = mid - side; } return 0; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/mixer.c��������������������������������������������������������������0000644�0001750�0001750�00000004700�12264733566�016127� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//mixer.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roar_mix_pcm (void * output, int bits, void ** input, int samples) { switch (bits) { case 8: return roar_mix_pcm_8bit (output, (int8_t **)input, samples); break; case 16: return roar_mix_pcm_16bit(output, (int16_t **)input, samples); break; case 32: return roar_mix_pcm_32bit(output, (int32_t **)input, samples); break; default: return -1; } } int roar_mix_pcm_8bit (int8_t * output, int8_t ** input, int samples) { int i, s; register int c; for (s = 0; s < samples; s++) { c = 0; for (i = 0; input[i] != NULL; i++) c += input[i][s]; if ( c > 127 ) c = 127; else if ( c < -128 ) c = -128; output[s] = (char)c; } return 0; } int roar_mix_pcm_16bit (int16_t * output, int16_t ** input, int samples) { int i, s; register int_least32_t c; #ifdef DEBUG for (i = 0; input[i] != NULL; i++) ROAR_DBG("mix_clients_16bit(*): input[%i] = %p", i, input[i]); #endif for (s = 0; s < samples; s++) { c = 0; for (i = 0; input[i] != NULL; i++) { c += input[i][s]; } if ( c > 32767 ) c = 32767; else if ( c < -32768 ) c = -32768; output[s] = c; } return 0; } int roar_mix_pcm_32bit (int32_t * output, int32_t ** input, int samples) { #ifdef ROAR_NATIVE_INT64 int i, s; ROAR_NATIVE_INT64 c; for (s = 0; s < samples; s++) { c = 0; for (i = 0; input[i]; i++) c += input[i][s]; if ( c > 21474836487LL ) c = 2147483647LL; else if ( c < -2147483648LL ) c = -2147483648LL; output[s] = (int32_t)c; } return 0; #else return -1; #endif } //ll ����������������������������������������������������������������roaraudio-1.0beta11/libroardsp/mulaw.c��������������������������������������������������������������0000644�0001750�0001750�00000322426�12264733566�016140� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//mulaw.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* * In addition to the above copyright statement codec marked with * '-------- SUN --------' is under the following license as it is extracted * from SoX 12.17.9: * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #include "libroardsp.h" #ifdef ROAR_SUPPORT_MULAW static const int16_t _roardsp_mulaw2pcm16[] = { /* -------- SUN -------- */ -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 /* -------- /SUN -------- */ }; #ifdef ROAR_SUPPORT_MULAW_RW static const int8_t _roardsp_pcm142mulaw[] = { /* -------- SUN -------- */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6, 0xf5, 0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf2, 0xf1, 0xf1, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 /* -------- /SUN -------- */ }; #endif #endif int roardsp_conv_mulaw2pcm16 (int16_t * out, char * in, size_t len) { #ifdef ROAR_SUPPORT_MULAW unsigned char * inp = (unsigned char *) in; ssize_t i; for (i = len-1; i > -1; i--) { out[i] = _roardsp_mulaw2pcm16[inp[i]]; } return 0; #else return -1; #endif } int roardsp_conv_pcm162mulaw (char * out, int16_t * in, size_t len) { #ifdef ROAR_SUPPORT_MULAW_RW unsigned int i; for (i = 0; i < len; i++) { out[i] = _roardsp_pcm142mulaw[(in[i] + 32768) >> 2]; } return 0; #else return -1; #endif } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/poly.c���������������������������������������������������������������0000644�0001750�0001750�00000010031�12264733566�015760� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//poly.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroardsp.h" int roar_math_mkpoly (float * poly, float * data, int len) { if ( len == 2 ) return roar_math_mkpoly_2x2(poly, data); if ( len == 3 ) return roar_math_mkpoly_3x3(poly, data); if ( len == 4 ) return roar_math_mkpoly_4x4(poly, data); if ( len == 5 ) return roar_math_mkpoly_5x5(poly, data); return -1; } int roar_math_mkpoly_2x2 (float * poly, float * data) { /* A B 0 1 x 1 1 y B = x A = y - x */ poly[0] = data[0]; poly[1] = data[1] - data[0]; return 0; } int roar_math_mkpoly_3x3 (float * poly, float * data) { /* A B C 0 0 1 x 1 1 1 y 4 2 1 z */ poly[0] = data[0]; poly[1] = 2*data[1] - 2*data[0] - (data[2]-data[0])/2; poly[2] = (data[2]-data[0])/2 - data[1] + data[0]; return 0; } int roar_math_mkpoly_4x4 (float * poly, float * data) { /* a b c d 0 0 0 1 A X 0 1 1 1 1 B Y 1 8 4 2 1 C Z 2 27 9 3 1 D Q 3 */ // { a = -(3z-3y+x-q)/6, b = (4z-5y+2x-q)/2, c = -(9z-18y+11x-2q)/6, d = x }. poly[0] = data[0]; poly[1] = -(11*data[0] - 18*data[1] + 9*data[2] - 2*data[3])/6; poly[2] = (2 *data[0] - 5*data[1] + 4*data[2] - data[3])/2; poly[3] = -( data[0] - 3*data[1] + 3*data[2] - data[3])/6; return 0; } int roar_math_mkpoly_5x5 (float * poly, float * data) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } float roar_math_cvpoly (float * poly, float t, int len) { float ret = 0; float ct = 1; int i; if ( poly == NULL ) return 0; switch (len) { case 4: return roar_math_cvpoly_4x4(poly, t); } for (i = 0; i < len; i++) { ret += poly[i] * ct; ct *= t; } return ret; } float roar_math_cvpoly_4x4 (float * poly, float t) { float ret = poly[0]; float ct = t; ret += poly[1] * ct; ct *= t; ret += poly[2] * ct; ct *= t; ret += poly[3] * ct; // printf("ret=%f\n", ret); return ret; } int roar_math_diffpoly(float * poly, int len) { int i; for (i = 1; i < len; i++) { poly[i-1] = poly[i]*(i+1); } poly[len-1] = 0; return 0; } int roar_math_intpoly(float * poly, int len, float c) { int i; for (i = len; i > 0; i--) { poly[i] = poly[i-1]/i; } poly[0] = c; return 0; } float roar_math_numintpoly(float * poly, int len, float st, float et) { float ipoly[8]; float upper, lower; if (len > 7) { roar_err_set(ROAR_ERROR_RANGE); return -1.; } memcpy(ipoly, poly, sizeof(float)*len); roar_math_intpoly(ipoly, len, 0); // printf("{%f, %f, %f}\n", ipoly[0], ipoly[1], ipoly[2]); lower = roar_math_cvpoly(ipoly, st, len+1); upper = roar_math_cvpoly(ipoly, et, len+1); // printf("lower(%f)=%f, upper(%f)=%f\n", st, lower, et, upper); return upper-lower; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/remove.c�������������������������������������������������������������0000644�0001750�0001750�00000013124�12264733567�016301� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//remove.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roar_remove_init (struct roar_remove_state * state) { if ( state == NULL ) return -1; memset(state, 0, sizeof(struct roar_remove_state)); state->old = 65535; return 0; } int roar_remove (void * inout, void * subs, int samples, int bits, struct roar_remove_state * state) { if ( inout == NULL || subs == NULL || samples < 0 ) return -1; switch (bits) { case 8: return roar_remove_8 (inout, subs, samples, state); break; case 16: return roar_remove_16(inout, subs, samples, state); break; case 32: return roar_remove_32(inout, subs, samples, state); break; } return -1; } int roar_remove_8 (int8_t * inout, int8_t * subs, int samples, struct roar_remove_state * state) { int i; register int_least16_t s; register int_least16_t peak; if ( state == NULL ) { for (i = 0; i < samples; i++) { s = inout[i]; s -= subs[i]; inout[i] = s; } } else { peak = 127; for (i = 0; i < samples; i++) { s = inout[i]; s -= subs[i]; s = s < 0 ? -s : s; // we true 32 bit, not int operation here if ( s > peak ) peak = s; } for (i = 0; i < samples; i++) { s = -subs[i]; s *= 127; s /= peak; s += inout[i]; inout[i] = s; } } return 0; } int roar_remove_16 (int16_t * inout, int16_t * subs, int samples, struct roar_remove_state * state) { int i; register int32_t s; register int32_t peak; if ( state == NULL ) { for (i = 0; i < samples; i++) { s = inout[i]; s -= subs[i]; inout[i] = s; } } else { peak = 65535; for (i = 0; i < samples; i++) { s = inout[i]; s -= subs[i]; s = s < 0 ? -s : s; // we true 32 bit, not int operation here if ( s > peak ) peak = s; } for (i = 0; i < samples; i++) { s = -subs[i]; s *= 65535; s /= peak; s += inout[i]; inout[i] = s; } } return 0; } int roar_remove_32 (int32_t * inout, int32_t * subs, int samples, struct roar_remove_state * state) { int i; register int64_t s; register int64_t peak; if ( state == NULL ) { for (i = 0; i < samples; i++) { s = inout[i]; s -= subs[i]; inout[i] = s; } } else { peak = 4294967295UL; for (i = 0; i < samples; i++) { s = inout[i]; s -= subs[i]; s = s < 0 ? -s : s; // we true 32 bit, not int operation here if ( s > peak ) peak = s; } for (i = 0; i < samples; i++) { s = -subs[i]; s *= 4294967295UL; s /= peak; s += inout[i]; inout[i] = s; } } return 0; } int roar_remove_so (void * subout, void * in, int samples, int bits, struct roar_remove_state * state) { if ( subout == NULL || in == NULL || samples < 0 ) return -1; switch (bits) { case 8: return roar_remove_so8 (subout, in, samples, state); break; case 16: return roar_remove_so16(subout, in, samples, state); break; case 32: return roar_remove_so32(subout, in, samples, state); break; } return -1; } int roar_remove_so8 (int8_t * subout, int8_t * in, int samples, struct roar_remove_state * state) { int i; register int_least16_t s; register int_least16_t peak; if ( state == NULL ) { for (i = 0; i < samples; i++) { s = -subout[i]; s += in[i]; subout[i] = s; } } else { peak = 127; for (i = 0; i < samples; i++) { s = -subout[i]; s += in[i]; s = s < 0 ? -s : s; // we true 32 bit, not int operation here if ( s > peak ) peak = s; } for (i = 0; i < samples; i++) { s = -subout[i]; s *= 127; s /= peak; s += in[i]; subout[i] = s; } } return 0; } int roar_remove_so16 (int16_t * subout, int16_t * in, int samples, struct roar_remove_state * state) { int i; register int32_t s; register int32_t peak; if ( state == NULL ) { for (i = 0; i < samples; i++) { s = -subout[i]; s += in[i]; subout[i] = s; } } else { peak = 65535; for (i = 0; i < samples; i++) { s = -subout[i]; s += in[i]; s = s < 0 ? -s : s; // we true 32 bit, not int operation here if ( s > peak ) peak = s; } for (i = 0; i < samples; i++) { s = -subout[i]; s *= 65535; s /= peak; s += in[i]; subout[i] = s; } } return 0; } int roar_remove_so32 (int32_t * subout, int32_t * in, int samples, struct roar_remove_state * state) { int i; register int64_t s; register int64_t peak; if ( state == NULL ) { for (i = 0; i < samples; i++) { s = -subout[i]; s += in[i]; subout[i] = s; } } else { peak = 2147483647UL; for (i = 0; i < samples; i++) { s = -subout[i]; s += in[i]; s = s < 0 ? -s : s; // we true 32 bit, not int operation here if ( s > peak ) peak = s; } for (i = 0; i < samples; i++) { s = -subout[i]; s *= 2147483647UL; s /= peak; s += in[i]; subout[i] = s; } } return 0; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/resampler_poly3.c����������������������������������������������������0000644�0001750�0001750�00000016326�12264733567�020133� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//resampler_poly3.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroardsp.h" int roar_conv_poly3_8 (int8_t * out, int8_t * in, size_t olen, size_t ilen, int channels) { float ratio = (float)olen / (float)ilen; int8_t *ip; int c, x; float pos_in; float poly[3]; float y[3]; float x_val; int_least16_t temp; /* Can't create poly out of less than 3 samples in each channel. */ if ( ilen < 3 * channels ) return -1; ip = roar_mm_malloc(ilen * sizeof(int8_t)); if ( ip == NULL ) return -1; memcpy(ip, in, ilen * sizeof(int8_t)); olen /= channels; for (x = 0; x < olen; x++) { for (c = 0; c < channels; c++) { pos_in = (float)x / ratio; if ( (int)pos_in == 0 ) { y[0] = ip[0 * channels + c]; y[1] = ip[1 * channels + c]; y[2] = ip[2 * channels + c]; x_val = pos_in; roar_math_mkpoly_3x3(poly, y); } else if ( (int)pos_in + 1 >= ilen/channels ) { /* If we're at the end of the block, we will need to interpolate against a value that is not yet known. * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */ y[0] = ip[((int)pos_in - 1) * channels + c]; y[1] = ip[((int)pos_in ) * channels + c]; // we create a 2x2 poly here and set the 3rd coefficient to zero to build a 3x3 poly roar_math_mkpoly_2x2(poly, y); poly[2] = 0; x_val = pos_in - (int)pos_in + 1.0; } else { y[0] = ip[((int)pos_in - 1) * channels + c]; y[1] = ip[((int)pos_in ) * channels + c]; y[2] = ip[((int)pos_in + 1) * channels + c]; x_val = pos_in - (int)pos_in + 1.0; roar_math_mkpoly_3x3(poly, y); } temp = (float)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5); /* temp could be out of bounds, so need to check this */ if ( temp > 0x7E ) { out[x * channels + c] = 0x7E; } else if (temp < -0x7F) { out[x * channels + c] = -0x7F; } else { out[x * channels + c] = (int8_t)temp; } } } roar_mm_free(ip); return 0; } int roar_conv_poly3_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen, int channels) { float ratio = (float)olen / (float)ilen; int16_t *ip; int c, x; float pos_in; float poly[3]; float y[3]; float x_val; int_least32_t temp; /* Can't create poly out of less than 3 samples in each channel. */ if ( ilen < 3 * channels ) return -1; ip = roar_mm_malloc(ilen * sizeof(int16_t)); if ( ip == NULL ) return -1; memcpy(ip, in, ilen * sizeof(int16_t)); olen /= channels; for (x = 0; x < olen; x++) { for (c = 0; c < channels; c++) { pos_in = (float)x / ratio; if ( (int)pos_in == 0 ) { y[0] = ip[0 * channels + c]; y[1] = ip[1 * channels + c]; y[2] = ip[2 * channels + c]; x_val = pos_in; roar_math_mkpoly_3x3(poly, y); } else if ( (int)pos_in + 1 >= ilen/channels ) { /* If we're at the end of the block, we will need to interpolate against a value that is not yet known. * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */ y[0] = ip[((int)pos_in - 1) * channels + c]; y[1] = ip[((int)pos_in ) * channels + c]; // we create a 2x2 poly here and set the 3rd coefficient to zero to build a 3x3 poly roar_math_mkpoly_2x2(poly, y); poly[2] = 0; x_val = pos_in - (int)pos_in + 1.0; } else { y[0] = ip[((int)pos_in - 1) * channels + c]; y[1] = ip[((int)pos_in ) * channels + c]; y[2] = ip[((int)pos_in + 1) * channels + c]; x_val = pos_in - (int)pos_in + 1.0; roar_math_mkpoly_3x3(poly, y); } temp = (float)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5); /* temp could be out of bounds, so need to check this */ if (temp > 0x7FFE ) { out[x * channels + c] = 0x7FFE; } else if (temp < -0x7FFF) { out[x * channels + c] = -0x7FFF; } else { out[x * channels + c] = (int16_t)temp; } } } roar_mm_free(ip); return 0; } int roar_conv_poly3_32 (int32_t * out, int32_t * in, size_t olen, size_t ilen, int channels) { float ratio = (float)olen / (float)ilen; int32_t *ip; int c, x; float pos_in; float poly[3]; float y[3]; float x_val; int_least64_t temp; /* Can't create poly out of less than 3 samples in each channel. */ if ( ilen < 3 * channels ) return -1; ip = roar_mm_malloc(ilen * sizeof(int32_t)); if ( ip == NULL ) return -1; memcpy(ip, in, ilen * sizeof(int32_t)); olen /= channels; for (x = 0; x < olen; x++) { for (c = 0; c < channels; c++) { pos_in = (float)x / ratio; if ( (int)pos_in == 0 ) { y[0] = ip[0 * channels + c]; y[1] = ip[1 * channels + c]; y[2] = ip[2 * channels + c]; x_val = pos_in; roar_math_mkpoly_3x3(poly, y); } else if ( (int)pos_in + 1 >= ilen/channels ) { /* If we're at the end of the block, we will need to interpolate against a value that is not yet known. * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */ y[0] = ip[((int)pos_in - 1) * channels + c]; y[1] = ip[((int)pos_in ) * channels + c]; // we create a 2x2 poly here and set the 3rd coefficient to zero to build a 3x3 poly roar_math_mkpoly_2x2(poly, y); poly[2] = 0; x_val = pos_in - (int)pos_in + 1.0; } else { y[0] = ip[((int)pos_in - 1) * channels + c]; y[1] = ip[((int)pos_in ) * channels + c]; y[2] = ip[((int)pos_in + 1) * channels + c]; x_val = pos_in - (int)pos_in + 1.0; roar_math_mkpoly_3x3(poly, y); } temp = (float)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5); /* temp could be out of bounds, so need to check this */ if ( temp > 0x7FFFFFFE ) { out[x * channels + c] = 0x7FFFFFFE; } else if (temp < -0x7FFFFFFF) { out[x * channels + c] = -0x7FFFFFFF; } else { out[x * channels + c] = (int32_t)temp; } } } roar_mm_free(ip); return 0; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/rms.c����������������������������������������������������������������0000644�0001750�0001750�00000010176�12264733567�015611� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//rms.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int64_t roar_rms2_1_8 (int8_t * data, size_t samples) { register int64_t s = 0; register size_t i; for (i = 0; i < samples; i++) s += data[i] * data[i]; s /= samples; return s; } int64_t roar_rms2_1_16 (int16_t * data, size_t samples) { register int64_t s = 0; register size_t i; for (i = 0; i < samples; i++) s += data[i] * data[i]; s /= samples; return s; } int64_t roar_rms2_1_32 (int32_t * data, size_t samples) { register int64_t s = 0; register size_t i; for (i = 0; i < samples; i++) s += data[i] * data[i]; s /= samples; return s; } int roar_rms2_1_8_2 (int8_t * data, size_t samples, int64_t * rms) { register int64_t a0 = 0, a1 = 0; register size_t i; if ( samples == 0 ) return 0; if ( data == NULL ) return -1; if ( samples & 0x1 ) /* odd */ return -1; for (i = 0; i < samples; i += 2) { a0 += data[i+0] * data[i+0]; a1 += data[i+1] * data[i+1]; } samples /= 2; a0 /= samples; a1 /= samples; rms[0] = a0; rms[1] = a1; return 0; } int roar_rms2_1_16_2 (int16_t * data, size_t samples, int64_t * rms) { register int64_t a0 = 0, a1 = 0; register size_t i; if ( samples == 0 ) return 0; if ( data == NULL ) return -1; if ( samples & 0x1 ) /* odd */ return -1; for (i = 0; i < samples; i += 2) { a0 += data[i+0] * data[i+0]; a1 += data[i+1] * data[i+1]; } samples /= 2; a0 /= samples; a1 /= samples; rms[0] = a0; rms[1] = a1; return 0; } int roar_rms2_1_32_2 (int32_t * data, size_t samples, int64_t * rms) { register int64_t a0 = 0, a1 = 0; register size_t i; if ( samples == 0 ) return 0; if ( data == NULL ) return -1; if ( samples & 0x1 ) /* odd */ return -1; for (i = 0; i < samples; i += 2) { a0 += data[i+0] * data[i+0]; a1 += data[i+1] * data[i+1]; } samples /= 2; a0 /= samples; a1 /= samples; rms[0] = a0; rms[1] = a1; return 0; } int roar_rms2_1_8_n (int8_t * data, size_t samples, int64_t * rms, size_t n) { if ( n == 0 ) return 0; if ( rms == NULL ) return -1; switch (n) { case 1: return *rms = roar_rms2_1_8(data, samples); return *rms == -1 ? -1 : 0; break; case 2: return roar_rms2_1_8_2(data, samples, rms); break; default: return -1; } } int roar_rms2_1_16_n (int16_t * data, size_t samples, int64_t * rms, size_t n) { if ( n == 0 ) return 0; if ( rms == NULL ) return -1; switch (n) { case 1: return *rms = roar_rms2_1_16(data, samples); return *rms == -1 ? -1 : 0; break; case 2: return roar_rms2_1_16_2(data, samples, rms); break; default: return -1; } } int roar_rms2_1_32_n (int32_t * data, size_t samples, int64_t * rms, size_t n) { if ( n == 0 ) return 0; if ( rms == NULL ) return -1; switch (n) { case 1: return *rms = roar_rms2_1_32(data, samples); return *rms == -1 ? -1 : 0; break; case 2: return roar_rms2_1_32_2(data, samples, rms); break; default: return -1; } } int roar_rms2_1_b_n (void * data, size_t samples, int64_t * rms, size_t n, size_t bits) { switch (bits) { case 8: return roar_rms2_1_8_n(data, samples, rms, n); break; case 16: return roar_rms2_1_16_n(data, samples, rms, n); break; case 32: return roar_rms2_1_32_n(data, samples, rms, n); break; default: return -1; } } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/synth.c��������������������������������������������������������������0000644�0001750�0001750�00000010137�12264733567�016152� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//synth.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #if !defined(ROAR_HAVE_LIBM) && !defined(M_PI) #define M_PI 3.141592 #endif #define _CHECK_BASIC() if ( state == NULL ) return -1 #define _CHECK_PCMOUT() _CHECK_BASIC(); if ( frames == 0 ) return 0; if ( out == NULL ) return -1 int roar_synth_init(struct roar_synth_state * state, struct roar_note_octave * note, int rate) { _CHECK_BASIC(); if ( rate <= 0 ) return -1; memset(state, 0, sizeof(struct roar_synth_state)); state->note = note; // NULL is valid here! state->rate = rate; state->volume = 1; state->func = ROAR_SYNTH_SYNF_DEFAULT; return 0; } int roar_synth_set_offset(struct roar_synth_state * state, size_t offset) { _CHECK_BASIC(); state->pcmoffset = offset; return 0; } int roar_synth_set_func (struct roar_synth_state * state, ROAR_SYNTH_FUNC_TYPE(func)) { _CHECK_BASIC(); if ( func == NULL ) return -1; state->func = func; return 0; } int roar_synth_set_volume(struct roar_synth_state * state, float volume) { _CHECK_BASIC(); state->volume = volume; return 0; } int roar_synth_pcmout_i16n(struct roar_synth_state * state, int16_t * out, size_t frames, int channels) { _CHECK_PCMOUT(); switch (channels) { case 1: return roar_synth_pcmout_i161(state, out, frames); default: return -1; } return 0; } int roar_synth_pcmout_i161(struct roar_synth_state * state, int16_t * out, size_t frames) { float t_step; float t_cur; float freq; #ifdef DEBUG float cv0, cv1; #endif size_t i; _CHECK_PCMOUT(); t_step = 1.0/state->rate; ROAR_DBG("roar_synth_pcmout_i161(*): state->pcmoffset=%lu", (unsigned long)state->pcmoffset); t_cur = (float)state->pcmoffset/(float)state->rate; freq = state->note->freq; ROAR_DBG("roar_synth_pcmout_i161(*): t_cur=%f, freq=%f", t_cur, freq); #ifdef DEBUG cv0 = 2.0*M_PI*freq*t_cur; #endif for (i = 0; i < frames; i++, t_cur += t_step) { out[i] = 32767.0*state->volume*state->func(2.0*M_PI*freq*t_cur, state); } #ifdef DEBUG cv1 = 2.0*M_PI*freq*t_cur; #endif #ifdef DEBUG ROAR_DBG("roar_synth_pcmout_i161(*): cv0=%f, cv1=%f, cv1-cv0=%f", cv0, cv1, cv1-cv0); #endif state->pcmoffset += frames; ROAR_DBG("roar_synth_pcmout_i161(*): state->pcmoffset=%lu", (unsigned long)state->pcmoffset); return 0; } // basic SINFs: float roar_synth_synf_rect (float t, struct roar_synth_state * state) { (void)state; t /= 2*M_PI; t -= (int)t; if ( t < 0.5 ) return 1; else return -1; } float roar_synth_synf_saw (float t, struct roar_synth_state * state) { (void)state; t /= 2*M_PI; t -= (int)t; return 2*t - 1; } float roar_synth_synf_tri (float t, struct roar_synth_state * state) { (void)state; t /= 2*M_PI; t -= (int)t; if ( t < 0.5 ) return 4* t - 1; else return -4*(t-0.5) + 1; } float roar_synth_synf_trap (float t, struct roar_synth_state * state) { (void)state; t /= 2*M_PI; t -= (int)t; if ( t < 0.125 || t > 0.875 ) { return -1; } else if ( t < 0.625 && t > 0.375 ) { return 1; } else if ( t < 0.5 ) { return 8*(t-0.375) + 1; } else { return -8*(t-0.625) + 1; } } #ifdef ROAR_HAVE_LIBM float roar_synth_synf_s2s (float t, struct roar_synth_state * state) { (void)state; float sin2 = sinf(t/1.2); return sin2*sin2 * sin(t*1.2); } #endif //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/transcode.c����������������������������������������������������������0000644�0001750�0001750�00000026646�12264733567�017003� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//transcode.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #define _FUNC(func) (state->entry->func) #define _CHECK_STATE() (!(state == NULL || state->entry == NULL)) #define _CHECK_FUNC(func) (_CHECK_STATE() && _FUNC(func) != NULL) #define _CHECK_BASIC(func) if ( !_CHECK_FUNC(func) ) return -1 #define _CHECK() if ( !_CHECK_STATE() ) return -1 static struct roar_xcoder_entry g_xcoders[] = { {ROAR_CODEC_ALAW, roar_xcoder_dummy_inituninit, roar_xcoder_dummy_inituninit, roar_xcoder_dummy_packet_size_any, roar_xcoder_alaw_encode, roar_xcoder_alaw_decode, roar_xcoder_dummy_proc_header}, {ROAR_CODEC_MULAW, roar_xcoder_dummy_inituninit, roar_xcoder_dummy_inituninit, roar_xcoder_dummy_packet_size_any, roar_xcoder_mulaw_encode, roar_xcoder_mulaw_decode, roar_xcoder_dummy_proc_header}, #ifdef ROAR_HAVE_LIBCELT {ROAR_CODEC_ROAR_CELT, roar_xcoder_celt_init, roar_xcoder_celt_uninit, roar_xcoder_celt_packet_size, roar_xcoder_celt_encode, roar_xcoder_celt_decode, NULL}, #endif #ifdef ROAR_HAVE_LIBSPEEX {ROAR_CODEC_ROAR_SPEEX, roar_xcoder_speex_init, roar_xcoder_speex_uninit, roar_xcoder_speex_packet_size, roar_xcoder_speex_encode, roar_xcoder_speex_decode, roar_xcoder_speex_proc_header}, #endif {-1, NULL, NULL, NULL, NULL, NULL, NULL} }; int roar_xcoder_init(struct roar_xcoder * state, int encoder, struct roar_audio_info * info, struct roar_vio_calls * vio) { int i; if ( state == NULL || info == NULL ) return -1; memset(state, 0, sizeof(struct roar_xcoder)); for (i = 0; g_xcoders[i].codec != -1; i++) { if ( g_xcoders[i].codec == (int)info->codec ) { state->entry = &(g_xcoders[i]); break; } } if ( state->entry == NULL ) return -1; state->stage = ROAR_XCODER_STAGE_NONE; state->encode = encoder; state->packet_len = -1; if ( roar_xcoder_set_backend(state, vio) == -1 ) return -1; memcpy(&(state->info.coded), info, sizeof(struct roar_audio_info)); memcpy(&(state->info.pcm ), info, sizeof(struct roar_audio_info)); state->info.pcm.codec = ROAR_CODEC_DEFAULT; if ( _FUNC(init) == NULL ) return -1; if ( _FUNC(init)(state) != 0 ) return -1; state->stage = ROAR_XCODER_STAGE_INITED; return 0; } int roar_xcoder_set_backend(struct roar_xcoder * state, struct roar_vio_calls * vio) { _CHECK(); if ( vio == NULL && state->backend != NULL ) return -1; state->backend = vio; return 0; } int roar_xcoder_packet_size(struct roar_xcoder * state, int samples) { _CHECK_BASIC(packet_size); state->packet_len = state->entry->packet_size(state, samples); if ( state->packet_len == 0 ) { if ( samples < 1 ) { return ROAR_RATE_DEFAULT/100; } else { return samples; } } return state->packet_len; } int roar_xcoder_close (struct roar_xcoder * state) { _CHECK_BASIC(uninit); if ( state->iobuffer != NULL ) { roar_xcoder_proc(state, NULL, 0); // try to flush roar_buffer_free(state->iobuffer); } return _FUNC(uninit)(state); } int roar_xcoder_proc_header(struct roar_xcoder * state) { _CHECK_BASIC(proc_header); return _FUNC(proc_header)(state); } int roar_xcoder_proc_packet(struct roar_xcoder * state, void * buf, size_t len) { _CHECK(); ROAR_DBG("roar_xcoder_proc_packet(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( state->backend == NULL ) return -1; if ( state->packet_len > 0 && state->packet_len != (ssize_t)len ) return -1; ROAR_DBG("roar_xcoder_proc_packet(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( state->encode ) { _CHECK_BASIC(encode); ROAR_DBG("roar_xcoder_proc_packet(state=%p, buf=%p, len=%lu) = ? // _CHECK_BASIC(encode) -> OK", state, buf, (unsigned long)len); return _FUNC(encode)(state, buf, len); } else { _CHECK_BASIC(decode); ROAR_DBG("roar_xcoder_proc_packet(state=%p, buf=%p, len=%lu) = ? // _CHECK_BASIC(decode) -> OK", state, buf, (unsigned long)len); return _FUNC(decode)(state, buf, len); } } int roar_xcoder_proc (struct roar_xcoder * state, void * buf, size_t len) { struct roar_buffer_stats ringstats; struct roar_buffer * bufbuf; void * bufdata; size_t curlen; ROAR_DBG("roar_xcoder_proc(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( state == NULL ) return -1; if ( buf == NULL && len != 0 ) return -1; if ( state->packet_len == -1 ) if ( roar_xcoder_packet_size(state, -1) == -1 ) return -1; ROAR_DBG("roar_xcoder_proc(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( state->packet_len == 0 ) return roar_xcoder_proc_packet(state, buf, len); ROAR_DBG("roar_xcoder_proc(state=%p, buf=%p, len=%lu): state->packet_len=%li", state, buf, (unsigned long)len, (long int) state->packet_len); if ( state->iobuffer == NULL ) { while ( (ssize_t)len >= state->packet_len ) { if ( roar_xcoder_proc_packet(state, buf, state->packet_len) == -1 ) { ROAR_DBG("roar_xcoder_proc(state=%p, buf=%p, len=%lu) = -1 // roar_xcoder_proc_packet() error", state, buf, (unsigned long)len); return -1; } buf += state->packet_len; len -= state->packet_len; } if ( !len ) { ROAR_DBG("roar_xcoder_proc(state=%p, buf=%p, len=%lu) = 0", state, buf, (unsigned long)len); return 0; } ROAR_DBG("roar_xcoder_proc(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( state->encode ) { curlen = len; } else { curlen = state->packet_len; } if ( roar_buffer_new_data(&bufbuf, curlen, &bufdata) == -1 ) return -1; if ( state->encode ) { memcpy(bufdata, buf, len); } else { if ( roar_xcoder_proc_packet(state, bufdata, state->packet_len) == -1 ) { roar_buffer_free(bufbuf); return -1; } curlen = len; if ( roar_buffer_shift_out(&bufbuf, buf, &curlen) == -1 ) { roar_buffer_free(bufbuf); return -1; } if ( curlen < len ) { // this should never happen! roar_buffer_free(bufbuf); return -1; } } state->iobuffer = bufbuf; } else { if ( state->encode ) { if ( roar_buffer_new_data(&bufbuf, len, &bufdata) == -1 ) return -1; memcpy(bufdata, buf, len); if ( roar_buffer_moveinto(state->iobuffer, &bufbuf) == -1 ) { roar_buffer_free(bufbuf); return -1; } if ( roar_buffer_ring_stats(state->iobuffer, &ringstats) == -1 ) return -1; if ( roar_buffer_new_data(&bufbuf, state->packet_len, &bufdata) == -1 ) return -1; while ( (ssize_t)ringstats.bytes > state->packet_len ) { curlen = state->packet_len; if ( roar_buffer_shift_out(&(state->iobuffer), bufdata, &curlen) == -1 ) { roar_buffer_free(bufbuf); return -1; } if ( (ssize_t)curlen < state->packet_len ) { // this should not happen... roar_buffer_free(bufbuf); return -1; } if ( roar_xcoder_proc_packet(state, bufdata, state->packet_len) == -1 ) { roar_buffer_free(bufbuf); return -1; } if ( roar_buffer_ring_stats(state->iobuffer, &ringstats) == -1 ) { roar_buffer_free(bufbuf); return -1; } } if ( roar_buffer_free(bufbuf) == -1 ) return -1; } else { curlen = len; if ( roar_buffer_shift_out(&(state->iobuffer), buf, &curlen) == -1 ) { return -1; } if ( curlen == len ) return -1; // we now have curlen < len and state->iobuffer == NULL // as no data is left in the buffer, need to get some new data. // we simply call ourself to get some more data... if ( state->iobuffer == NULL ) { ROAR_WARN("roar_xcoder_proc(state=%p, buf=%p, len=%lu): iobuffer != NULL, " "This is a bug in libroar{dsp,} or some hardware is broken", state, buf, (unsigned long)len); return -1; } len -= curlen; buf += curlen; return roar_xcoder_proc(state, buf, len); } } return 0; } int roar_bixcoder_init(struct roar_bixcoder * state, struct roar_audio_info * info, struct roar_vio_calls * vio) { if ( state == NULL || info == NULL || vio == NULL ) return -1; memset(state, 0, sizeof(struct roar_bixcoder)); if ( roar_xcoder_init(&(state->encoder), 1, info, vio) == -1 ) return -1; if ( roar_xcoder_init(&(state->decoder), 0, info, vio) == -1 ) { roar_xcoder_close(&(state->encoder)); return -1; } return 0; } int roar_bixcoder_packet_size (struct roar_bixcoder * state, int samples) { int ret; ROAR_DBG("roar_bixcoder_packet_size(state=%p, samples=%i) = ?", state, samples); if ( state == NULL ) return -1; if ( (ret = roar_xcoder_packet_size(&(state->encoder), samples)) == -1 ) return -1; ROAR_DBG("roar_bixcoder_packet_size(state=%p, samples=%i): ret=%i", state, samples, ret); // TODO: we need a lot hope here... /* if ( roar_xcoder_packet_size(&(state->decoder), ret) != ret ) return -1; */ ROAR_DBG("roar_bixcoder_packet_size(state=%p, samples=%i) = %i", state, samples, ret); return ret; } int roar_bixcoder_close (struct roar_bixcoder * state) { int ret = 0; if ( state == NULL ) return -1; ret = roar_xcoder_close(&(state->encoder)); if ( roar_xcoder_close(&(state->decoder)) == -1 ) return -1; return ret; } int roar_bixcoder_read_header (struct roar_bixcoder * state) { if ( state == NULL ) return -1; return roar_xcoder_proc_header(&(state->decoder)); } int roar_bixcoder_read_packet (struct roar_bixcoder * state, void * buf, size_t len) { ROAR_DBG("roar_bixcoder_read_packet(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( state == NULL ) return -1; return roar_xcoder_proc_packet(&(state->decoder), buf, len); } int roar_bixcoder_read (struct roar_bixcoder * state, void * buf, size_t len) { if ( state == NULL ) return -1; return roar_xcoder_proc(&(state->decoder), buf, len); } int roar_bixcoder_write_header(struct roar_bixcoder * state) { if ( state == NULL ) return -1; return roar_xcoder_proc_header(&(state->decoder)); } int roar_bixcoder_write_packet(struct roar_bixcoder * state, void * buf, size_t len) { if ( state == NULL ) return -1; return roar_xcoder_proc_packet(&(state->encoder), buf, len); } int roar_bixcoder_write (struct roar_bixcoder * state, void * buf, size_t len) { if ( state == NULL ) return -1; return roar_xcoder_proc(&(state->encoder), buf, len); } // dummy functions used by some de/encoders: int roar_xcoder_dummy_inituninit(struct roar_xcoder * state) { (void)state; return 0; } int roar_xcoder_dummy_packet_size_any(struct roar_xcoder * state, int samples) { // the case samples=-1/samples!=-1 based things are done in the general func (void)state, (void)samples; return 0; } int roar_xcoder_dummy_proc_header(struct roar_xcoder * state) { (void)state; return 0; } //ll ������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/transcode_celt.c�����������������������������������������������������0000644�0001750�0001750�00000012513�12264733570�017770� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//transcode_celt.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBCELT #define _16BIT (16/8) #define _SIZE_LEN 2 #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 typedef celt_int16 celt_int16_t; #endif int roar_xcoder_celt_init (struct roar_xcoder * state) { struct roar_xcoder_celt * self = roar_mm_malloc(sizeof(struct roar_xcoder_celt)); struct roar_audio_info * info = &(state->info.pcm); if ( self == NULL ) return -1; // curruntly only 16 bit mode is supported if ( info->bits != 16 ) { roar_mm_free(self); return -1; } memset(self, 0, sizeof(struct roar_xcoder_celt)); state->inst = self; self->frame_size = 256; self->bufferlen = info->channels * 32 + _SIZE_LEN; self->iobuffer = roar_mm_malloc(self->bufferlen); if ( self->iobuffer == NULL ) { roar_mm_free(self); return -1; } #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 self->mode = celt_mode_create(info->rate, self->frame_size, NULL); #else self->mode = celt_mode_create(info->rate, info->channels, self->frame_size, NULL); #endif if ( self->mode == NULL ) { roar_mm_free(self->iobuffer); roar_mm_free(self); return -1; } if (state->encode) { #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 self->encoder = celt_encoder_create(self->mode, info->channels, NULL); #else self->encoder = celt_encoder_create(self->mode); #endif if ( self->encoder == NULL ) { roar_xcoder_celt_uninit(state); return -1; } } else { #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 self->decoder = celt_decoder_create(self->mode, info->channels, NULL); #else self->decoder = celt_decoder_create(self->mode); #endif if ( self->decoder == NULL ) { roar_xcoder_celt_uninit(state); return -1; } } ROAR_DBG("roar_xcoder_celt_init(*) = 0"); return 0; } int roar_xcoder_celt_uninit (struct roar_xcoder * state) { struct roar_xcoder_celt * self = state->inst; if ( self->iobuffer ) roar_mm_free(self->iobuffer); if ( self->encoder ) celt_encoder_destroy(self->encoder); if ( self->decoder ) celt_decoder_destroy(self->decoder); if ( self->mode ) celt_mode_destroy(self->mode); roar_mm_free(self); ROAR_DBG("roar_xcoder_celt_uninit(*) = 0"); return 0; } int roar_xcoder_celt_packet_size(struct roar_xcoder * state, int samples) { struct roar_xcoder_celt * self = state->inst; register int ret = self->frame_size * _16BIT * state->info.pcm.channels; ROAR_DBG("roar_xcoder_celt_packet_size(state=%p, samples=%i) = %i", state, samples, ret); return ret; } int roar_xcoder_celt_encode (struct roar_xcoder * state, void * buf, size_t len) { struct roar_xcoder_celt * self = state->inst; uint16_t * lenp = self->iobuffer; void * cp = self->iobuffer + _SIZE_LEN; uint16_t pkglen; ROAR_DBG("roar_xcoder_celt_encode(*): test if we are in encoding mode..."); if (!state->encode) return -1; ROAR_DBG("roar_xcoder_celt_encode(*): Encoding..."); if ( state->stage == ROAR_XCODER_STAGE_INITED ) { if ( roar_vio_write(state->backend, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN ) return -1; state->stage = ROAR_XCODER_STAGE_MAGIC; ROAR_DBG("roar_xcoder_celt_encode(*): Wrote MAGIC"); } pkglen = celt_encode(self->encoder, (celt_int16_t *) buf, NULL, cp, self->bufferlen - _SIZE_LEN); *lenp = ROAR_HOST2NET16(pkglen); if ( roar_vio_write(state->backend, self->iobuffer, pkglen+2) == -1 ) return -1; return 0; } int roar_xcoder_celt_decode (struct roar_xcoder * state, void * buf, size_t len) { struct roar_xcoder_celt * self = state->inst; uint16_t * lenp = self->iobuffer; void * cp = self->iobuffer + _SIZE_LEN; uint16_t pkglen; char magic[ROAR_CELT_MAGIC_LEN]; ROAR_DBG("roar_xcoder_celt_decode(*): test if we are in decoding mode..."); if (state->encode) return -1; if ( state->stage == ROAR_XCODER_STAGE_INITED ) { if ( roar_vio_read(state->backend, magic, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN ) return -1; if ( memcmp(magic, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != 0 ) return -1; state->stage = ROAR_XCODER_STAGE_MAGIC; ROAR_DBG("roar_xcoder_celt_decode(*): Found valid Magic"); } if ( roar_vio_read(state->backend, lenp, _SIZE_LEN) != _SIZE_LEN ) return -1; pkglen = ROAR_NET2HOST16(*lenp); if ( pkglen > (self->bufferlen - _SIZE_LEN) ) return -1; if ( roar_vio_read(state->backend, cp, pkglen) != pkglen ) return -1; if ( celt_decode(self->decoder, cp, pkglen, (celt_int16_t *) buf) < 0 ) return -1; return 0; } #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/transcode_mualaw.c���������������������������������������������������0000644�0001750�0001750�00000006342�12264733570�020332� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//transcode_mualaw.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #define _CHECK() if ( state == NULL || state->info.pcm.bits != 16 || buf == NULL ) return -1 #define _CHECK_BUF(len) \ void * iobuf; \ size_t outbyte = (len)/2; \ _CHECK(); \ if ( (len) & 0x01 ) return -1; \ if ( provide_buffer(&iobuf, outbyte) == -1 ) \ return -1; #define _SEND_RETURN() if ( roar_vio_write(state->backend, iobuf, outbyte) != (ssize_t)outbyte ) \ return -1; \ return 0; #define _READ() if ( roar_vio_read(state->backend, iobuf, outbyte) != (ssize_t)outbyte ) \ return -1; static int provide_buffer(void ** buf, size_t len) { static struct roar_buffer * bufbuf = NULL; size_t buflen; ROAR_DBG("provide_buffer(*) = ?"); if ( bufbuf != NULL ) { if ( roar_buffer_get_len(bufbuf, &buflen) == -1 ) return -1; if ( buflen >= len ) { if ( roar_buffer_get_data(bufbuf, buf) == -1 ) return -1; ROAR_DBG("provide_buffer(*) = 0"); return 0; } else { if ( roar_buffer_free(bufbuf) == -1 ) return -1; bufbuf = NULL; } } if ( roar_buffer_new_data(&bufbuf, len, buf) == -1 ) return -1; ROAR_DBG("provide_buffer(*) = 0"); return 0; } int roar_xcoder_alaw_encode(struct roar_xcoder * state, void * buf, size_t len) { _CHECK_BUF(len); ROAR_DBG("roar_xcoder_alaw_encode(*) = ?"); if ( roardsp_conv_pcm162alaw(iobuf, buf, outbyte) == -1 ) return -1; ROAR_DBG("roar_xcoder_alaw_encode(*) = ?"); _SEND_RETURN(); } int roar_xcoder_alaw_decode(struct roar_xcoder * state, void * buf, size_t len) { _CHECK_BUF(len); _READ(); ROAR_DBG("roar_xcoder_alaw_decode(*): Start decoding.."); if ( roardsp_conv_alaw2pcm16(buf, iobuf, outbyte) == -1 ) return -1; ROAR_DBG("roar_xcoder_alaw_decode(*): Decoding sucessful"); return 0; } int roar_xcoder_mulaw_encode(struct roar_xcoder * state, void * buf, size_t len) { _CHECK_BUF(len); if ( roardsp_conv_pcm162mulaw(iobuf, buf, outbyte) == -1 ) return -1; _SEND_RETURN(); } int roar_xcoder_mulaw_decode(struct roar_xcoder * state, void * buf, size_t len) { _CHECK_BUF(len); _READ(); if ( roardsp_conv_mulaw2pcm16(buf, iobuf, outbyte) == -1 ) return -1; return 0; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/transcode_speex.c����������������������������������������������������0000644�0001750�0001750�00000021435�12264733570�020170� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//transcode_speex.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" #ifdef ROAR_HAVE_LIBSPEEX #define _16BIT (16/8) #define _SIZE_LEN 2 #define _HAVE_CCFG(x) (self->codec_config != NULL && (self->codec_config->para_set & (x))) int roar_xcoder_speex_init (struct roar_xcoder * state) { struct roar_xcoder_speex * self = roar_mm_malloc(sizeof(struct roar_xcoder_speex)); struct roar_audio_info * info = &(state->info.pcm); int tmp; ROAR_DBG("roar_xcoder_speex_init(*): sizeof(*self) = %lu", (unsigned long)sizeof(*self)); if ( self == NULL ) return -1; // curruntly only 16 bit mode is supported if ( info->bits != 16 ) { roar_mm_free(self); return -1; } // only mono/stereo mode is supported switch (info->channels) { case 1: self->stereo = 0; break; case 2: self->stereo = 1; break; default: roar_mm_free(self); return -1; } memset(self, 0, sizeof(struct roar_xcoder_speex)); state->inst = self; self->mode = ROAR_SPEEX_MODE_UWB; if (state->encode) { self->codec_config = roar_libroar_config_codec_get(ROAR_CODEC_ROAR_SPEEX, 0); self->max_cc = ROAR_SPEEX_MAX_CC; ROAR_DBG("roar_xcoder_speex_init(*): self->codec_config=%p", self->codec_config); if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_MAX_CC) ) { self->max_cc = self->codec_config->max_cc; } if ( info->rate < 12000 ) { self->mode = ROAR_SPEEX_MODE_NB; // optimized for 8kHz } else if ( info->rate < 24000 ) { self->mode = ROAR_SPEEX_MODE_WB; // optimized for 16kHz } else { self->mode = ROAR_SPEEX_MODE_UWB; // optimized for 32kHz } if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_MODE) ) { // NB, WB and UWB mode numbers are the same for Speex and codec config. self->mode = self->codec_config->mode; } switch (self->mode) { case ROAR_SPEEX_MODE_NB: self->xcoder = speex_encoder_init(&speex_nb_mode); break; case ROAR_SPEEX_MODE_WB: self->xcoder = speex_encoder_init(&speex_wb_mode); break; case ROAR_SPEEX_MODE_UWB: self->xcoder = speex_encoder_init(&speex_uwb_mode); break; default: return -1; } if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_COMPLEXITY) ) { tmp = self->codec_config->complexity / 256; } else { tmp = 8; } speex_encoder_ctl(self->xcoder, SPEEX_SET_COMPLEXITY, &tmp); if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_Q) ) { tmp = self->codec_config->q / 256; speex_encoder_ctl(self->xcoder, SPEEX_SET_QUALITY, &tmp); } if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_VBR) ) { tmp = self->codec_config->vbr ? 1 : 0; speex_encoder_ctl(self->xcoder, SPEEX_SET_VBR, &tmp); } if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_DTX) ) { tmp = self->codec_config->dtx ? 1 : 0; speex_encoder_ctl(self->xcoder, SPEEX_SET_DTX, &tmp); } tmp = info->rate; speex_encoder_ctl(self->xcoder, SPEEX_SET_SAMPLING_RATE, &tmp); speex_encoder_ctl(self->xcoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size)); } else { self->xcoder = NULL; } speex_bits_init(&(self->bits)); return 0; } int roar_xcoder_speex_uninit (struct roar_xcoder * state) { struct roar_xcoder_speex * self = state->inst; if ( self->xcoder != NULL ) { if (state->encode) { speex_encoder_destroy(self->xcoder); } else { speex_decoder_destroy(self->xcoder); } } speex_bits_destroy(&(self->bits)); roar_mm_free(self); return 0; } int roar_xcoder_speex_packet_size(struct roar_xcoder * state, int samples) { struct roar_xcoder_speex * self = state->inst; if (!state->encode) if (state->stage != ROAR_XCODER_STAGE_OPENED) return -1; return _16BIT * self->frame_size * (self->stereo ? 2 : 1); } int roar_xcoder_speex_proc_header(struct roar_xcoder * state) { struct roar_xcoder_speex * self = state->inst; uint16_t tmp_net; int tmp; SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT; SpeexCallback callback; char magic[ROAR_SPEEX_MAGIC_LEN]; // we do allready open streams not considder an error. if ( state->stage == ROAR_XCODER_STAGE_OPENED ) return 0; // everything else expected an INITED stream (OPENING, MAGIC,..) // is an error... if ( state->stage != ROAR_XCODER_STAGE_INITED ) return -1; if ( state->encode ) { if ( roar_vio_write(state->backend, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN ) return -1; state->stage = ROAR_XCODER_STAGE_MAGIC; ROAR_DBG("roar_xcoder_speex_proc_header(*): Wrote MAGIC"); state->stage = ROAR_XCODER_STAGE_OPENING; tmp_net = ROAR_HOST2NET16(self->mode); if ( roar_vio_write(state->backend, &tmp_net, 2) != 2 ) return -1; state->stage = ROAR_XCODER_STAGE_OPENED; } else { if ( roar_vio_read(state->backend, magic, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN ) return -1; if ( memcmp(magic, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != 0 ) return -1; state->stage = ROAR_XCODER_STAGE_MAGIC; if ( roar_vio_read(state->backend, &tmp_net, 2) != 2 ) return -1; self->mode = ROAR_NET2HOST16(tmp_net); state->stage = ROAR_XCODER_STAGE_OPENING; switch (self->mode) { case ROAR_SPEEX_MODE_NB: self->xcoder = speex_decoder_init(&speex_nb_mode); break; case ROAR_SPEEX_MODE_WB: self->xcoder = speex_decoder_init(&speex_wb_mode); break; case ROAR_SPEEX_MODE_UWB: self->xcoder = speex_decoder_init(&speex_uwb_mode); break; default: return -1; } tmp=1; speex_decoder_ctl(self->xcoder, SPEEX_SET_ENH, &tmp); tmp = state->info.pcm.rate; speex_decoder_ctl(self->xcoder, SPEEX_SET_SAMPLING_RATE, &tmp); speex_decoder_ctl(self->xcoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size)); if ( self->stereo ) { memcpy(&(self->stereo_state), &stereo, sizeof(self->stereo_state)); callback.callback_id = SPEEX_INBAND_STEREO; callback.func = speex_std_stereo_request_handler; callback.data = &(self->stereo_state); speex_decoder_ctl(self->xcoder, SPEEX_SET_HANDLER, &callback); } state->stage = ROAR_XCODER_STAGE_OPENED; } // on no error... return 0; } int roar_xcoder_speex_encode (struct roar_xcoder * state, void * buf, size_t len) { struct roar_xcoder_speex * self = state->inst; int pkg_len; if (!state->encode) return -1; ROAR_DBG("roar_xcoder_speex_encode(*): Encoding..."); if ( state->stage == ROAR_XCODER_STAGE_INITED ) if ( roar_xcoder_speex_proc_header(state) == -1 ) return -1; speex_bits_reset(&(self->bits)); if ( self->stereo ) speex_encode_stereo_int((spx_int16_t *) buf, self->frame_size, &(self->bits)); speex_encode_int(self->xcoder, (spx_int16_t *) buf, &(self->bits)); pkg_len = speex_bits_write(&(self->bits), self->cc + 2, self->max_cc); self->cc[0] = (pkg_len & 0xFF00) >> 8; self->cc[1] = pkg_len & 0x00FF; if ( roar_vio_write(state->backend, self->cc, pkg_len + 2) != (pkg_len + 2) ) return -1; return 0; } // TODO: move all the init thingys into a seperate function int roar_xcoder_speex_decode (struct roar_xcoder * state, void * buf, size_t len) { struct roar_xcoder_speex * self = state->inst; uint16_t tmp_net; int pkg_len; ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( state->stage == ROAR_XCODER_STAGE_INITED ) if ( roar_xcoder_speex_proc_header(state) == -1 ) return -1; ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu): state->stage = %s", state, buf, (unsigned long)len, state->stage == ROAR_XCODER_STAGE_OPENED ? "OPENED" : "???" ); if ( roar_vio_read(state->backend, &tmp_net, 2) != 2 ) return -1; pkg_len = ROAR_NET2HOST16(tmp_net); if ( pkg_len > ROAR_SPEEX_MAX_CC ) return -1; ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu) = ?", state, buf, (unsigned long)len); if ( roar_vio_read(state->backend, self->cc, pkg_len) != pkg_len ) return -1; speex_bits_read_from(&(self->bits), self->cc, pkg_len); speex_decode_int(self->xcoder, &(self->bits), buf); if ( self->stereo ) { speex_decode_stereo_int(buf, self->frame_size, &(self->stereo_state)); } ROAR_DBG("roar_xcoder_speex_decode(state=%p, buf=%p, len=%lu) = 0", state, buf, (unsigned long)len); return 0; } #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroardsp/vio_transcode.c������������������������������������������������������0000644�0001750�0001750�00000010010�12264733570�017624� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//vio_transcode.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroardsp.h" int roar_vio_open_xcode (struct roar_vio_calls * calls, int encoder, struct roar_audio_info * info, struct roar_vio_calls * dst) { struct roar_xcoder * xcoder = roar_mm_malloc(sizeof(struct roar_xcoder)); if ( xcoder == NULL ) return -1; if ( calls == NULL || info == NULL || dst == NULL ) { roar_mm_free(xcoder); return -1; } if ( roar_xcoder_init(xcoder, encoder, info, dst) == -1 ) { roar_mm_free(xcoder); return -1; } memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->inst = (void*)xcoder; calls->close = roar_vio_xcode_close; if ( encoder ) { calls->write = roar_vio_xcode_proc; } else { calls->read = roar_vio_xcode_proc; } return 0; } ssize_t roar_vio_xcode_proc (struct roar_vio_calls * vio, void *buf, size_t count) { #ifdef DEBUG int ret; #endif if ( vio == NULL ) return -1; if ( buf == NULL && count != 0 ) return -1; #ifdef DEBUG ret = roar_xcoder_proc(vio->inst, buf, count); ROAR_DBG("roar_vio_xcode_proc(vio=%p, buf=%p, count=%lu): ret=%i", vio, buf, (unsigned long) count, ret); return !ret ? count : -1; #else return !roar_xcoder_proc(vio->inst, buf, count) ? (ssize_t)count : -1; #endif } int roar_vio_xcode_sync (struct roar_vio_calls * vio); int roar_vio_xcode_close (struct roar_vio_calls * vio) { int ret = 0; if ( vio == NULL ) return -1; if ( roar_xcoder_close(vio->inst) == -1 ) ret = -1; if ( vio->inst != NULL ) roar_mm_free(vio->inst); return ret; } int roar_vio_open_bixcode (struct roar_vio_calls * calls, struct roar_audio_info * info, struct roar_vio_calls * dst) { struct roar_bixcoder * bixcoder = roar_mm_malloc(sizeof(struct roar_bixcoder)); if ( bixcoder == NULL ) return -1; if ( calls == NULL || info == NULL || dst == NULL ) { roar_mm_free(bixcoder); return -1; } if ( roar_bixcoder_init(bixcoder, info, dst) == -1 ) { roar_mm_free(bixcoder); return -1; } memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->inst = (void*)bixcoder; calls->close = roar_vio_bixcode_close; calls->read = roar_vio_bixcode_read; calls->write = roar_vio_bixcode_write; return 0; } ssize_t roar_vio_bixcode_read (struct roar_vio_calls * vio, void *buf, size_t count) { if ( vio == NULL ) return -1; if ( buf == NULL && count != 0 ) return -1; return !roar_bixcoder_read(vio->inst, buf, count) ? (ssize_t)count : -1; } ssize_t roar_vio_bixcode_write (struct roar_vio_calls * vio, void *buf, size_t count) { if ( vio == NULL ) return -1; if ( buf == NULL && count != 0 ) return -1; return !roar_bixcoder_write(vio->inst, buf, count) ? (ssize_t)count : -1; } int roar_vio_bixcode_sync (struct roar_vio_calls * vio); int roar_vio_bixcode_close (struct roar_vio_calls * vio) { int ret = 0; if ( vio == NULL ) return -1; if ( roar_bixcoder_close(vio->inst) == -1 ) ret = -1; if ( vio->inst != NULL ) roar_mm_free(vio->inst); return ret; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�014617� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/Makefile�������������������������������������������������������������0000644�0001750�0001750�00000002256�12072565214�016257� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroareio SLIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) DRIVER=driver.o driver_oss.o driver_roar.o esdfw.a FF=ff_ssdp.o OBJS=libroareio.o $(DRIVER) $(FF) httpd.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroareio CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(Wextra) $(SHARED) -L../lib/ $(LDPATH) LIBS = $(LIBROAREIO_NS) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} autodetected.h esdfw.a *.o new: clean all esdfw.a: if [ "`ls esdfw_*.o`" != '' ]; then ${AR} cru esdfw.a esdfw_*.o; else ${AR} cru esdfw.a; fi ${RANLIB} esdfw.a $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(LIBROAREIO_V) -o $(SLIB) $(OBJS) $(LIBS) $(ALIB): ${OBJS} ${AR} cru $(ALIB) ${OBJS} ${RANLIB} $(ALIB) driver.c: autodetected.h autodetected.h: echo "/* *** */" > autodetected.h [ -f driver_esdfw.h -a -f driver_esdfw.c ] && echo '#define ROAR_HAVE_AD_ESDFW' >> autodetected.h || true echo "/* *** */" >> autodetected.h ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/driver.c�������������������������������������������������������������0000644�0001750�0001750�00000011567�12264733570�016270� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//driver.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> #include "driver.h" #include "autodetected.h" #ifdef ROAR_HAVE_AD_ESDFW #include "driver_esdfw.h" #endif static int roar_cdriver_null(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen) { ROAR_DBG("roar_cdriver_null(calls=%p, name='%s', dev='%s', info=%p{...}, dir=%i(?)) = ?", calls, name, dev, info, dir); (void)name, (void)dev, (void)info, (void)dir, (void)para, (void)paralen; memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->read = roar_vio_null_rw; calls->write = roar_vio_null_rw; ROAR_DBG("roar_cdriver_null(calls=%p, name='%s', dev='%s', info=%p{...}, dir=%i(?)) = 0", calls, name, dev, info, dir); return 0; } struct { const char * name; int (*open)(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir); int (*open2)(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen); } _g_roar_cdriver[] = { {"null", NULL, roar_cdriver_null}, {"roar", roar_cdriver_roar, NULL}, #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) {"oss", roar_cdriver_oss, NULL}, #endif #ifdef ROAR_HAVE_AD_ESDFW #include "driver_esdfw.c" #endif {NULL, NULL, NULL} }; static int roar_cdriver_open_default(struct roar_vio_calls * calls, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen) { const char * names[] = { // native APIs: "oss", // Virtual APIs: "roar", // Dummys: "null" }; size_t i; int ret; if ( dev != NULL ) { ROAR_WARN("roar_cdriver_open_default(calls=%p, dev='%s', info=%p, dir=%i): Try to open given device without driver name is a bad thing to do. This is normaly a Application error.", calls, dev, info, dir); } for (i = 0; i < (sizeof(names)/sizeof(*names)); i++) { ret = roar_cdriver_open2(calls, names[i], dev, info, dir, para, paralen); if ( ret != -1 ) return ret; } // roar_error is still set to the error of the last tested driver. return -1; } int roar_cdriver_open2(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir, struct roar_keyval * para, ssize_t paralen) { int i; char *delm; if ( name == NULL ) return roar_cdriver_open_default(calls, dev, info, dir, para, paralen); for (i = 0; _g_roar_cdriver[i].name != NULL; i++) { ROAR_DBG("roar_cdriver_open(*): _g_roar_cdriver[i].name='%s' <cmp> name='%s'", _g_roar_cdriver[i].name, name); if ( !strcmp(_g_roar_cdriver[i].name, name) ) { if ( _g_roar_cdriver[i].open2 != NULL ) return _g_roar_cdriver[i].open2(calls, name, dev, info, dir, para, paralen); if ( _g_roar_cdriver[i].open != NULL ) return _g_roar_cdriver[i].open(calls, name, dev, info, dir); } if ( (delm = strstr(_g_roar_cdriver[i].name, ":")) != NULL ) { ROAR_DBG("roar_cdriver_open(*): delm+1='%s' <cmp> name='%s'", delm+1, name); if ( !strcmp(delm+1, name) ) { if ( _g_roar_cdriver[i].open2 != NULL ) return _g_roar_cdriver[i].open2(calls, name, dev, info, dir, para, paralen); if ( _g_roar_cdriver[i].open != NULL ) return _g_roar_cdriver[i].open(calls, name, dev, info, dir); } } } roar_err_set(ROAR_ERROR_NOENT); return -1; } ssize_t roar_cdriver_list (const char ** list, size_t len, size_t offset) { size_t i; size_t idx = 0; if ( list == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( len == 0 ) return 0; if ( offset >= (sizeof(_g_roar_cdriver)/sizeof(*_g_roar_cdriver)) ) return 0; for (i = offset; _g_roar_cdriver[i].name != NULL; i++) { list[idx++] = _g_roar_cdriver[i].name; } return idx; } int roar_cdriver_open(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir) { return roar_cdriver_open2(calls, name, dev, info, dir, NULL, -1); } //ll �����������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/driver_oss.c���������������������������������������������������������0000644�0001750�0001750�00000010345�12264733570�017145� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//driver_oss.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> #include "driver.h" #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) #if defined(__OpenBSD__) || defined(__NetBSD__) #include <soundcard.h> #else #include <sys/soundcard.h> #endif #include <sys/ioctl.h> #ifdef SNDCTL_DSP_SETFRAGMENT static void roar_cdriver_oss_try_buf_setups(struct roar_vio_calls * calls) { struct roar_vio_sysio_ioctl ctl; int blocksizes[] = {11, 12, 13}; int blocks[] = {4, 5, 6, 3, 7, 2, 8}; size_t bs, b; int tmp; ctl.cmd = SNDCTL_DSP_SETFRAGMENT; ctl.argp = &tmp; for (bs = 0; bs < sizeof(blocksizes)/sizeof(int); bs++) { for (b = 0; b < sizeof(blocks) /sizeof(int); b++ ) { tmp = blocksizes[bs] | (blocks[b] << 16); if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == 0 ) return; } } } #endif #define _err() roar_vio_close(calls); return -1 int roar_cdriver_oss(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir) { struct roar_vio_defaults def; struct roar_vio_sysio_ioctl ctl; int tmp, ctmp; (void)name; // preinit ctl struct, we always pass ints in tmp. ctl.argp = &tmp; ROAR_DBG("roar_cdriver_oss(*) = ?"); #ifdef ROAR_DEFAULT_OSS_DEV if ( dev == NULL ) dev = ROAR_DEFAULT_OSS_DEV; #endif if ( dev == NULL ) return -1; ROAR_DBG("roar_cdriver_oss(*) = ?"); switch (dir) { case ROAR_DIR_PLAY: case ROAR_DIR_MONITOR: case ROAR_DIR_OUTPUT: tmp = O_WRONLY; break; case ROAR_DIR_BIDIR: case ROAR_DIR_RECPLAY: tmp = O_RDWR; break; case ROAR_DIR_RECORD: tmp = O_RDONLY; break; default: return -1; } ROAR_DBG("roar_cdriver_oss(*) = ?"); if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, tmp, 0644) == -1 ) return -1; if ( roar_vio_open_dstr(calls, dev, &def, 1) == -1 ) return -1; // channels: #ifdef SNDCTL_DSP_CHANNELS tmp = info->channels; ctl.cmd = SNDCTL_DSP_CHANNELS; if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) { _err(); } if ( tmp != (int)info->channels ) { _err(); } #else switch (info->channels) { case 1: tmp = 0; break; case 2: tmp = 1; break; default: _err(); } ctl.cmd = SNDCTL_DSP_STEREO; if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) { _err(); } #endif // codec/bits: if ( info->codec != ROAR_CODEC_ALAW && info->codec != ROAR_CODEC_MULAW && info->bits != 16 ) { // other modes are currently not supported _err(); } switch (info->codec) { case ROAR_CODEC_PCM_S_LE: tmp = AFMT_S16_LE; break; case ROAR_CODEC_PCM_S_BE: tmp = AFMT_S16_BE; break; case ROAR_CODEC_PCM_U_LE: tmp = AFMT_U16_LE; break; case ROAR_CODEC_PCM_U_BE: tmp = AFMT_U16_BE; break; case ROAR_CODEC_ALAW: tmp = AFMT_A_LAW; break; case ROAR_CODEC_MULAW: tmp = AFMT_MU_LAW; break; default: _err(); } ctmp = tmp; #ifdef SNDCTL_DSP_SETFMT ctl.cmd = SNDCTL_DSP_SETFMT; #else ctl.cmd = SNDCTL_DSP_SAMPLESIZE; #endif if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) { _err(); } if ( tmp != ctmp ) { _err(); } // rate: tmp = info->rate; ctl.cmd = SNDCTL_DSP_SPEED; if ( roar_vio_ctl(calls, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) { _err(); } if ( tmp != (int)info->rate ) { _err(); } #ifdef SNDCTL_DSP_SETFRAGMENT roar_cdriver_oss_try_buf_setups(calls); #endif return 0; } #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/driver_roar.c��������������������������������������������������������0000644�0001750�0001750�00000002563�12264733570�017307� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//driver_roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> #include "driver.h" #define MIXER_ID -1 int roar_cdriver_roar(struct roar_vio_calls * calls, const char * name, const char * dev, struct roar_audio_info * info, int dir) { (void)name; return roar_vio_simple_stream(calls, info->rate, info->channels, info->bits, info->codec, dev, dir, "libroareio client", MIXER_ID); } //ll ���������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/ff_ssdp.c������������������������������������������������������������0000644�0001750�0001750�00000005472�12264733571�016420� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ff_ssdp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroareio a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroareio.h" void roar_ff_ssdp_init (struct roar_ff_ssdp * c) { memset(c, 0, sizeof(struct roar_ff_ssdp)); c->method = ROAR_FF_SSDP_M_NOTIFY; c->server = roar_mm_strdup("RoarAudio libroareio/ff_ssdp.c"); c->max_age = 1800; c->location = NULL; c->nt = NULL; c->usn = NULL; c->usn_nt_suffix = 1; c->host = roar_mm_strdup(ROAR_FF_SSDP_HOST_UPNP); } void roar_ff_ssdp_free (struct roar_ff_ssdp * c) { if ( c->server != NULL ) roar_mm_free(c->server); if ( c->location != NULL ) roar_mm_free(c->location); if ( c->nt != NULL ) roar_mm_free(c->nt); if ( c->usn != NULL ) roar_mm_free(c->usn); if ( c->host != NULL ) roar_mm_free(c->host); memset(c, 0, sizeof(struct roar_ff_ssdp)); } int roar_ff_ssdp_write(struct roar_vio_calls * vio, struct roar_ff_ssdp * c) { char * met; char * nts; switch (c->method) { case ROAR_FF_SSDP_M_NOTIFY: met = ROAR_FF_SSDP_MS_NOTIFY; break; case ROAR_FF_SSDP_M_M_SEARCH: met = ROAR_FF_SSDP_MS_M_SEARCH; break; default: return -1; } switch (c->nst) { case ROAR_FF_SSDP_A_ALIVE: nts = ROAR_FF_SSDP_AS_ALIVE; break; case ROAR_FF_SSDP_A_BYEBYE: nts = ROAR_FF_SSDP_AS_BYEBYE; break; default: return -1; } roar_vio_printf(vio, "%s * HTTP/1.1\r\n", met); roar_vio_printf(vio, "SERVER: %s\r\n", c->server); roar_vio_printf(vio, "CACHE-CONTROL: max-age=%i\r\n", c->max_age); roar_vio_printf(vio, "LOCATION: %s\r\n", c->location); roar_vio_printf(vio, "NTS: %s\r\n", nts); roar_vio_printf(vio, "NT: %s\r\n", c->nt); if ( c->usn_nt_suffix ) { roar_vio_printf(vio, "USN: %s::%s\r\n", c->usn, c->nt); } else { roar_vio_printf(vio, "USN: %s\r\n", c->usn); } roar_vio_printf(vio, "HOST: %s\r\n", c->host); roar_vio_printf(vio, "\r\n"); return 0; } int roar_ff_ssdp_read (struct roar_vio_calls * vio, struct roar_ff_ssdp * c) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/httpd.c��������������������������������������������������������������0000644�0001750�0001750�00000010056�12264733571�016111� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//httpd.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroareio a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroareio.h" struct roar_httpd * roar_http_new(struct roar_vio_calls * client, int (*cb_eoh)(struct roar_httpd * httpd)) { struct roar_httpd * httpd; if ( client == NULL || cb_eoh == NULL ) return NULL; if ( (httpd = roar_mm_malloc(sizeof(struct roar_httpd))) == NULL ) return NULL; memset(httpd, 0, sizeof(struct roar_httpd)); httpd->state = ROAR_HTTPD_STATE_REQ; httpd->client = client; httpd->cb_eoh = cb_eoh; return NULL; } int roar_http_free(struct roar_httpd * httpd) { if ( httpd->response.file != NULL ) roar_vio_close(httpd->response.file); if ( httpd->client != NULL ) roar_vio_close(httpd->client); roar_mm_free(httpd); return 0; } // TODO: update this function to use iobuffer: static int roar_http_eoh (struct roar_httpd * httpd) { struct roar_httpd_request * req = &(httpd->request); struct roar_httpd_response * resp = &(httpd->response); int i; // TODO: parse HTTP here resp->version = req->version; resp->status = -1; httpd->cb_eoh(httpd); if ( resp->status == -1 ) { if ( resp->file == NULL ) { resp->status = ROAR_HTTPD_STATUS_NOT_FOUND; } else { resp->status = ROAR_HTTPD_STATUS_OK; } } roar_vio_printf(httpd->client, "HTTP/%i.%i %i State %i\r\n", _ROAR_EIO_HTTPD_VERSION_MAJOR(resp->version), _ROAR_EIO_HTTPD_VERSION_MINOR(resp->version), resp->status, resp->status); if ( resp->header != NULL ) { for (i = 0; resp->header[i].key != NULL; i++) { roar_vio_printf(httpd->client, "%s: %s\r\n", resp->header[i].key, resp->header[i].value); } roar_mm_free(resp->header); } return 0; } int roar_http_update(struct roar_httpd * httpd) { void * data; size_t len; ssize_t ret; switch (httpd->state) { case ROAR_HTTPD_STATE_REQ: break; case ROAR_HTTPD_STATE_EOH: return roar_http_eoh(httpd); break; case ROAR_HTTPD_STATE_RESP: if ( httpd->iobuffer != NULL ) { if ( roar_buffer_get_len(httpd->iobuffer, &len) == -1 ) return -1; } else { len = 0; } if ( len != 0 ) { if ( roar_buffer_get_data(httpd->iobuffer, &data) == -1 ) return -1; if ( (ret = roar_vio_write(httpd->client, data, len)) == -1 ) return -1; if ( roar_buffer_set_offset(httpd->iobuffer, ret) == -1 ) return -1; // bad error return 0; } if ( httpd->iobuffer != NULL ) { len = 2048; if ( roar_buffer_set_len(httpd->iobuffer, len) == -1 ) return -1; } else { if ( roar_buffer_new(&(httpd->iobuffer), len) == -1 ) return -1; } if ( roar_buffer_get_data(httpd->iobuffer, &data) == -1 ) return -1; if ( (ret = roar_vio_read(httpd->response.file, data, len)) == -1 ) { if ( roar_buffer_set_len(httpd->iobuffer, 0) == -1 ) return -1; // bad error } len = ret; if ( roar_buffer_set_len(httpd->iobuffer, len) == -1 ) return -1; if ( (ret = roar_vio_write(httpd->client, data, len)) == -1 ) return -1; if ( roar_buffer_set_offset(httpd->iobuffer, ret) == -1 ) return -1; // bad error return 0; break; } return -1; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroareio/libroareio.c���������������������������������������������������������0000644�0001750�0001750�00000001706�12264733571�017117� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroareio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroareio a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroareio.h" //ll ����������������������������������������������������������roaraudio-1.0beta11/libroaresd/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553175�014622� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaresd/AUTHORS.esd����������������������������������������������������������0000644�0001750�0001750�00000004513�11055605305�016432� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This file is taken from my copy of EsounD (debian pkg) without any modification expect this header. For more information see the EsounD sources and/or contact the current EsounD mainteiner(s). ------------------------------- Program History: EsounD was coded and maintained by Eric B. Mitchell (aka 'Ricdude) <ericmit@ix.netcom.com> before moving on to other things. This was based on a prototype sound daemon created by Carsten Haitzler (aka The Rasterman). Some snips of his code are probably still lurking about, but the overwhelming majority of it was written from scratch. Additional Credits: Chutt <#E>, for insanely agreeing to alpha test, and porting Emusic, to EsounD. Emusic is a highly customizable sound player available from: http://www.icom.net/~smelecat/emp3/index.htm. And for the initial configure setup Elliot Lee <sopwith@redhat.com>, for insanely jumping in and carrying on, during my untimely extended leaves of absence. Shaleh <#E>, for "-Wall -pedantic" cleanup patches adnans <#E>, threshhold clipping patches Peter Asobeck, Sun driver update. Jason Ish, BSD patches and debugging. Jeff Dubrule, mklinux driver and patches. Vendu <#E>, remembering to check for errors in esdcat. Brian M. Almeida, Sun driver update. Simon Kagedal, for esdplay, a generic audio file player. mackman, linuxppc patches. Nick Lopez <kimo_sabe@usa.net>: ALSA port. Dave Glowacki <dglo@SSEC.WISC.EDU>: audio_hpux patches. Kimball Thurston: audio_irix patches. Mandrake (Geoff Harrison) <mandrake@mandrake.net>: making sure the library revision numbers actually come out right. :) Bibek Sahu: Improved ALSA detection algorithms, filters, mixdown optimizations. Jimmy Olsen <jo@hrp.no>: hpux driver fixes Manish Singh <yosh@gimp.org>: misc autoconf hackery, the magic /dev/dsp to esd rerouter. Philippe Defert: aix driver fixes Miodrag Vallat: unnecessary fsync() cleanup, rounding patch. Bob Bell <bobbell@zk3.dec.com> is the man behind audio_osf.c A whole list of people in the ChangeLog, who fail to appear here. The masses of "early adopters" who beat the snot out of esound early on. Your Name Here, simply submit a patch, or port an existing application for use with this package. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaresd/Makefile�������������������������������������������������������������0000644�0001750�0001750�00000001411�12072565214�016246� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroaresd SLIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) OBJS=libroaresd.o esdbasic.o esdctl.o esdstream.o esdsample.o esdfile.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroaresd CFLAGS += $(DEBUG_g) $(Wall) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) $(LDPATH) -L../lib/ LIBS = $(LIBROAR) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(COMMON_SOVERSION) -o $(SLIB) ${OBJS} ${LIBS} $(ALIB): ${OBJS} ${AR} cru $(ALIB) ${OBJS} ${RANLIB} $(ALIB) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaresd/esdbasic.c�����������������������������������������������������������0000644�0001750�0001750�00000007411�12264733571�016543� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//esdbasic.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from EsounD. * They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude) * <ericmit@ix.netcom.com>. For more information see AUTHORS.esd. * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroaresd.h" /* opens channel, authenticates connection, and prefares for protos */ /* returns EsounD socket for communication, result < 0 = error */ /* server = listen socket (localhost:5001, 192.168.168.0:9999 */ /* rate, format = (bits | channels | stream | func) */ int esd_open_sound( const char *host ) { struct roar_connection con; int fh; if ( host == NULL ) host = roar_env_get("ESPEAKER"); if ( roar_simple_connect(&con, (char*) host, NULL) == -1 ) { ROAR_DBG("esd_open_sound(*): roar_simple_connect() faild!"); return -1; } if ( (fh = roar_get_connection_fh(&con)) == -1 ) { roar_disconnect(&con); return -1; } return fh; } /* send the authorization cookie, create one if needed */ int esd_send_auth( int sock ) { (void) sock; return 0; } /* closes fd, previously obtained by esd_open */ int esd_close( int esd ) { struct roar_vio_calls vio; if ( roar_vio_open_fh_socket(&vio, esd) == -1 ) { roar_err_update(); return -1; } if ( roar_vio_close(&vio) == -1 ) { roar_err_update(); return -1; } return 0; } /* get the stream latency to esound (latency is number of samples */ /* at 44.1khz stereo 16 bit - you'll have to adjust if oyur input */ /* sampling rate is less (in bytes per second) */ /* so if you're at 44.1khz stereo 16bit in your stream - your lag */ /* in bytes woudl be lag * 2 * 2 bytes (2 for stereo, 2 for 16bit) */ /* if your stream is at 22.05 Khz it'll be double this - in mono */ /* double again ... etc. */ // TODO: FIXME: write something usefull here. int esd_get_latency(int esd) { #ifdef ROAR_HAVE_GETTIMEOFDAY struct timeval try, ans; struct roar_message m; struct roar_connection con; memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_NOOP; m.datalen = 0; roar_connect_fh(&con, esd); gettimeofday(&try, NULL); roar_req(&con, &m, NULL); gettimeofday(&ans, NULL); while (ans.tv_sec > try.tv_sec) { ans.tv_sec--; ans.tv_usec += 1000000; } ans.tv_usec -= try.tv_usec; /* 1 -> 44100 0.5 -> 22050 */ return 441*ans.tv_usec/10000; #else // don't know... return 0; #endif } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaresd/esdctl.c�������������������������������������������������������������0000644�0001750�0001750�00000025351�12264733572�016250� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//esdctl.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from EsounD. * They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude) * <ericmit@ix.netcom.com>. For more information see AUTHORS.esd. * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroaresd.h" /* lock/unlock will disable/enable foreign clients from connecting */ // we do not have such a thing at the moment... // so always return -1 int esd_lock( int esd ) { (void)esd; errno = ENOSYS; return -1; } int esd_unlock( int esd ) { (void)esd; errno = ENOSYS; return -1; } /* standby/resume will free/reclaim audio device so others may use it */ int esd_standby( int esd ) { struct roar_connection con; roar_connect_fh(&con, esd); return roar_set_standby(&con, ROAR_STANDBY_ACTIVE); } int esd_resume( int esd ) { struct roar_connection con; roar_connect_fh(&con, esd); return roar_set_standby(&con, ROAR_STANDBY_INACTIVE); } static void _format2str(char * buf, size_t len, esd_format_t format) { if ( (format & ESD_BITS16) == ESD_BITS16 ) { roar_mm_strlcat(buf, "16 bit ", len); } else { roar_mm_strlcat(buf, "8 bit ", len); } if ( (format & ESD_STEREO) == ESD_STEREO ) { roar_mm_strlcat(buf, "stereo ", len); } else { roar_mm_strlcat(buf, "mono ", len); } } /* print server into to stdout */ void esd_print_server_info(esd_server_info_t *server_info ) { char buf[80] = ""; _format2str(buf, sizeof(buf), server_info->format); printf("server version = %i\n", server_info->version); printf("server format = 0x%08x %s\n", server_info->format, buf); printf("server rate = %i\n", server_info->rate); } void esd_print_player_info( esd_player_info_t *player_info ) { char buf[80] = ""; _format2str(buf, sizeof(buf), player_info->format); printf("player %i name = %s\n", player_info->source_id, player_info->name); printf("player %i format = 0x%08x %s\n", player_info->source_id, player_info->format, buf); printf("player %i rate = %i\n", player_info->source_id, player_info->rate); printf("player %i left = %i\n", player_info->source_id, player_info->left_vol_scale ); printf("player %i right = %i\n", player_info->source_id, player_info->right_vol_scale ); } void esd_print_sample_info( esd_sample_info_t *sample_info ) { char buf[80] = ""; _format2str(buf, sizeof(buf), sample_info->format); printf("sample %i name = %s\n", sample_info->sample_id, sample_info->name); printf("sample %i format = 0x%08x %s\n", sample_info->sample_id, sample_info->format, buf); printf("sample %i rate = %i\n", sample_info->sample_id, sample_info->rate); printf("sample %i left = %i\n", sample_info->sample_id, sample_info->left_vol_scale); printf("sample %i right = %i\n", sample_info->sample_id, sample_info->right_vol_scale); printf("sample %i length = %i\n", sample_info->sample_id, sample_info->length); } /* print all info to stdout */ void esd_print_all_info( esd_info_t *all_info ) { esd_player_info_t *player; esd_sample_info_t *sample; esd_print_server_info(all_info->server); player = all_info->player_list; while (player) { esd_print_player_info(player); player = player->next; } sample = all_info->sample_list; while (sample) { esd_print_sample_info(sample); sample = sample->next; } } /* retrieve server properties (sample rate, format, version number) */ esd_server_info_t *esd_get_server_info( int esd ) { esd_server_info_t * r; struct roar_stream s; struct roar_connection con; struct roar_message m; r = roar_mm_malloc(sizeof(esd_server_info_t)); if ( r == NULL ) return NULL; r->version = 0; // seems to be static roar_connect_fh(&con, esd); memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_SERVER_OINFO; m.datalen = 0; if ( roar_req(&con, &m, NULL) == -1 ) { roar_mm_free(r); return NULL; } if ( m.cmd != ROAR_CMD_OK ) { roar_mm_free(r); return NULL; } if ( roar_stream_m2s(&s, &m) == -1 ) { roar_mm_free(r); return NULL; } r->rate = s.info.rate; r->format = 0; if ( s.info.channels == 1 ) r->format |= ESD_MONO; else r->format |= ESD_STEREO; if ( s.info.bits == 8 ) r->format |= ESD_BITS8; else r->format |= ESD_BITS16; return r; } /* release all memory allocated for the server properties structure */ void esd_free_server_info( esd_server_info_t *server_info ) { if (server_info != NULL) roar_mm_free(server_info); } /* retrieve all information from server */ esd_info_t *esd_get_all_info( int esd ) { esd_info_t * r; int i; int num; int clients[ROAR_CLIENTS_MAX]; struct roar_client c; struct roar_stream s; struct roar_connection con[1]; struct roar_mixer_settings mixer; int channels; float fs; esd_player_info_t * new_player, * cur = NULL; // = NULL to avoid gcc warning roar_connect_fh(con, esd); r = roar_mm_malloc(sizeof(esd_info_t)); if ( r == NULL ) return NULL; r->server = esd_get_server_info(esd); r->player_list = NULL; r->sample_list = NULL; if ( (num = roar_list_clients(con, clients, ROAR_CLIENTS_MAX)) == -1 ) { ROAR_ERR("esd_get_all_info(*): can not get client list"); num = 0; } for (i = 0; i < num; i++) { if ( roar_get_client(con, &c, clients[i]) == -1 ) { ROAR_ERR("esd_get_all_info(*): can not get client info"); continue; } if ( c.execed != -1 ) { if ( roar_get_stream(con, &s, c.execed) == -1 ) { ROAR_ERR("esd_get_all_info(*): can not get stream info"); continue; } if ( (new_player = roar_mm_malloc(sizeof(esd_player_info_t))) == NULL ) { ROAR_ERR("esd_get_all_info(*): can not alloc memory for new player! BAD"); continue; } new_player->next = NULL; new_player->source_id = c.execed; new_player->rate = s.info.rate; new_player->format = ROAR_S2ESD(&s); // sprintf(new_player->name, "roar stream %i", c.execed); strncpy(new_player->name, c.name, ESD_NAME_MAX < ROAR_BUFFER_NAME ? ESD_NAME_MAX : ESD_NAME_MAX); new_player->server = r->server; if ( roar_get_vol(con, c.execed, &mixer, &channels) == -1 ) { ROAR_ERR("esd_get_all_info(*): can not get stream mixer info"); new_player->left_vol_scale = new_player->right_vol_scale = 256; } else { fs = mixer.scale / 257; if ( channels == 1 ) { new_player->left_vol_scale = new_player->right_vol_scale = mixer.mixer[0] == mixer.scale ? 256 : mixer.mixer[0] / fs; } else { if ( channels != 2 ) { ROAR_ERR("esd_get_all_info(*): server seems to run in > 2 channel mode. ignoring any but the first two channels!"); } new_player->left_vol_scale = mixer.mixer[0] == mixer.scale ? 256 : mixer.mixer[0] / fs; new_player->right_vol_scale = mixer.mixer[1] == mixer.scale ? 256 : mixer.mixer[1] / fs; } } if ( r->player_list == NULL ) { r->player_list = cur = new_player; } else { cur->next = new_player; // add to old player cur = new_player; // hop to next player } } } return r; } /* retrieve all information from server, and update until unsubsribed or closed */ esd_info_t *esd_subscribe_all_info( int esd ) { (void)esd; errno = ENOSYS; return NULL; // Not yet implemented in upstream esd } /* call to update the info structure with new information, and call callbacks */ esd_info_t *esd_update_info( int esd, esd_info_t *info, esd_update_info_callbacks_t *callbacks ) { (void)esd, (void)info, (void)callbacks; errno = ENOSYS; return NULL; // Not yet implemented in upstream esd } esd_info_t *esd_unsubscribe_info( int esd ) { (void)esd; errno = ENOSYS; return NULL; // Not yet implemented in upstream esd } /* release all memory allocated for the esd info structure */ void esd_free_all_info( esd_info_t *info ) { esd_player_info_t *player, *oplayer; esd_sample_info_t *sample, *osample; if ( info != NULL ) { /* if ( info->server ) free(info->server); */ esd_free_server_info(info->server); /* // TODO: do we need to free more? if ( info->player_list ) free(info->player_list); if ( info->sample_list ) free(info->sample_list); */ player = info->player_list; while (player != NULL) { oplayer = player; player = player->next; roar_mm_free(oplayer); } sample = info->sample_list; while (sample) { osample = sample; sample = sample->next; roar_mm_free(osample); } roar_mm_free(info); } } /* reset the volume panning for a stream */ int esd_set_stream_pan( int esd, int stream_id, int left_scale, int right_scale ) { struct roar_connection con; struct roar_mixer_settings mixer; roar_connect_fh(&con, esd); mixer.scale = 256; mixer.mixer[0] = left_scale; mixer.mixer[1] = right_scale; ROAR_DBG("esd_set_stream_pan(esd=%i, stream_id=%i, left_scale=%i, right_scale=%i) = ?", esd, stream_id, left_scale, right_scale); return roar_set_vol(&con, stream_id, &mixer, 2, ROAR_SET_VOL_UNMAPPED); } /* reset the default volume panning for a sample */ int esd_set_default_sample_pan( int esd, int sample_id, int left_scale, int right_scale ) { // this is not yet implemented by the RA protocol. (void)esd, (void)sample_id, (void)left_scale, (void)right_scale; errno = ENOSYS; return -1; } /* see if the server is in stnaby, autostandby, etc */ esd_standby_mode_t esd_get_standby_mode( int esd ) { struct roar_connection con; if ( roar_connect_fh(&con, esd) == -1 ) return -1; return roar_get_standby(&con); } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaresd/esdfile.c������������������������������������������������������������0000644�0001750�0001750�00000004413�12264733573�016402� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//esdfile.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from EsounD. * They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude) * <ericmit@ix.netcom.com>. For more information see AUTHORS.esd. * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroaresd.h" /*******************************************************************/ /* esdfile.c - audiofile wrappers for sane handling of files */ int esd_send_file( int esd, AFfilehandle au_file, int frame_length ) { return -1; } int esd_play_file( const char *name_prefix, const char *filename, int fallback ) { int ret = roar_simple_play_file(filename, NULL, name_prefix); if ( ret != -1 ) return 0; if ( !fallback ) return -1; return roar_simple_play_file(filename, "+fork", name_prefix) == -1 ? -1 : 0; } int esd_file_cache( int esd, const char *name_prefix, const char *filename ) { return -1; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaresd/esdsample.c����������������������������������������������������������0000644�0001750�0001750�00000005067�12264733573�016752� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//esdsample.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from EsounD. * They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude) * <ericmit@ix.netcom.com>. For more information see AUTHORS.esd. * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroaresd.h" // TODO: add support for all of thiese funcs /* cache a sample in the server returns sample id, < 0 = error */ int esd_sample_cache( int esd, esd_format_t format, const int rate, const int length, const char *name ) { return -1; } int esd_confirm_sample_cache( int esd ) { return -1; } /* get the sample id for an already-cached sample */ int esd_sample_getid( int esd, const char *name) { return -1; } /* uncache a sample in the server */ int esd_sample_free( int esd, int sample ) { return -1; } /* play a cached sample once */ int esd_sample_play( int esd, int sample ) { return -1; } /* make a cached sample loop */ int esd_sample_loop( int esd, int sample ) { return -1; } /* stop the looping sample at end */ int esd_sample_stop( int esd, int sample ) { return -1; } /* stop a playing sample immed. */ int esd_sample_kill( int esd, int sample ) { return -1; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaresd/esdstream.c����������������������������������������������������������0000644�0001750�0001750�00000007776�12264733573�016775� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//esdstream.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from EsounD. * They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude) * <ericmit@ix.netcom.com>. For more information see AUTHORS.esd. * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroaresd.h" #if BYTE_ORDER == BIG_ENDIAN #define CODEC_DEF_8BIT ROAR_CODEC_PCM_U_BE #elif BYTE_ORDER == LITTLE_ENDIAN #define CODEC_DEF_8BIT ROAR_CODEC_PCM_U_LE #else #define CODEC_DEF_8BIT ROAR_CODEC_PCM_U_PDP #endif /* open a socket for playing, monitoring, or recording as a stream */ /* the *_fallback functions try to open /dev/dsp if there's no EsounD */ static int libroaresd_stream(esd_format_t format, int rate, const char *host, const char *name, int dir) { struct roar_vio_calls calls; int channels; int bits; int codec = ROAR_CODEC_DEFAULT; int fh; int ret = -1; if ( (format & ESD_BITS16) ) { bits = 16; } else { bits = 8; codec = CODEC_DEF_8BIT; } if ( (format & ESD_MONO) ) { channels = 1; } else { channels = 2; } if ( roar_vio_simple_stream(&calls, rate, channels, bits, codec, host, dir, name, -1) == -1 ) return -1; if ( roar_vio_ctl(&calls, ROAR_VIO_CTL_GET_FH, &fh) != -1 ) if ( fh != -1 ) ret = dup(fh); roar_vio_close(&calls); return ret; } int esd_play_stream( esd_format_t format, int rate, const char *host, const char *name ) { return libroaresd_stream(format, rate, host, name, ROAR_DIR_PLAY); } int esd_play_stream_fallback( esd_format_t format, int rate, const char *host, const char *name ) { int r; if ( (r = esd_play_stream(format, rate, host, name)) != -1 ) { return r; } return esd_play_stream(format, rate, "+fork", name); } int esd_monitor_stream( esd_format_t format, int rate, const char *host, const char *name ) { return libroaresd_stream(format, rate, host, name, ROAR_DIR_MONITOR); } /* int esd_monitor_stream_fallback( esd_format_t format, int rate ); */ int esd_record_stream( esd_format_t format, int rate, const char *host, const char *name ) { return libroaresd_stream(format, rate, host, name, ROAR_DIR_RECORD); } int esd_record_stream_fallback( esd_format_t format, int rate, const char *host, const char *name ) { int r; if ( (r = esd_record_stream(format, rate, host, name)) != -1 ) { return r; } return esd_record_stream(format, rate, "+fork", name); } int esd_filter_stream( esd_format_t format, int rate, const char *host, const char *name ) { return libroaresd_stream(format, rate, host, name, ROAR_DIR_FILTER); } //ll ��roaraudio-1.0beta11/libroaresd/libroaresd.c���������������������������������������������������������0000644�0001750�0001750�00000003261�12264733574�017116� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroaresd.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from EsounD. * They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude) * <ericmit@ix.netcom.com>. For more information see AUTHORS.esd. * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "libroaresd.h" //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarlight/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�015152� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarlight/Makefile�����������������������������������������������������������0000644�0001750�0001750�00000001402�12072565215�016603� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroarlight SLIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) OBJS=libroarlight.o colors.o roardmx.o pwm.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroarlight CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) -L../lib/ $(LDPATH) LIBS = $(LIBROARLIGHT_NS) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(LIBROARLIGHT_V) -o $(SLIB) ${OBJS} ${LIBS} $(ALIB): ${OBJS} ${AR} cru $(ALIB) ${OBJS} ${RANLIB} $(ALIB) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarlight/colors.c�����������������������������������������������������������0000644�0001750�0001750�00000006704�12264733574�016632� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//colors.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroarlight.h" int roar_color_new (struct roar_color * c) { if ( c == NULL ) return -1; memset(c, 0, sizeof(struct roar_color)); c->system = ROAR_COLORSYSTEM_NONE; return 0; } int roar_color_new_gray (struct roar_color * c, unsigned char k) { if ( roar_color_new(c) == -1 ) return -1; c->system = ROAR_COLORSYSTEM_GRAY; c->color.gray.k = k; return 0; } int roar_color_new_rgb (struct roar_color * c, unsigned char r, unsigned char g, unsigned char b) { if ( roar_color_new(c) == -1 ) return -1; c->system = ROAR_COLORSYSTEM_RGB; c->color.rgb.r = r; c->color.rgb.g = g; c->color.rgb.b = b; return 0; } int roar_color_copy (struct roar_color * dst, struct roar_color * src) { if ( dst == NULL || src == NULL ) return -1; memcpy(dst, src, sizeof(struct roar_color)); return 0; } int roar_color_conv (struct roar_color * c, uint32_t system) { if ( c == NULL ) return -1; switch (c->system) { case ROAR_COLORSYSTEM_GRAY: return roar_color_conv_gray(c, system); break; case ROAR_COLORSYSTEM_RGB: return roar_color_conv_rgb(c, system); break; } return -1; } int roar_color_conv_gray (struct roar_color * c, uint32_t system) { unsigned char k; if ( c == NULL ) return -1; if ( c->system != ROAR_COLORSYSTEM_GRAY ) return -1; switch (system) { case ROAR_COLORSYSTEM_RGB: k = c->color.gray.k; c->color.rgb.r = k; c->color.rgb.g = k; c->color.rgb.b = k; c->system = ROAR_COLORSYSTEM_RGB; return 0; break; } return -1; } int roar_color_conv_rgb (struct roar_color * c, uint32_t system) { if ( c == NULL ) return -1; if ( c->system != ROAR_COLORSYSTEM_GRAY ) return -1; switch (system) { } return -1; } int roar_color_to_string (struct roar_color * c, char * str, size_t len) { size_t needlen; if ( c == NULL || str == NULL || len == 0 ) return -1; // just to be sure: if ( len >= 1 ) *str = 0; switch (c->system) { case ROAR_COLORSYSTEM_NONE: needlen = 6; break; // '(none)' case ROAR_COLORSYSTEM_RGB: needlen = 7; break; // '#RRGGBB' default: return -1; } needlen++; // terminating \0 if ( needlen > len ) return -1; switch (c->system) { case ROAR_COLORSYSTEM_NONE: strcpy(str, "(none)"); break; case ROAR_COLORSYSTEM_RGB: snprintf(str, 8, "#%.2X%.2X%.2X", c->color.rgb.r, c->color.rgb.g, c->color.rgb.b); break; } return 0; } int roar_color_to_blob (struct roar_color * c, char * blob, size_t len); int roar_color_from_blob (struct roar_color * c, char * blob, size_t len); //ll ������������������������������������������������������������roaraudio-1.0beta11/libroarlight/libroarlight.c�����������������������������������������������������0000644�0001750�0001750�00000001712�12264733575�020006� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarlight.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroarlight.h" //ll ������������������������������������������������������roaraudio-1.0beta11/libroarlight/pwm.c��������������������������������������������������������������0000644�0001750�0001750�00000005656�12264733575�016142� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//pwm.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroarlight.h" uint16_t _g_roar_lpwm16[] = { /* 0x0000, 0x0001, 0x0101, 0x0111, 0x1111, 0x1115, 0x1515, 0x1555, 0x5555, 0x5557, 0x5757, 0x5777, 0x7777, 0x777F, 0x7F7F, 0x7FFF, 0xFFFF */ 0xFFFF, 0x7FFF, 0x7F7F, 0x777F, 0x7777, 0x5777, 0x5757, 0x5557, 0x5555, 0x1555, 0x1515, 0x1115, 0x1111, 0x0111, 0x0101, 0x0001, 0x0000 }; int roar_light_pwm_new (struct roar_lpwm_state * state, int bits ) { if ( state == NULL ) return -1; if ( bits < 1 || bits > 32 ) return -1; state->bits = bits; return roar_light_pwm_set(state, 0); } int roar_light_pwm_set (struct roar_lpwm_state * state, int value) { if ( state == NULL ) return -1; if ( value < 0 || value > (state->bits+1) ) return -1; state->value = value; return 0; } int roar_light_pwm_send(struct roar_lpwm_state * state, struct roar_vio_calls * vio, size_t len) { char * buf; int16_t * buf16; size_t todo = len; uint64_t s; ROAR_DBG("roar_light_pwm_send(state=%p, vio=%p, len=%u) = ?", state, vio, len); if ( state == NULL ) return -1; if ( vio == NULL ) return -1; if ( state->bits != 16 ) return -1; if ( len == 0 ) return 0; if ( (buf = roar_mm_malloc(len)) == NULL ) return -1; buf16 = (int16_t *) buf; while (todo > 1) { ROAR_DBG("roar_light_pwm_send(*): loop: todo=%u, fill=%i", todo, state->fill); if ( state->fill < 16 ) { s = _g_roar_lpwm16[state->value]; s <<= state->fill; state->s |= s; state->fill += 16; } *buf16 = state->s & 0xFFFF; state->s >>= 16; state->fill -= 16; buf16++; todo -= 2; } if ( todo ) { if ( state->fill < 8 ) { s = _g_roar_lpwm16[state->value]; s <<= state->fill; state->s |= s; state->fill += 16; } buf[len-1] = state->s & 0xFF; state->s >>= 8; state->fill -= 8; } if ( roar_vio_write(vio, buf, len) != (ssize_t)len ) { roar_mm_free(buf); return -1; } roar_mm_free(buf); return 0; } //ll ����������������������������������������������������������������������������������roaraudio-1.0beta11/libroarlight/roardmx.c����������������������������������������������������������0000644�0001750�0001750�00000030611�12264733576�017001� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roardmx.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroarlight.h" // base(ic) check #define BCHK(x) if ( (x) == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } // database access: static const struct { const int id; const char * const name; } __eventnames[] = { //$ grep '^#define ROAR_ROARDMX_EVENT_' roardmx.h | cut -d ' ' -f2 | while read line; do name=`echo $line | cut -d_ -f4 | tr A-Z a-z`; for suffix in beat off on hold; do printf " {%-56s \"%s\"},\n" "$line|ROAR_ROARDMX_ETYPE_`tr a-z A-Z <<<$suffix`," $name-$suffix; done; printf " {%-56s \"%s\"},\n" $line, $name; done {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_BEAT, "none-beat"}, {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_OFF, "none-off"}, {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_ON, "none-on"}, {ROAR_ROARDMX_EVENT_NONE|ROAR_ROARDMX_ETYPE_HOLD, "none-hold"}, {ROAR_ROARDMX_EVENT_NONE, "none"}, {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_BEAT, "step-beat"}, {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_OFF, "step-off"}, {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_ON, "step-on"}, {ROAR_ROARDMX_EVENT_STEP|ROAR_ROARDMX_ETYPE_HOLD, "step-hold"}, {ROAR_ROARDMX_EVENT_STEP, "step"}, {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_BEAT, "tap-beat"}, {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_OFF, "tap-off"}, {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_ON, "tap-on"}, {ROAR_ROARDMX_EVENT_TAP|ROAR_ROARDMX_ETYPE_HOLD, "tap-hold"}, {ROAR_ROARDMX_EVENT_TAP, "tap"}, {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_BEAT, "beat-beat"}, {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_OFF, "beat-off"}, {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_ON, "beat-on"}, {ROAR_ROARDMX_EVENT_BEAT|ROAR_ROARDMX_ETYPE_HOLD, "beat-hold"}, {ROAR_ROARDMX_EVENT_BEAT, "beat"}, {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_BEAT, "blackout-beat"}, {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_OFF, "blackout-off"}, {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_ON, "blackout-on"}, {ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_HOLD, "blackout-hold"}, {ROAR_ROARDMX_EVENT_BLACKOUT, "blackout"}, {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_BEAT, "fullon-beat"}, {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_OFF, "fullon-off"}, {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_ON, "fullon-on"}, {ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_HOLD, "fullon-hold"}, {ROAR_ROARDMX_EVENT_FULLON, "fullon"}, {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_BEAT, "flash-beat"}, {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_OFF, "flash-off"}, {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_ON, "flash-on"}, {ROAR_ROARDMX_EVENT_FLASH|ROAR_ROARDMX_ETYPE_HOLD, "flash-hold"}, {ROAR_ROARDMX_EVENT_FLASH, "flash"}, {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_BEAT, "strobe-beat"}, {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_OFF, "strobe-off"}, {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_ON, "strobe-on"}, {ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_HOLD, "strobe-hold"}, {ROAR_ROARDMX_EVENT_STROBE, "strobe"}, {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_BEAT, "strobeready-beat"}, {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_OFF, "strobeready-off"}, {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_ON, "strobeready-on"}, {ROAR_ROARDMX_EVENT_STROBEREADY|ROAR_ROARDMX_ETYPE_HOLD, "strobeready-hold"}, {ROAR_ROARDMX_EVENT_STROBEREADY, "strobeready"}, {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_BEAT, "strobeload-beat"}, {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_OFF, "strobeload-off"}, {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_ON, "strobeload-on"}, {ROAR_ROARDMX_EVENT_STROBELOAD|ROAR_ROARDMX_ETYPE_HOLD, "strobeload-hold"}, {ROAR_ROARDMX_EVENT_STROBELOAD, "strobeload"}, {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_BEAT, "fog-beat"}, {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_OFF, "fog-off"}, {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_ON, "fog-on"}, {ROAR_ROARDMX_EVENT_FOG|ROAR_ROARDMX_ETYPE_HOLD, "fog-hold"}, {ROAR_ROARDMX_EVENT_FOG, "fog"}, {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_BEAT, "fogready-beat"}, {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_OFF, "fogready-off"}, {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_ON, "fogready-on"}, {ROAR_ROARDMX_EVENT_FOGREADY|ROAR_ROARDMX_ETYPE_HOLD, "fogready-hold"}, {ROAR_ROARDMX_EVENT_FOGREADY, "fogready"}, {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_BEAT, "fogheat-beat"}, {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_OFF, "fogheat-off"}, {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_ON, "fogheat-on"}, {ROAR_ROARDMX_EVENT_FOGHEAT|ROAR_ROARDMX_ETYPE_HOLD, "fogheat-hold"}, {ROAR_ROARDMX_EVENT_FOGHEAT, "fogheat"} }; int roar_roardmx_str2event(const char * event) { size_t i; if ( event == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; i < (sizeof(__eventnames)/sizeof(*__eventnames)); i++) if ( !strcasecmp(event, __eventnames[i].name) ) return __eventnames[i].id; roar_err_set(ROAR_ERROR_NOENT); return -1; } const char * roar_roardmx_event2str(const int event) { size_t i; for (i = 0; i < (sizeof(__eventnames)/sizeof(*__eventnames)); i++) if ( __eventnames[i].id == event ) return __eventnames[i].name; roar_err_set(ROAR_ERROR_NOENT); return NULL; } // generic things: int roar_roardmx_message_new (struct roar_roardmx_message * mes) { BCHK(mes); memset(mes, 0, sizeof(struct roar_roardmx_message)); mes->version = ROAR_ROARDMX_VERSION; return 0; } // low level: //int roar_roardmx_message_set_flag(struct roar_roardmx_message * mes, unsigned char flag); //int roar_roardmx_message_set_len (struct roar_roardmx_message * mes, size_t type); //int roar_roardmx_message_get_data(struct roar_roardmx_message * mes, unsigned char ** data); // medium level: int roar_roardmx_message_set_type(struct roar_roardmx_message * mes, unsigned char type) { BCHK(mes); // check if type contains non-type bits. if ( (type | ROAR_ROARDMX_MASK_TYPE) - ROAR_ROARDMX_MASK_TYPE ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } mes->type = type; return 0; } int roar_roardmx_message_get_flag(struct roar_roardmx_message * mes, unsigned char * flag) { BCHK(mes); *flag = mes->flags; return 0; } int roar_roardmx_message_get_type(struct roar_roardmx_message * mes, unsigned char * type) { BCHK(mes); *type = mes->type; return 0; } int roar_roardmx_message_get_len (struct roar_roardmx_message * mes, size_t * length) { BCHK(mes); *length = mes->length; return 0; } // IO: int roar_roardmx_message_send(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) { BCHK(mes); BCHK(vio); if ( mes->length > ROAR_ROARDMX_DATA_LENGTH ) { // this is very fatal! roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION, NULL); roar_err_set(ROAR_ERROR_FAULT); return -1; } mes->data[0] = mes->version; mes->data[1] = (mes->flags & ROAR_ROARDMX_MASK_FLAGS) | (mes->type & ROAR_ROARDMX_MASK_TYPE ) ; mes->data[2] = mes->length; return roar_vio_write(vio, mes->data, mes->length + 3) == (ssize_t)(mes->length + 3) ? 0 : -1; } int roar_roardmx_message_recv(struct roar_roardmx_message * mes, struct roar_vio_calls * vio) { BCHK(mes); BCHK(vio); if ( roar_roardmx_message_new(mes) == -1 ) return -1; if ( roar_vio_read(vio, mes->data, 3) != 3 ) return -1; mes->version = mes->data[0]; if ( mes->version != ROAR_ROARDMX_VERSION ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } mes->flags = mes->data[1] & ROAR_ROARDMX_MASK_FLAGS; mes->type = mes->data[1] & ROAR_ROARDMX_MASK_TYPE; mes->length = mes->data[2]; if ( roar_vio_read(vio, &(mes->data[3]), mes->length) != (ssize_t)mes->length ) return -1; return 0; } // Data/high level: // * *: int roar_roardmx_message_add_chanval(struct roar_roardmx_message * mes, uint16_t channel, unsigned char val) { register uint16_t * chan; BCHK(mes); switch (mes->type) { case ROAR_ROARDMX_TYPE_SSET: case ROAR_ROARDMX_TYPE_INC8S: break; default: roar_err_set(ROAR_ERROR_TYPEMM); return -1; break; } if ( (mes->length + 3) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long roar_err_set(ROAR_ERROR_NOSPC); return -1; } chan = (uint16_t *) &(mes->data[mes->length + 3]); *chan = ROAR_HOST2NET16(channel); mes->data[mes->length + 2 + 3] = val; mes->length += 3; return 0; } int roar_roardmx_message_get_chanval(struct roar_roardmx_message * mes, uint16_t * channel, unsigned char * val, int index) { register uint16_t * chan; BCHK(mes); if ( index < 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( mes->version != ROAR_ROARDMX_VERSION ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } switch (mes->type) { case ROAR_ROARDMX_TYPE_SSET: case ROAR_ROARDMX_TYPE_INC8S: if ( index >= (ROAR_ROARDMX_DATA_LENGTH/3) ) return -1; *val = mes->data[3 * index + 2 + 3]; chan = (uint16_t *) &(mes->data[3 + 3 * index]); *channel = ROAR_NET2HOST16(*chan); return 0; break; } roar_err_set(ROAR_ERROR_NSTYPE); return -1; } int roar_roardmx_message_numchannels(struct roar_roardmx_message * mes) { BCHK(mes); if ( mes->version != ROAR_ROARDMX_VERSION ) { roar_err_set(ROAR_ERROR_NSVERSION); return -1; } switch (mes->type) { case ROAR_ROARDMX_TYPE_SSET: case ROAR_ROARDMX_TYPE_INC8S: return mes->length / 3; break; case ROAR_ROARDMX_TYPE_IPO1: return mes->length / 6; break; case ROAR_ROARDMX_TYPE_IPO4: return mes->length / 12; break; case ROAR_ROARDMX_TYPE_RANGESET: return mes->length / 5; break; case ROAR_ROARDMX_TYPE_EVENT: case ROAR_ROARDMX_TYPE_CONTROL: return 0; break; } roar_err_set(ROAR_ERROR_NSTYPE); return -1; } // * SSET: int roar_roardmx_message_new_sset (struct roar_roardmx_message * mes) { BCHK(mes); if ( roar_roardmx_message_new(mes) == -1 ) return -1; mes->type = ROAR_ROARDMX_TYPE_SSET; return 0; } // * IPO1: // Not yet supported. // * IPO4: // Not yet supported. // * INC8S: // Not yet supported. // * RANGESET: // Not yet supported. // * EVENT: int roar_roardmx_message_new_event(struct roar_roardmx_message * mes) { BCHK(mes); if ( roar_roardmx_message_new(mes) == -1 ) return -1; mes->type = ROAR_ROARDMX_TYPE_EVENT; return 0; } int roar_roardmx_message_add_events(struct roar_roardmx_message * mes, const uint8_t * events, size_t len) { BCHK(mes); if ( mes->type != ROAR_ROARDMX_TYPE_EVENT ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } if ( (mes->length + len) > ROAR_ROARDMX_DATA_LENGTH ) { // message would be to long roar_err_set(ROAR_ERROR_NOSPC); return -1; } memcpy(mes->data + 3 + mes->length, events, len); mes->length += len; return 0; } int roar_roardmx_message_get_events(struct roar_roardmx_message * mes, const uint8_t ** events, size_t * len) { BCHK(mes); if ( mes->type != ROAR_ROARDMX_TYPE_EVENT ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } *events = (const uint8_t *)(mes->data + 3); *len = mes->length; return 0; } // * CONTROL: // Not yet supported. //ll �����������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarmidi/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�014765� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarmidi/Makefile������������������������������������������������������������0000644�0001750�0001750�00000001344�12072565215�016423� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroarmidi SLIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) OBJS=libroarmidi.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroarmidi CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) -L../lib/ $(LDPATH) LIBS = $(LIBROARMIDI_NS) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(LIBROARMIDI_V) -o $(SLIB) ${OBJS} ${LIBS} $(ALIB): ${OBJS} ${AR} cru $(ALIB) ${OBJS} ${RANLIB} $(ALIB) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarmidi/libroarmidi.c�������������������������������������������������������0000644�0001750�0001750�00000001710�12264733576�017433� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarmidi.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of libroardsp a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroardsp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "libroarmidi.h" //ll ��������������������������������������������������������roaraudio-1.0beta11/libroaross/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553175�014653� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaross/Makefile�������������������������������������������������������������0000644�0001750�0001750�00000001354�12072565215�016306� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroaross SLIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) OBJS=libroaross.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroar CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) $(LDPATH) -L../lib LIBS = $(LIBROAR) $(LIBROARLIGHT) $(lib_dl) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(COMMON_SOVERSION) -o $(SLIB) ${OBJS} ${LIBS} $(ALIB): ${OBJS} ${AR} cru $(ALIB) ${OBJS} ${RANLIB} $(ALIB) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaross/libroaross.c���������������������������������������������������������0000644�0001750�0001750�00000157641�12264733576�017216� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroaross.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include "roaraudio.h" #include "libroarlight/libroarlight.h" #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) #if defined(__OpenBSD__) || defined(__NetBSD__) #include <soundcard.h> #else #include <sys/soundcard.h> #endif #include <sys/ioctl.h> #ifdef ROAR_HAVE_H_SYS_TYPES #include <sys/types.h> #endif #ifdef ROAR_HAVE_H_FCNTL #include <fcntl.h> #endif #ifdef ROAR_HAVE_H_UNISTD #include <unistd.h> #endif #include <sys/stat.h> #include <dlfcn.h> #include <stdarg.h> #if defined(RTLD_NEXT) #define REAL_LIBC RTLD_NEXT #else #define REAL_LIBC ((void *) -1L) #endif #ifndef ENOTSUP #define ENOTSUP ENOSYS #endif #ifndef O_DIRECTORY #define O_DIRECTORY 0 #endif #ifndef O_DIRECT #define O_DIRECT 0 #endif #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif #ifndef O_NOATIME #define O_NOATIME 0 #endif #define _O_PARA_DIR (O_RDONLY|O_WRONLY|O_RDWR) #define _O_PARA_IGN (O_DIRECT|O_APPEND|O_LARGEFILE|O_NOATIME|O_NOCTTY|O_TRUNC) #if defined(ROAR_OS_NETBSD) && defined(ioctl) #define IOCTL_IS_ALIAS #endif #ifdef ROAR_OS_FREEBSD #define _VA_ARGS_MODE_T int #else #define _VA_ARGS_MODE_T mode_t #endif #ifdef ROAR_OS_FREEBSD #define _CREAT_ARG_PATHNAME path #else #define _CREAT_ARG_PATHNAME pathname #endif #ifdef ROAR_OS_NETBSD #define IOCTL() int _oss_ioctl __P((int fd, unsigned long com, void *argp)) #define map_args int __fd = fd; unsigned long int __request = com #elif defined(ROAR_TARGET_CYGWIN) #define IOCTL() int ioctl (int __fd, int __cmd, ...) #define map_args unsigned long int __request = __cmd; void * argp #define va_argp #define ioctl_lastarg __cmd #else #define IOCTL() int ioctl (int __fd, unsigned long int __request, ...) #define map_args void * argp #define va_argp #define ioctl_lastarg __request #endif #define OSS_VOLUME_SCALE 100 #define _MAX_POINTER 8 // handle type: #define HT_NONE 0 /* Unused object */ #define HT_STREAM 1 /* Stream with no specal handling needed */ #define HT_MIXER 2 /* Mixer device */ #define HT_WAVEFORM 3 /* Waveform device */ #define HT_MIDI 4 /* MIDI device */ #define HT_DMX 5 /* DMX512/DMX4Linux device */ #define HT_VIO 6 /* General VIO object */ #define HT_STATIC 7 /* Static file */ struct session { int refc; struct roar_connection con; }; static struct session _session = {.refc = 0}; struct handle { int refc; // refrence counter struct session * session; int type; int sysio_flags; struct roar_stream stream; struct roar_vio_calls stream_vio; int stream_dir; int stream_opened; size_t stream_buffersize; size_t readc, writec; size_t pos; union { struct { char * data; size_t len; } sf; } userdata; }; static struct { int (*open)(const char *pathname, int flags, mode_t mode); int (*close)(int fd); ssize_t (*write)(int fd, const void *buf, size_t count); ssize_t (*read)(int fd, void *buf, size_t count); #ifndef IOCTL_IS_ALIAS int (*ioctl)(int d, int request, ...); #endif off_t (*lseek)(int fildes, off_t offset, int whence); FILE *(*fopen)(const char *path, const char *mode); int (*dup)(int oldfd); int (*dup2)(int oldfd, int newfd); int (*select)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int (*fcntl)(int fd, int cmd, ...); int (*access)(const char *pathname, int mode); int (*open64)(const char *__file, int __oflag, ...); int (*creat)(const char *_CREAT_ARG_PATHNAME, mode_t mode); #ifndef __clang__ int (*stat)(const char *path, struct stat *buf); int (*fstat)(int filedes, struct stat *buf); int (*lstat)(const char *path, struct stat *buf); #endif } _os; static struct { struct { int volume; int pcm; int line; int line1; int line2; int line3; int digital1; int digital2; int digital3; } sid; } _mix_settings = { .sid = { .volume = -1, .pcm = -1, .line = 0, .line1 = 1, .line2 = 2, .line3 = 3, .digital1 = 1, .digital2 = 2, .digital3 = 3 } }; static struct pointer { int fh; struct handle * handle; } _ptr[_MAX_POINTER]; static char _sf__dev_sndstat[] = "Sound Driver:RoarAudio\n" "Config options: 0\n" "\n" "Installed drivers:\n" "Type 10: RoarAudio emulation\n" "\n" "Card config:\n" "\n" "Audio devices:\n" "0: RoarAudio OSS emulation (DUPLEX)\n" "\n" "Midi devices:\n" "0: RoarAudio OSS emulation MIDI\n" "\n" "Timers:\n" "\n" "Mixers:\n" "0: RoarAudio OSS emulation Mixer\n" ; static struct devices { char * prefix; int type; size_t len; void * userdata; struct handle * (*open)(const char * file, int flags, mode_t mode, struct devices * ptr); } _device_list[] = { {"/dev/dsp", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/dsp?", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/audio", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/audio?", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/sound/dsp", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/sound/dsp?", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/sound/audio", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/sound/audio?", HT_WAVEFORM, 0, NULL, NULL}, {"/dev/mixer", HT_MIXER, 0, NULL, NULL}, {"/dev/mixer?", HT_MIXER, 0, NULL, NULL}, {"/dev/sound/mixer", HT_MIXER, 0, NULL, NULL}, {"/dev/sound/mixer?", HT_MIXER, 0, NULL, NULL}, {"/dev/midi", HT_MIDI, 0, NULL, NULL}, {"/dev/midi?", HT_MIDI, 0, NULL, NULL}, {"/dev/rmidi", HT_MIDI, 0, NULL, NULL}, {"/dev/rmidi?", HT_MIDI, 0, NULL, NULL}, {"/dev/sound/midi", HT_MIDI, 0, NULL, NULL}, {"/dev/sound/midi?", HT_MIDI, 0, NULL, NULL}, {"/dev/sound/rmidi", HT_MIDI, 0, NULL, NULL}, {"/dev/sound/rmidi?", HT_MIDI, 0, NULL, NULL}, {"/dev/dmx", HT_DMX, 0, NULL, NULL}, {"/dev/dmx?", HT_DMX, 0, NULL, NULL}, {"/dev/misc/dmx", HT_DMX, 0, NULL, NULL}, {"/dev/misc/dmx?", HT_DMX, 0, NULL, NULL}, {"/dev/dmxin", HT_DMX, 0, NULL, NULL}, {"/dev/dmxin?", HT_DMX, 0, NULL, NULL}, {"/dev/misc/dmxin", HT_DMX, 0, NULL, NULL}, {"/dev/misc/dmxin?", HT_DMX, 0, NULL, NULL}, {"/dev/sndstat", HT_STATIC, sizeof(_sf__dev_sndstat)-1, _sf__dev_sndstat, NULL}, #ifdef ROAR_DEFAULT_OSS_DEV {ROAR_DEFAULT_OSS_DEV, HT_WAVEFORM, 0, NULL, NULL}, #endif #ifdef ROAR_DEFAULT_OSS_MIX_DEV {ROAR_DEFAULT_OSS_MIX_DEV, HT_MIXER, 0, NULL, NULL}, #endif {NULL, HT_NONE, 0, NULL, NULL}, }; static int _update_nonblock (struct handle * handle); static void _init_os (void) { memset(&_os, 0, sizeof(_os)); // if call roar_dl_getsym() here all applications will segfaul. // why? _os.open = dlsym(REAL_LIBC, "open"); _os.close = dlsym(REAL_LIBC, "close"); _os.write = dlsym(REAL_LIBC, "write"); _os.read = dlsym(REAL_LIBC, "read"); #ifndef IOCTL_IS_ALIAS _os.ioctl = dlsym(REAL_LIBC, "ioctl"); #endif _os.lseek = dlsym(REAL_LIBC, "lseek"); _os.fopen = dlsym(REAL_LIBC, "fopen"); _os.dup = dlsym(REAL_LIBC, "dup"); _os.dup2 = dlsym(REAL_LIBC, "dup2"); _os.select = dlsym(REAL_LIBC, "select"); _os.fcntl = dlsym(REAL_LIBC, "fcntl"); _os.access = dlsym(REAL_LIBC, "access"); _os.open64 = dlsym(REAL_LIBC, "open64"); _os.creat = dlsym(REAL_LIBC, "creat"); #ifndef __clang__ _os.stat = dlsym(REAL_LIBC, "stat"); _os.fstat = dlsym(REAL_LIBC, "fstat"); _os.lstat = dlsym(REAL_LIBC, "lstat"); #endif } static void _init_ptr (void) { int i; for (i = 0; i < _MAX_POINTER; i++) { _ptr[i].fh = -1; } } static void _init (void) { static int inited = 0; if ( !inited ) { _init_os(); _init_ptr(); roar_vio_select(NULL, 0, NULL, NULL); inited++; } } static void _find_volume_sid (struct session * session) { int i; int num; int id[ROAR_STREAMS_MAX]; struct roar_stream s; char name[1024]; ROAR_DBG("_find_volume_sid(session=%p) = ?", session); if ( (num = roar_list_streams(&(session->con), id, ROAR_STREAMS_MAX)) == -1 ) { return; } for (i = 0; i < num; i++) { if ( roar_get_stream(&(session->con), &s, id[i]) == -1 ) continue; if ( s.dir != ROAR_DIR_MIXING ) continue; if ( roar_stream_get_name(&(session->con), &s, name, 1024) == -1 ) continue; if ( !strcasecmp(name, "Waveform Mixer") ) { _mix_settings.sid.volume = id[i]; ROAR_DBG("_find_volume_sid(session=%p): found waveform mixer at sid %i", session, id[i]); ROAR_DBG("_find_volume_sid(session=%p) = (void)", session); return; } } } static int _open_dummy (void) { int p[2]; ROAR_DBG("_open_dummy(void) = ?"); if ( pipe(p) == -1 ) return -1; close(p[1]); ROAR_DBG("_open_dummy(void) = %i", p[0]); return p[0]; } static struct session * _open_session (const char * server, const char * name) { struct session * ses = &_session; int new_session = roar_env_get("ROAR_OSS_NEW_SESSION") == NULL ? 0 : 1; ROAR_DBG("_open_session(server='%s', name='%s') = ?", server, name); ROAR_DBG("_open_session(server='%s', name='%s'): _session.refc=%i", server, name, _session.refc); if ( new_session ) { ses = roar_mm_malloc(sizeof(struct session)); if ( ses == NULL ) return NULL; memset(ses, 0, sizeof(struct session)); } if ( ses->refc == 0 ) { if ( name == NULL ) name = roar_env_get("ROAR_OSS_CLIENT_NAME"); if ( name == NULL ) name = "libroaross client"; if ( roar_simple_connect(&(ses->con), server, name) == -1 ) { if ( new_session ) roar_mm_free(ses); return NULL; } _find_volume_sid(ses); if ( !new_session ) { if ( roar_env_get("ROAR_OSS_KEEP_SESSION") != NULL ) ses->refc++; } } ses->refc++; ROAR_DBG("_open_session(server='%s', name='%s') = %p", server, name, ses); return ses; } static void _close_session(struct session * session) { if ( session == NULL ) return; session->refc--; ROAR_DBG("_close_session(session=%p): session->refc=%i", session, session->refc); if ( session->refc == 0 ) { roar_disconnect(&(session->con)); } if ( session != &_session ) roar_mm_free(session); } static struct handle * _open_handle(struct session * session) { struct handle * handle; ROAR_DBG("_open_handle(session=%p) = ?", session); if ( (handle = roar_mm_malloc(sizeof(struct handle))) == NULL ) return NULL; memset(handle, 0, sizeof(struct handle)); handle->refc = 1; handle->session = session; if ( session != NULL ) session->refc++; // TODO: better warp this handle->type = HT_NONE; handle->stream_dir = ROAR_DIR_PLAY; roar_stream_new(&(handle->stream), ROAR_RATE_DEFAULT, ROAR_CHANNELS_DEFAULT, ROAR_BITS_DEFAULT, ROAR_CODEC_DEFAULT); ROAR_DBG("_open_handle(session=%p) = %p", session, handle); return handle; } static void _close_handle(struct handle * handle) { int need_close = 0; if (handle == NULL) return; handle->refc--; ROAR_DBG("_close_handle(handle=%p): handle->refc=%i", handle, handle->refc); if ( handle->refc == 0 ) { switch (handle->type) { case HT_VIO: need_close = 1; break; case HT_STREAM: if ( handle->stream_opened ) need_close = 1; break; } if ( need_close ) roar_vio_close(&(handle->stream_vio)); if ( handle->session != NULL ) { handle->session->refc--; _close_session(handle->session); } roar_mm_free(handle); } } static struct pointer * _get_pointer_by_fh_or_new (int fh) { int i; for (i = 0; i < _MAX_POINTER; i++) { if ( _ptr[i].fh == fh ) return &(_ptr[i]); } return NULL; } static struct pointer * _get_pointer_by_fh (int fh) { if ( fh == -1 ) return NULL; return _get_pointer_by_fh_or_new(fh); } static struct pointer * _open_pointer(struct handle * handle) { struct pointer * ret = _get_pointer_by_fh_or_new(-1); ROAR_DBG("_open_pointer(handle=%p) = ?", handle); if ( ret == NULL ) { ROAR_DBG("_open_pointer(handle=%p) = NULL", handle); return NULL; } if ( (ret->fh = _open_dummy()) == -1 ) { ROAR_DBG("_open_pointer(handle=%p) = NULL", handle); return NULL; } ret->handle = handle; ROAR_DBG("_open_pointer(handle=%p) = %p", handle, ret); return ret; } static struct pointer * _attach_pointer(struct handle * handle, int fh) { struct pointer * ret = _get_pointer_by_fh_or_new(-1); if ( ret == NULL ) return NULL; if ( (ret->fh = fh) == -1 ) return NULL; ret->handle = handle; handle->refc++; return ret; } static void _close_pointer(struct pointer * pointer) { if ( pointer == NULL ) return; _os.close(pointer->fh); pointer->fh = -1; _close_handle(pointer->handle); } // ------------------------------------- // central function to find device: // ------------------------------------- static struct devices * _get_device (const char * pathname) { size_t len, pathlen; int i; int qm_match; ROAR_DBG("_get_device(pathname='%s') = ?", pathname); pathlen = strlen(pathname); for (i = 0; _device_list[i].prefix != NULL; i++) { len = strlen(_device_list[i].prefix); qm_match = 0; if ( _device_list[i].prefix[len-1] == '*' ) { len--; } else if ( _device_list[i].prefix[len-1] == '?' ) { qm_match = 1; len--; } else { len++; } if ( !strncmp(pathname, _device_list[i].prefix, len) ) { if ( !qm_match || pathlen == (len + 1) ) return &(_device_list[i]); } } ROAR_DBG("_get_device(pathname='%s') = NULL", pathname); return NULL; } // ------------------------------------- // central open function: // ------------------------------------- static int _open_file (const char *pathname, int flags) { struct session * session; struct handle * handle; struct pointer * pointer; struct devices * ptr = NULL; ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = ?", pathname, flags); /* * Flags we ignore: * O_DIRECT, O_APPEND, O_LARGEFILE, O_NOATIME, O_NOCTTY, O_TRUNC */ if ( (ptr = _get_device(pathname)) == NULL ) { ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -2", pathname, flags); return -2; } ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = ?", pathname, flags); #ifdef O_ASYNC if ( flags & O_ASYNC ) { ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1 // not supported O_ASYNC", pathname, flags); errno = ENOSYS; return -1; } #endif if ( flags & O_DIRECTORY ) { ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1 // invalid flags (O_DIRECTORY)", pathname, flags); errno = EINVAL; return -1; } if ( flags & O_EXCL ) { ROAR_WARN("_open_file(pathname='%s', flags=0x%x): This application is asked us for exclusive device access.", pathname, flags); ROAR_WARN("_open_file(pathname='%s', flags=0x%x): This is maybe not what you want.", pathname, flags); ROAR_WARN("_open_file(pathname='%s', flags=0x%x): We reject this according to OSS specs.", pathname, flags); ROAR_WARN("_open_file(pathname='%s', flags=0x%x): There should be a option in the application to switch this off.", pathname, flags); ROAR_WARN("_open_file(pathname='%s', flags=0x%x) = -1 // invalid flags (O_EXCL)", pathname, flags); errno = EINVAL; return -1; } ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = ?", pathname, flags); if ( ptr->type == HT_STATIC || ptr->type == HT_VIO ) { // non-session handles session = NULL; } else { if ( (session = _open_session(NULL, NULL)) == NULL ) { ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1", pathname, flags); return -1; } } if ( ptr->open != NULL ) { // TODO: Add support to pass mode (perms) to open. if ( (handle = ptr->open(pathname, flags, 0000, ptr)) == NULL ) { _close_session(session); ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1", pathname, flags); return -1; } } else { if ( (handle = _open_handle(session)) == NULL ) { _close_session(session); ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1", pathname, flags); return -1; } handle->type = ptr->type; handle->sysio_flags = flags; handle->stream_dir = -1; } switch (flags & _O_PARA_DIR) { case O_RDONLY: switch (ptr->type) { case HT_WAVEFORM: handle->stream_dir = ROAR_DIR_RECORD; break; case HT_MIDI: handle->stream_dir = ROAR_DIR_MIDI_OUT; break; case HT_DMX: handle->stream_dir = ROAR_DIR_LIGHT_OUT; break; case HT_MIXER: case HT_STATIC: break; default: ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1", pathname, flags); return -1; } break; case O_WRONLY: switch (ptr->type) { case HT_WAVEFORM: handle->stream_dir = ROAR_DIR_PLAY; break; case HT_MIDI: handle->stream_dir = ROAR_DIR_MIDI_IN; break; case HT_DMX: handle->stream_dir = ROAR_DIR_LIGHT_IN; break; case HT_MIXER: case HT_STATIC: break; default: ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1", pathname, flags); return -1; } break; case O_RDWR: switch (ptr->type) { case HT_WAVEFORM: handle->stream_dir = ROAR_DIR_RECPLAY; break; case HT_MIXER: case HT_STATIC: break; default: ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1", pathname, flags); return -1; } break; } switch (handle->type) { case HT_WAVEFORM: handle->type = HT_STREAM; break; case HT_MIDI: handle->type = HT_STREAM; handle->stream.info.rate = 0; handle->stream.info.bits = ROAR_MIDI_BITS; handle->stream.info.channels = ROAR_MIDI_CHANNELS_DEFAULT; handle->stream.info.codec = ROAR_CODEC_MIDI; break; case HT_DMX: handle->stream.info.rate = 0; handle->stream.info.bits = ROAR_LIGHT_BITS; handle->stream.info.channels = 512; handle->stream.info.codec = ROAR_CODEC_ROARDMX; break; case HT_STATIC: handle->userdata.sf.len = ptr->len; handle->userdata.sf.data = ptr->userdata; break; } ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = ?", pathname, flags); if ( (pointer = _open_pointer(handle)) == NULL ) { _close_handle(handle); ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = -1", pathname, flags); return -1; } ROAR_DBG("_open_file(pathname='%s', flags=0x%x) = %i", pathname, flags, pointer->fh); return pointer->fh; } // ------------------------------------- // VIO open function: // ------------------------------------- int libroaross_open_vio(struct handle ** handleret, struct roar_vio_calls ** vio, int flags) { struct handle * handle; struct pointer * pointer; _init(); if ( vio == NULL ) return -1; if ( (handle = _open_handle(NULL)) == NULL ) { return -1; } handle->type = HT_VIO; handle->sysio_flags = flags; if ( roar_vio_clear_calls(&(handle->stream_vio)) == -1 ) { _close_handle(handle); return -1; } *vio = &(handle->stream_vio); if ( handleret != NULL ) *handleret = handle; if ( (pointer = _open_pointer(handle)) == NULL ) { _close_handle(handle); return -1; } return pointer->fh; } // ------------------------------------- // open function for streams: // ------------------------------------- static int _open_stream (struct handle * handle) { // FIXME: this should be re-written much more cleanly: if ( handle == NULL ) return -1; if ( roar_vio_simple_new_stream_obj(&(handle->stream_vio), &(handle->session->con), &(handle->stream), handle->stream.info.rate, handle->stream.info.channels, handle->stream.info.bits, handle->stream.info.codec, handle->stream_dir, -1 /* TODO: Find better way to select mixer ID. */ ) == -1 ) return -1; handle->stream_opened++; _mix_settings.sid.pcm = roar_stream_get_id(&(handle->stream)); _update_nonblock(handle); return 0; } // ------------------------------------- // function to update O_NONBLOCK: // ------------------------------------- static int _update_nonblock (struct handle * handle) { int opened = 0; int state = handle->sysio_flags & O_NONBLOCK ? ROAR_SOCKET_NONBLOCK : ROAR_SOCKET_BLOCK; switch (handle->type) { case HT_NONE: case HT_STATIC: case HT_MIXER: // we can ignore setting of nonblock flag here. return 0; break; case HT_VIO: opened = 1; break; case HT_STREAM: case HT_WAVEFORM: case HT_MIDI: case HT_DMX: opened = handle->stream_opened; break; } if ( opened ) { return roar_vio_nonblock(&(handle->stream_vio), state); } return 0; } // ------------------------------------- // function to parse format: // ------------------------------------- static int _ioctl_stream_format (struct handle * handle, int format) { struct roar_audio_info * info = &(handle->stream.info); switch (format) { case AFMT_S8: info->bits = 8; info->codec = ROAR_CODEC_PCM_S_LE; break; case AFMT_U8: info->bits = 8; info->codec = ROAR_CODEC_PCM_U_LE; break; case AFMT_S16_BE: info->bits = 16; info->codec = ROAR_CODEC_PCM_S_BE; break; case AFMT_S16_LE: info->bits = 16; info->codec = ROAR_CODEC_PCM_S_LE; break; case AFMT_U16_BE: info->bits = 16; info->codec = ROAR_CODEC_PCM_U_BE; break; case AFMT_U16_LE: info->bits = 16; info->codec = ROAR_CODEC_PCM_U_LE; break; #ifdef AFMT_S32_BE case AFMT_S32_BE: info->bits = 32; info->codec = ROAR_CODEC_PCM_S_BE; break; #endif #ifdef AFMT_S32_LE case AFMT_S32_LE: info->bits = 32; info->codec = ROAR_CODEC_PCM_S_LE; break; #endif case AFMT_A_LAW: info->bits = 8; info->codec = ROAR_CODEC_ALAW; break; case AFMT_MU_LAW: info->bits = 8; info->codec = ROAR_CODEC_MULAW; break; #ifdef AFMT_VORBIS case AFMT_VORBIS: info->codec = ROAR_CODEC_OGG_VORBIS; break; #endif default: ROAR_DBG("_ioctl_stream_format(*): unsupported format"); errno = ENOSYS; return -1; break; } return 0; } static inline int _ioctl_stream_format_list (void) { int format = 0; format |= AFMT_S8; format |= AFMT_U8; format |= AFMT_S16_BE; format |= AFMT_S16_LE; format |= AFMT_U16_BE; format |= AFMT_U16_LE; #ifdef AFMT_S32_BE format |= AFMT_S32_BE; #endif #ifdef AFMT_S32_LE format |= AFMT_S32_LE; #endif format |= AFMT_A_LAW; format |= AFMT_MU_LAW; #ifdef AFMT_VORBIS format |= AFMT_VORBIS; #endif return format; } // ------------------------------------- // mixer ioctls: // ------------------------------------- static int _ioctl_mixer (struct handle * handle, long unsigned int req, void * vp) { mixer_info * info; int channels; struct roar_mixer_settings mixer; int o_w = 0; int o_sid = -1; int * ip = vp; #if defined(DEBUG) && defined(DEBUG_IOCTL_NAMES) char * name = NULL; #endif #if defined(DEBUG) && defined(DEBUG_IOCTL_NAMES) switch (req) { #if 0 case SNDCTL_MIX_DESCRIPTION: name = "SNDCTL_MIX_DESCRIPTION"; break; case SNDCTL_MIX_ENUMINFO: name = "SNDCTL_MIX_ENUMINFO"; break; case SNDCTL_MIX_EXTINFO: name = "SNDCTL_MIX_EXTINFO"; break; case SNDCTL_MIX_NREXT: name = "SNDCTL_MIX_NREXT"; break; case SNDCTL_MIX_NRMIX: name = "SNDCTL_MIX_NRMIX"; break; case SNDCTL_MIX_READ: name = "SNDCTL_MIX_READ"; break; case SNDCTL_MIX_WRITE: name = "SNDCTL_MIX_WRITE"; break; #endif // case SOUND_MIXER_INFO: name = "SOUND_MIXER_INFO"; break; case SOUND_OLD_MIXER_INFO: name = "SOUND_OLD_MIXER_INFO"; break; case SOUND_MIXER_ACCESS: name = "SOUND_MIXER_ACCESS"; break; case SOUND_MIXER_AGC: name = "SOUND_MIXER_AGC"; break; case SOUND_MIXER_3DSE: name = "SOUND_MIXER_3DSE"; break; case SOUND_MIXER_GETLEVELS: name = "SOUND_MIXER_GETLEVELS"; break; case SOUND_MIXER_SETLEVELS: name = "SOUND_MIXER_SETLEVELS"; break; case SOUND_MIXER_PRIVATE1: name = "SOUND_MIXER_PRIVATE1"; break; case SOUND_MIXER_PRIVATE2: name = "SOUND_MIXER_PRIVATE2"; break; case SOUND_MIXER_PRIVATE3: name = "SOUND_MIXER_PRIVATE3"; break; case SOUND_MIXER_PRIVATE4: name = "SOUND_MIXER_PRIVATE4"; break; case SOUND_MIXER_PRIVATE5: name = "SOUND_MIXER_PRIVATE5"; break; case OSS_GETVERSION: name = "OSS_GETVERSION"; break; // case SOUND_MIXER_READ_CAPS: name = "SOUND_MIXER_READ_CAPS"; break; case SOUND_MIXER_READ_MUTE: name = "SOUND_MIXER_READ_MUTE"; break; /* case : name = ""; break; case : name = ""; break; */ } if ( name != NULL ) { ROAR_DBG("_ioctl_mixer(handle=%p, req=0x%lX, ip=%p): unspported mixer command %s", handle, req, ip, name); ROAR_DBG("_ioctl_mixer(handle=%p, req=0x%lX, ip=%p) = -1 // errno = ENOSYS", handle, req, ip); errno = ENOSYS; return -1; } #endif switch (req) { case SOUND_MIXER_READ_VOLUME: o_w = 0; o_sid = _mix_settings.sid.volume; break; case SOUND_MIXER_READ_LINE: o_w = 0; o_sid = _mix_settings.sid.line; break; case SOUND_MIXER_READ_LINE1: o_w = 0; o_sid = _mix_settings.sid.line1; break; case SOUND_MIXER_READ_LINE2: o_w = 0; o_sid = _mix_settings.sid.line2; break; case SOUND_MIXER_READ_LINE3: o_w = 0; o_sid = _mix_settings.sid.line3; break; #if 0 case SOUND_MIXER_READ_DIGITAL1: o_w = 0; o_sid = _mix_settings.sid.digital1; break; case SOUND_MIXER_READ_DIGITAL2: o_w = 0; o_sid = _mix_settings.sid.digital2; break; case SOUND_MIXER_READ_DIGITAL3: o_w = 0; o_sid = _mix_settings.sid.digital3; break; #endif case SOUND_MIXER_WRITE_VOLUME: o_w = 1; o_sid = _mix_settings.sid.volume; break; case SOUND_MIXER_WRITE_LINE: o_w = 1; o_sid = _mix_settings.sid.line; break; case SOUND_MIXER_WRITE_LINE1: o_w = 1; o_sid = _mix_settings.sid.line1; break; case SOUND_MIXER_WRITE_LINE2: o_w = 1; o_sid = _mix_settings.sid.line2; break; case SOUND_MIXER_WRITE_LINE3: o_w = 1; o_sid = _mix_settings.sid.line3; break; #if 0 case SOUND_MIXER_WRITE_DIGITAL1: o_w = 1; o_sid = _mix_settings.sid.digital1; break; case SOUND_MIXER_WRITE_DIGITAL2: o_w = 1; o_sid = _mix_settings.sid.digital2; break; case SOUND_MIXER_WRITE_DIGITAL3: o_w = 1; o_sid = _mix_settings.sid.digital3; break; #endif // we handle PCM seperatly as we want to be abled to abled to handle it on a stream (not mixer), too: case SOUND_MIXER_READ_PCM: o_w = 0; if ( handle->type == HT_STREAM ) { o_sid = roar_stream_get_id(&(handle->stream)); } else { o_sid = _mix_settings.sid.pcm; } break; case SOUND_MIXER_WRITE_PCM: o_w = 1; if ( handle->type == HT_STREAM ) { o_sid = roar_stream_get_id(&(handle->stream)); } else { o_sid = _mix_settings.sid.pcm; } break; } if ( o_sid != -1 ) { // set/get volume if ( o_w ) { mixer.scale = OSS_VOLUME_SCALE; mixer.mixer[0] = ( *ip & 0xFF); mixer.mixer[1] = ((*ip >> 8) & 0xFF); if ( roar_set_vol(&(handle->session->con), o_sid, &mixer, 2, ROAR_SET_VOL_UNMAPPED) == -1 ) { errno = EIO; return -1; } return 0; } else { if ( roar_get_vol(&(handle->session->con), o_sid, &mixer, &channels) == -1 ) { errno = EIO; return -1; } *ip = ((OSS_VOLUME_SCALE*mixer.mixer[0])/mixer.scale) | (((OSS_VOLUME_SCALE*mixer.mixer[0])/mixer.scale)<<8); return 0; } } switch (req) { case SOUND_MIXER_READ_STEREODEVS: /* FIXME: check the streams for channel config */ case SOUND_MIXER_READ_DEVMASK: *ip = 0; if ( _mix_settings.sid.volume != -1 ) *ip |= SOUND_MASK_VOLUME; if ( _mix_settings.sid.pcm != -1 ) *ip |= SOUND_MASK_PCM; if ( _mix_settings.sid.line != -1 ) *ip |= SOUND_MASK_LINE; if ( _mix_settings.sid.line1 != -1 ) *ip |= SOUND_MASK_LINE1; if ( _mix_settings.sid.line2 != -1 ) *ip |= SOUND_MASK_LINE2; if ( _mix_settings.sid.line3 != -1 ) *ip |= SOUND_MASK_LINE3; if ( _mix_settings.sid.digital1 != -1 ) #if 0 *ip |= SOUND_MASK_DIGITAL1; if ( _mix_settings.sid.digital2 != -1 ) *ip |= SOUND_MASK_DIGITAL2; if ( _mix_settings.sid.digital3 != -1 ) *ip |= SOUND_MASK_DIGITAL3; #endif return 0; break; case SOUND_MIXER_READ_RECMASK: case SOUND_MIXER_READ_RECSRC: *ip = SOUND_MASK_VOLUME; // we can currently only read from mixer return 0; break; case SOUND_MIXER_WRITE_RECSRC: if ( *ip == SOUND_MASK_VOLUME ) { return 0; } else { errno = ENOTSUP; return -1; } break; case SOUND_MIXER_READ_CAPS: *ip = 0; return 0; break; case SOUND_MIXER_INFO: info = vp; memset(info, 0, sizeof(*info)); strcpy(info->id, "RoarAudio"); strcpy(info->name, "RoarAudio"); return 0; break; } ROAR_DBG("_ioctl_mixer(handle=%p, req=0x%lX, ip=%p): unknown mixer CTL", handle, req, ip); // _os.ioctl(-1, req, ip); ROAR_DBG("_ioctl_mixer(handle=%p, req=0x%lX, ip=%p) = -1 // errno = ENOSYS", handle, req, ip); errno = ENOSYS; return -1; } // ------------------------------------- // buffer size calculation: // ------------------------------------- static size_t _get_stream_buffersize (struct handle * handle) { if ( handle->stream_buffersize ) return handle->stream_buffersize; return handle->stream_buffersize = handle->stream.info.rate * handle->stream.info.channels * handle->stream.info.bits / 800; } // ------------------------------------- // emulated functions follow: // ------------------------------------- int open(const char *pathname, int flags, ...) { int ret; mode_t mode = 0; va_list args; _init(); if ( pathname == NULL ) { errno = EFAULT; return -1; } ROAR_DBG("open(pathname='%s', flags=%x, ...) = ?\n", pathname, flags); ret = _open_file(pathname, flags); switch (ret) { case -2: // continue as normal, use _op.open() ROAR_DBG("open(pathname='%s', flags=%x, ...): is not handled by us, pass to kernel\n", pathname, flags); break; case -1: // pass error to caller return -1; break; default: // return successfully opened pointer to caller return ret; break; } if (flags & O_CREAT) { va_start(args, flags); mode = va_arg(args, _VA_ARGS_MODE_T); va_end(args); } return _os.open(pathname, flags, mode); } int open64(const char *__file, int __oflag, ...) { int ret; mode_t mode = 0; va_list args; _init(); if ( __file == NULL ) { errno = EFAULT; return -1; } ROAR_DBG("open64(__file='%s', __oflags=%x, ...) = ?", __file, __oflag); ret = _open_file(__file, __oflag); switch (ret) { case -2: // continue as normal, use _op.open() ROAR_DBG("open64(__file='%s', __oflags=%x, ...): not for us, passing to kernel", __file, __oflag); break; case -1: // pass error to caller return -1; break; default: // return successfully opened pointer to caller ROAR_DBG("open64(__file='%s', __oflags=%x, ...) = %i", __file, __oflag, ret); return ret; break; } if (__oflag & O_CREAT) { va_start(args, __oflag); mode = va_arg(args, _VA_ARGS_MODE_T); va_end(args); } if ( _os.open64 != NULL ) { return _os.open64(__file, __oflag, mode); } else { #ifdef O_LARGEFILE return _os.open(__file, __oflag | O_LARGEFILE, mode); #else return _os.open(__file, __oflag, mode); #endif } } int close(int fd) { struct pointer * pointer; _init(); if ( (pointer = _get_pointer_by_fh(fd)) != NULL ) { _close_pointer(pointer); return 0; } return _os.close(fd); } ssize_t write(int fd, const void *buf, size_t count) { struct roar_roardmx_message roardmxmsg; struct pointer * pointer; ssize_t ret; size_t i; _init(); if ( (pointer = _get_pointer_by_fh(fd)) != NULL ) { ROAR_DBG("write(fd=%i, buf=%p, count=%lu) = ? // pointer write", fd, buf, (long unsigned int) count); switch (pointer->handle->type) { case HT_STREAM: // handle stream specific stuff if ( pointer->handle->stream_opened == 0 ) { if ( _open_stream(pointer->handle) == -1 ) { errno = EIO; return -1; } } case HT_VIO: // from here we only look at the VIO object of streams, or handle simple VIOs ret = roar_vio_write(&(pointer->handle->stream_vio), (char*)buf, count); if ( ret > 0 ) pointer->handle->writec += ret; return ret; break; case HT_DMX: // DMX need specal handling as we need to convert the protocol if ( pointer->handle->stream_opened == 0 ) { if ( _open_stream(pointer->handle) == -1 ) { errno = EIO; return -1; } } if ( count > 0 ) { if ( roar_roardmx_message_new_sset(&roardmxmsg) == -1 ) { errno = EIO; return -1; } for (i = 0; i < count; i++) { if ( roar_roardmx_message_add_chanval(&roardmxmsg, pointer->handle->pos + i, ((unsigned char*)buf)[i]) == -1 ) { #ifdef EMSGSIZE errno = EMSGSIZE; #else errno = EIO; #endif return -1; } } if ( roar_roardmx_message_send(&roardmxmsg, &(pointer->handle->stream_vio)) == -1 ) { errno = EIO; return -1; } } pointer->handle->pos += count; return count; break; default: // we don't know what to do with other types errno = EINVAL; return -1; break; } } return _os.write(fd, buf, count); } ssize_t read(int fd, void *buf, size_t count) { struct pointer * pointer; ssize_t ret; _init(); if ( (pointer = _get_pointer_by_fh(fd)) != NULL ) { ROAR_DBG("read(fd=%i, buf=%p, count=%lu) = ? // pointer read", fd, buf, (long unsigned int)count); switch (pointer->handle->type) { case HT_STREAM: if ( pointer->handle->stream_opened == 0 ) { if ( _open_stream(pointer->handle) == -1 ) { errno = EIO; return -1; } } case HT_VIO: ret = roar_vio_read(&(pointer->handle->stream_vio), buf, count); if ( ret > 0 ) pointer->handle->readc += ret; return ret; break; case HT_STATIC: ROAR_DBG("read(fd=%i, buf=%p, count=%lu) = ? // type=HT_STATIC", fd, buf, (long unsigned int)count); ret = pointer->handle->pos + count; // calc the end of the read if ( ret > (ssize_t)pointer->handle->userdata.sf.len ) { count = pointer->handle->userdata.sf.len - pointer->handle->pos; } memcpy(buf, pointer->handle->userdata.sf.data + pointer->handle->pos, count); pointer->handle->pos += count; return count; break; default: errno = EINVAL; return -1; break; } } return _os.read(fd, buf, count); } off_t lseek(int fildes, off_t offset, int whence) { struct pointer * pointer; ssize_t tmp; _init(); if ( (pointer = _get_pointer_by_fh(fildes)) != NULL ) { switch (pointer->handle->type) { case HT_DMX: switch (whence) { case SEEK_SET: pointer->handle->pos = offset; break; case SEEK_CUR: pointer->handle->pos += offset; break; case SEEK_END: default: errno = EINVAL; return -1; break; } return pointer->handle->pos; break; case HT_VIO: return roar_vio_lseek(&(pointer->handle->stream_vio), offset, whence); break; case HT_STATIC: switch (whence) { case SEEK_SET: if ( offset < 0 || offset > (ssize_t)pointer->handle->userdata.sf.len ) { errno = EINVAL; return -1; } pointer->handle->pos = offset; break; case SEEK_CUR: tmp = pointer->handle->pos + offset; if ( tmp < 0 || tmp > (ssize_t)pointer->handle->userdata.sf.len ) { errno = EINVAL; return -1; } pointer->handle->pos = tmp; break; case SEEK_END: tmp = pointer->handle->userdata.sf.len + offset; if ( tmp < 0 || tmp > (ssize_t)pointer->handle->userdata.sf.len ) { errno = EINVAL; return -1; } pointer->handle->pos = tmp; break; default: errno = EINVAL; return -1; break; } break; default: errno = EINVAL; return -1; break; } } return _os.lseek(fildes, offset, whence); } IOCTL() { map_args; struct pointer * pointer; struct handle * handle; int * ip = NULL; size_t tmp; audio_buf_info * bi; count_info * ci; #ifdef __FIXME__ char * nosys_reqname = NULL; #endif #ifdef va_argp va_list args; #endif _init(); ROAR_DBG("ioctl(__fd=%i, __request=0x%lX) = ?", __fd, (long unsigned int) __request); #ifdef va_argp va_start (args, ioctl_lastarg); argp = va_arg (args, void *); va_end (args); #endif // ROAR_DBG("ioctl(fh=%i, request=%i, ...) = ?", __fd, __request); ROAR_DBG("ioctl(__fd=%i, __request=0x%lX): argp=%p", __fd, (long unsigned int) __request, argp); if ( (pointer = _get_pointer_by_fh(__fd)) != NULL ) { ip = argp; // ROAR_DBG("ioctl(__fd=%i, __request=0x%lx): ip=%p", __fd, (long unsigned int) __request, ip); #ifdef __FIXME__ switch (__request) { case SOUND_PCM_READ_RATE: nosys_reqname = "SOUND_PCM_READ_RATE"; break; case SOUND_PCM_READ_CHANNELS: nosys_reqname = "SOUND_PCM_READ_CHANNELS"; break; case SOUND_PCM_READ_BITS: nosys_reqname = "SOUND_PCM_READ_BITS"; break; case SOUND_PCM_READ_FILTER: nosys_reqname = "SOUND_PCM_READ_FILTER"; break; case SNDCTL_COPR_RESET: nosys_reqname = "SNDCTL_COPR_RESET"; break; case SNDCTL_COPR_LOAD: nosys_reqname = "SNDCTL_COPR_LOAD"; break; case SNDCTL_COPR_HALT: nosys_reqname = "SNDCTL_COPR_HALT"; break; case SNDCTL_COPR_RDATA: nosys_reqname = "SNDCTL_COPR_RDATA"; break; case SNDCTL_COPR_RCODE: nosys_reqname = "SNDCTL_COPR_RCODE"; break; case SNDCTL_COPR_WDATA: nosys_reqname = "SNDCTL_COPR_WDATA"; break; case SNDCTL_COPR_WCODE: nosys_reqname = "SNDCTL_COPR_WCODE"; break; case SNDCTL_COPR_RUN: nosys_reqname = "SNDCTL_COPR_RUN"; break; case SNDCTL_COPR_SENDMSG: nosys_reqname = "SNDCTL_COPR_SENDMSG"; break; case SNDCTL_COPR_RCVMSG: nosys_reqname = "SNDCTL_COPR_RCVMSG"; break; case SNDCTL_DSP_GETCAPS: nosys_reqname = "SNDCTL_DSP_GETCAPS"; break; default: nosys_reqname = "<<<UNKNOWN>>>"; break; /* case : nosys_reqname = ""; break; case : nosys_reqname = ""; break; case : nosys_reqname = ""; break; */ } #endif switch ((handle = pointer->handle)->type) { case HT_STREAM: switch (__request) { case SNDCTL_DSP_RESET: case SNDCTL_DSP_POST: case SNDCTL_DSP_SYNC: // ignore for the moment. case SNDCTL_DSP_SETFRAGMENT: // any fragments should be ok for us... case SNDCTL_DSP_SETTRIGGER: // we should implement this using PAUSE flag. return 0; break; case SNDCTL_DSP_SETDUPLEX: ROAR_WARN("ioctl(__fd=%i, __request=0x%lX (SNDCTL_DSP_SETDUPLEX)): This call is obsolete since end of 90's. Stop using it.", __fd, (long unsigned int) __request); return 0; break; case SNDCTL_DSP_SPEED: handle->stream.info.rate = *ip; ROAR_DBG("ioctl(__fd=%i, __request=0x%lX): rate=%i", __fd, (long unsigned int) __request, *ip); return 0; break; case SNDCTL_DSP_CHANNELS: handle->stream.info.channels = *ip; ROAR_DBG("ioctl(__fd=%i, __request=0x%lX): channels=%i", __fd, (long unsigned int) __request, *ip); return 0; break; case SNDCTL_DSP_STEREO: handle->stream.info.channels = *ip ? 2 : 1; return 0; break; case SNDCTL_DSP_GETBLKSIZE: *ip = _get_stream_buffersize(handle); return 0; break; case SNDCTL_DSP_SETFMT: ROAR_DBG("ioctl(__fd=%i, __request=0x%lX): fmt=0x%x", __fd, (long unsigned int) __request, *ip); return _ioctl_stream_format(handle, *ip); break; case SNDCTL_DSP_GETFMTS: // ROAR_DBG("ioctl(__fd=%i, __request=0x%lX): ip=%p", __fd, (long unsigned int) __request, ip); *ip = _ioctl_stream_format_list(); return 0; break; case SNDCTL_DSP_GETOSPACE: case SNDCTL_DSP_GETISPACE: bi = argp; memset(bi, 0, sizeof(*bi)); bi->bytes = _get_stream_buffersize(handle); bi->fragments = 1; bi->fragsize = bi->bytes; bi->fragstotal = 1; return 0; break; case SNDCTL_DSP_GETOPTR: ROAR_DBG("ioctl(__fd=%i, __request=0x%lX): writec=%lu", __fd, (long unsigned int) __request, (long unsigned int) handle->writec); ci = argp; memset(ci, 0, sizeof(*ci)); ci->bytes = handle->writec; ci->blocks = ci->bytes / (tmp = _get_stream_buffersize(handle)); ci->ptr = ci->bytes % tmp; return 0; break; case SNDCTL_DSP_GETIPTR: ci = argp; memset(ci, 0, sizeof(*ci)); ci->bytes = handle->readc; ci->blocks = ci->bytes / (tmp = _get_stream_buffersize(handle)); ci->ptr = ci->bytes % tmp; return 0; break; #ifdef SNDCTL_DSP_GETPLAYVOL case SNDCTL_DSP_GETPLAYVOL: return _ioctl_mixer(handle, SOUND_MIXER_READ_PCM, argp); break; #endif #ifdef SNDCTL_DSP_SETPLAYVOL case SNDCTL_DSP_SETPLAYVOL: return _ioctl_mixer(handle, SOUND_MIXER_WRITE_PCM, argp); break; #endif #ifdef SNDCTL_DSP_NONBLOCK case SNDCTL_DSP_NONBLOCK: return fcntl(__fd, F_SETFL, handle->sysio_flags|O_NONBLOCK); break; #endif default: #ifdef __FIXME__ ROAR_DBG("ioctl(__fd=%i, __request=0x%lX (%s)) = -1 // errno = ENOSYS", __fd, (long unsigned int) __request, nosys_reqname); #else ROAR_DBG("ioctl(__fd=%i, __request=0x%lX) = -1 // errno = ENOSYS", __fd, (long unsigned int) __request); #endif errno = ENOSYS; return -1; } break; case HT_MIXER: return _ioctl_mixer(handle, __request, argp); break; default: ROAR_DBG("ioctl(__fd=%i, __request=0x%lX): unknown handle type: no ioctl()s supported", __fd, (long unsigned int) __request); ROAR_DBG("ioctl(__fd=%i, __request=0x%lX) = -1 // errno = ENOSYS", __fd, (long unsigned int) __request); errno = EINVAL; return -1; break; } } #ifdef IOCTL_IS_ALIAS errno = ENOSYS; return -1; #else ROAR_DBG("ioctl(__fd=%i, __request=0x%lX, argp=%p): not for us, passing to kernel", __fd, (long unsigned int) __request, argp); return _os.ioctl(__fd, __request, argp); #endif } int dup(int oldfd) { struct pointer * pointer; int ret; _init(); ret = _os.dup(oldfd); if (ret == -1) return -1; if ( (pointer = _get_pointer_by_fh(oldfd)) != NULL ) { if ( _attach_pointer(pointer->handle, ret) == NULL ) { _os.close(ret); return -1; } } return ret; } int dup2(int oldfd, int newfd) { struct pointer * pointer; int ret; _init(); ret = _os.dup2(oldfd, newfd); if (ret == -1) return -1; if ( (pointer = _get_pointer_by_fh(oldfd)) != NULL ) { if ( _attach_pointer(pointer->handle, ret) == NULL ) { _os.close(ret); return -1; } } return ret; } int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { struct roar_vio_selecttv rtv; struct roar_vio_select * sv = NULL; struct pointer * pointer; struct handle * handle; ssize_t ret; size_t num = 0; size_t idx; int i; int i_r, i_w, i_e; int max_index = -1; static volatile int is_critical = 0; _init(); if ( is_critical ) return _os.select(nfds, readfds, writefds, exceptfds, timeout); ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = ?", nfds, readfds, writefds, exceptfds, timeout); if ( nfds == 0 ) { ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = 0", nfds, readfds, writefds, exceptfds, timeout); return 0; } if ( readfds == NULL && writefds == NULL && exceptfds == NULL ) { ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = 0", nfds, readfds, writefds, exceptfds, timeout); return 0; } if ( timeout != NULL ) { rtv.sec = timeout->tv_sec; rtv.nsec = timeout->tv_usec*1000; } // count number of handles: for (i = 0; i < nfds; i++) { ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p): i=%i, EXISTS", nfds, readfds, writefds, exceptfds, timeout, i); if ( (readfds != NULL && FD_ISSET(i, readfds )) || (writefds != NULL && FD_ISSET(i, writefds )) || (exceptfds != NULL && FD_ISSET(i, exceptfds)) ) { ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p): i=%i, EXISTS", nfds, readfds, writefds, exceptfds, timeout, i); num++; max_index = i; } } if ( num == 0 ) { ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = 0", nfds, readfds, writefds, exceptfds, timeout); return 0; } nfds = max_index + 1; // create sv; sv = roar_mm_malloc(sizeof(struct roar_vio_select)*num); if ( sv == NULL ) { ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = -1", nfds, readfds, writefds, exceptfds, timeout); return -1; } memset(sv, 0, sizeof(struct roar_vio_select)*num); for (i = 0, idx = 0; i < nfds; i++) { if ( idx >= num ) { roar_mm_free(sv); errno = EFAULT; ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = -1 // i=%i, idx=%i, num=%i", nfds, readfds, writefds, exceptfds, timeout, i, (int)idx, (int)num); return -1; } i_r = readfds != NULL && FD_ISSET(i, readfds); i_w = writefds != NULL && FD_ISSET(i, writefds); i_e = exceptfds != NULL && FD_ISSET(i, exceptfds); ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p): i=%i, i_r=%i, i_w=%i, i_e=%i", nfds, readfds, writefds, exceptfds, timeout, i, i_r, i_w, i_e); if ( i_r || i_w || i_e ) { // TODO: use VIO for pointers... if ( (pointer = _get_pointer_by_fh(i)) != NULL ) { handle = pointer->handle; sv[idx].vio = NULL; sv[idx].fh = -1; switch (handle->type) { case HT_DMX: case HT_STREAM: if ( ! handle->stream_opened ) { // implement this as statichly return OK errno = ENOSYS; return -1; } case HT_VIO: sv[idx].vio = &(handle->stream_vio); break; default: /* non supported type */ errno = EINVAL; return -1; break; } } else { sv[idx].vio = NULL; sv[idx].fh = i; } sv[idx].ud.si = i; sv[idx].eventsq = (i_r ? ROAR_VIO_SELECT_READ : 0) | (i_w ? ROAR_VIO_SELECT_WRITE : 0) | (i_e ? ROAR_VIO_SELECT_EXCEPT : 0); idx++; } } is_critical++; ret = roar_vio_select(sv, num, timeout == NULL ? NULL : &rtv, NULL); is_critical--; if ( ret < 1 ) { roar_mm_free(sv); ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = %i", nfds, readfds, writefds, exceptfds, timeout, (int)ret); if ( ret == 0 ) { if ( readfds != NULL ) { FD_ZERO(readfds); } if ( writefds != NULL ) { FD_ZERO(writefds); } if ( exceptfds != NULL ) { FD_ZERO(exceptfds); } } return ret; } // update readfds, writefds, exceptfds: if ( readfds != NULL ) FD_ZERO(readfds); if ( writefds != NULL ) FD_ZERO(writefds); if ( exceptfds != NULL ) FD_ZERO(exceptfds); for (idx = 0; idx < num; idx++) { if ( sv[idx].eventsa == 0 ) continue; if ( sv[idx].eventsa & ROAR_VIO_SELECT_READ ) if ( readfds != NULL ) FD_SET(sv[idx].ud.si, readfds); if ( sv[idx].eventsa & ROAR_VIO_SELECT_WRITE ) if ( writefds != NULL ) FD_SET(sv[idx].ud.si, writefds); if ( sv[idx].eventsa & ROAR_VIO_SELECT_EXCEPT ) if ( exceptfds != NULL ) FD_SET(sv[idx].ud.si, exceptfds); } roar_mm_free(sv); ROAR_DBG("select(nfds=%i, readfds=%p, writefds=%p, exceptfds=%p, timeout=%p) = %i", nfds, readfds, writefds, exceptfds, timeout, (int)ret); return ret; } int fcntl(int fd, int cmd, ...) { enum { NONE, UNKNOWN, LONG, POINTER } type = NONE; struct pointer * pointer; va_list ap; long argl = -1; void * vp = NULL; int ret = -1; int diff; _init(); ROAR_DBG("fcntl(fd=%i, cmd=%i, ...) = ?", fd, cmd); switch (cmd) { case F_DUPFD: case F_SETFD: case F_SETFL: case F_SETOWN: #ifdef F_SETSIG case F_SETSIG: #endif #ifdef F_SETLEASE case F_SETLEASE: #endif #ifdef F_NOTIFY case F_NOTIFY: #endif type = LONG; break; case F_GETFD: case F_GETFL: case F_GETOWN: #ifdef F_GETSIG case F_GETSIG: #endif #ifdef F_GETLEASE case F_GETLEASE: #endif type = NONE; break; case F_GETLK: case F_SETLK: case F_SETLKW: #ifdef F_GETLK64 #if F_GETLK64 != F_GETLK case F_GETLK64: #endif #endif #ifdef F_SETLK64 #if F_SETLK64 != F_SETLK case F_SETLK64: #endif #endif #ifdef F_SETLKW64 #if F_SETLKW64 != F_SETLKW case F_SETLKW64: #endif #endif type = POINTER; break; /* case F_EXLCK: case F_GETLK64: case F_SETLK64: case F_SETLKW64: case F_SHLCK: case F_LINUX_SPECIFIC_BASE: case F_INPROGRESS: */ default: type = UNKNOWN; } if ( type == UNKNOWN ) { ROAR_DBG("fcntl(fd=%i, cmd=%i, ...): unknown data type!", fd, cmd); ROAR_DBG("fcntl(fd=%i, cmd=%i, ...) = -1 // errno = EINVAL", fd, cmd); errno = EINVAL; return -1; } if ( type != NONE ) { va_start(ap, cmd); switch (type) { case LONG: argl = va_arg(ap, long); break; case POINTER: vp = va_arg(ap, void*); break; default: /* make compiler happy */ break; } va_end(ap); } if ( (pointer = _get_pointer_by_fh(fd)) == NULL ) { switch (type) { case NONE: ROAR_DBG("fcntl(fd=%i, cmd=%i): fd is true sysio, pass call to kernel", fd, cmd); return _os.fcntl(fd, cmd); break; case LONG: ROAR_DBG("fcntl(fd=%i, cmd=%i, arg=%li): fd is true sysio, pass call to kernel", fd, cmd, argl); return _os.fcntl(fd, cmd, argl); break; case POINTER: ROAR_DBG("fcntl(fd=%i, cmd=%i, lock=%p): fd is true sysio, pass call to kernel", fd, cmd, vp); return _os.fcntl(fd, cmd, vp); break; default: /* make compiler happy */ break; } } ROAR_DBG("fcntl(fd=%i, cmd=%i, ...): fd is true pointer, handle internaly", fd, cmd); switch (cmd) { case F_DUPFD: ret = _os.fcntl(fd, F_DUPFD, argl); if ( ret != -1 ) { if ( _attach_pointer(pointer->handle, ret) == NULL ) { _os.close(ret); ret = -1; } } break; case F_SETFD: if ( argl == 0 ) { ret = 0; } else { errno = ENOSYS; ret = -1; } break; case F_GETFD: ret = 0; break; case F_GETFL: ret = pointer->handle->sysio_flags; break; case F_SETFL: diff = (int)argl ^ pointer->handle->sysio_flags; diff &= (int)~(int)_O_PARA_DIR; diff &= (int)~(int)_O_PARA_IGN; if ( diff & O_NONBLOCK ) { diff -= O_NONBLOCK; pointer->handle->sysio_flags ^= O_NONBLOCK; if ( _update_nonblock(pointer->handle) == -1 ) { pointer->handle->sysio_flags ^= O_NONBLOCK; return -1; } } if ( diff == 0 ) { // only flags changed we ignore anyway. pointer->handle->sysio_flags = (int)argl; ret = 0; } else { errno = EINVAL; ret = -1; } break; /* TODO: add support for those types: case F_SETFD: case F_SETOWN: case F_SETSIG: case F_SETLEASE: case F_NOTIFY: case F_GETOWN: case F_GETSIG: case F_GETLEASE: case F_GETLK: case F_SETLK: case F_SETLKW: */ default: errno = ENOSYS; ret = -1; break; } return ret; } int access(const char *pathname, int mode) { struct devices * ptr = NULL; _init(); if ( (ptr = _get_device(pathname)) != NULL ) { // the only flag we do not support is +x, which means // we need to reject all requets with X_OK. if ( mode & X_OK ) { errno = EACCES; return -1; } // in addition HT_STATIC files do not support write (+w) // so we need to reject W_OK. if ( ptr->type == HT_STATIC && (mode & W_OK) ) { errno = EACCES; return -1; } // Else the access is granted: return 0; } return _os.access(pathname, mode); } int creat(const char *_CREAT_ARG_PATHNAME, mode_t mode) { _init(); if ( _get_device(_CREAT_ARG_PATHNAME) != NULL ) { errno = EEXIST; return -1; } return _os.creat(_CREAT_ARG_PATHNAME, mode); } // ------------------------------------- // emulated *stat*() functions follow: // ------------------------------------- #ifndef __clang__ int stat(const char *path, struct stat *buf) { struct devices * ptr; _init(); if ( (ptr = _get_device(path)) != NULL ) { errno = ENOSYS; return -1; } return _os.stat(path, buf); } int fstat(int filedes, struct stat *buf) { struct pointer * pointer; _init(); if ( (pointer = _get_pointer_by_fh(filedes)) == NULL ) { return _os.fstat(filedes, buf); } errno = ENOSYS; return -1; } int lstat(const char *path, struct stat *buf) { _init(); if ( _get_device(path) != NULL ) { return stat(path, buf); } return _os.lstat(path, buf); } #endif // ------------------------------------- // emulated stdio functions follow: // ------------------------------------- //roar_vio_to_stdio static int _vio_close (struct roar_vio_calls * vio) { int ret = 0; int fh = -1; if ( roar_vio_ctl(vio, ROAR_VIO_CTL_GET_FH, &fh) != -1 ) if ( fh != -1 ) ret = close(fh); roar_mm_free(vio); return ret; } FILE *fopen(const char *path, const char *mode) { struct roar_vio_calls * vio; FILE * fr; int ret; int r = 0, w = 0; int flags = 0; int i; register char c; _init(); if ( path == NULL || mode == NULL ) { errno = EFAULT; return NULL; } ROAR_DBG("open(path='%s', mode='%s') = ?\n", path, mode); for (i = 0; (c = mode[i]) != 0; i++) { switch (c) { case 'r': r = 1; break; case 'w': w = 1; break; case 'a': w = 1; break; case '+': r = 1; w = 1; break; } } if ( r && w ) { flags = O_RDWR; } else if ( r ) { flags = O_RDONLY; } else if ( w ) { flags = O_WRONLY; } else { errno = EINVAL; return NULL; } ret = _open_file(path, flags); switch (ret) { case -2: // continue as normal, use _op.open() ROAR_DBG("fopen(path='%s', mode='%s'): not for us, passing to libc", path, mode); break; case -1: // pass error to caller return NULL; break; default: // return successfully opened pointer to caller #ifdef __USE_FDOPEN__ ROAR_DBG("fopen(path='%s', mode='%s') = fdopen(%i, '%s')", path, mode, ret, mode); return fdopen(ret, r ? (w ? "rw" : "r") : "w"); #else if ( (vio = roar_mm_malloc(sizeof(struct roar_vio_calls))) == NULL ) { return NULL; // errno should be set correctly by roar_mm_malloc(). } roar_vio_open_fh(vio, ret); vio->close = _vio_close; if ( (fr = roar_vio_to_stdio(vio, flags)) == NULL ) { _vio_close(vio); errno = EIO; return NULL; } else { return fr; } #endif break; } return _os.fopen(path, mode); } // ------------------------------------- // RoarAudio plugin functions follow: // ------------------------------------- ROAR_DL_PLUGIN_START(libroaross) { _init(); } ROAR_DL_PLUGIN_END #endif //ll �����������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�015173� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/Makefile�����������������������������������������������������������0000644�0001750�0001750�00000002342�12072565215�016630� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������LIB_PREFIX=libroarpulse LIB_STDAPI=$(LIB_PREFIX)$(SHARED_SUFFIX) LIB_SIMPLE=$(LIB_PREFIX)-simple$(SHARED_SUFFIX) TARGETS=$(LIB_STDAPI) $(LIB_SIMPLE) libroarpulseinfo OBJS_ROAR = libroarpulse.o OBJS_STD = util.o error.o timeval.o context.o xmalloc.o version.o operation.o introspect.o sample.o channelmap.o stream.o volume.o mainloop.o mainloop-signal.o mainloop-threaded.o utf8.o x11.o OBJS_SIMPLE = simple.o OBJS_STDAPI = $(OBJS_ROAR) $(OBJS_STD) include ../Makefile.conf include ../Makefile.inc #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroarpulse CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(Wextra) $(LDPATH) -L../lib/ -L. -Wl,--version-script=version-script LIBS = $(LIBROAR) all: ${TARGETS} cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(LIB_STDAPI): ${OBJS_STDAPI} ${CC} ${LDFLAGS} $(SHARED) -Wl,-soname,$(LIB_STDAPI).$(COMMON_SOVERSION) -o $(LIB_STDAPI) ${OBJS_STDAPI} ${LIBS} $(LIB_SIMPLE): ${OBJS_SIMPLE} $(LIB_STDAPI) ${CC} ${LDFLAGS} $(SHARED) -Wl,-soname,$(LIB_SIMPLE).$(COMMON_SOVERSION) -o $(LIB_SIMPLE) ${OBJS_SIMPLE} ${LIBS} -lroarpulse libroarpulseinfo: libroarpulseinfo.o ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/channelmap.c�������������������������������������������������������0000644�0001750�0001750�00000022331�12264733577�017455� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//channelmap.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> /** Initialize the specified channel map and return a pointer to it */ pa_channel_map* pa_channel_map_init(pa_channel_map *m); /** Initialize the specified channel map for monoaural audio and return a pointer to it */ pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m) { m->channels = 1; m->map[0] = PA_CHANNEL_POSITION_MONO; return m; } /** Initialize the specified channel map for stereophonic audio and return a pointer to it */ pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) { m->channels = 2; m->map[0] = PA_CHANNEL_POSITION_LEFT; m->map[1] = PA_CHANNEL_POSITION_RIGHT; return m; } /** Initialize the specified channel map for the specified number * of channels using default labels and return a pointer to it. */ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) { if ( m == NULL || channels == 0 ) return NULL; switch (channels) { case 1: return pa_channel_map_init_mono(m); break; case 2: return pa_channel_map_init_stereo(m); break; } switch (def) { default: return NULL; } } static struct { pa_channel_position_t pos; char * name; } _roar_po_chanpos[] = { {PA_CHANNEL_POSITION_INVALID, "invalid" }, {PA_CHANNEL_POSITION_MONO, "mono" }, {PA_CHANNEL_POSITION_LEFT, "left" }, {PA_CHANNEL_POSITION_RIGHT, "right" }, {PA_CHANNEL_POSITION_CENTER, "center" }, {PA_CHANNEL_POSITION_FRONT_LEFT, "front-left" }, {PA_CHANNEL_POSITION_FRONT_RIGHT, "front-right" }, {PA_CHANNEL_POSITION_FRONT_CENTER, "front-center" }, {PA_CHANNEL_POSITION_REAR_CENTER, "rear-center" }, {PA_CHANNEL_POSITION_REAR_LEFT, "rear-left" }, {PA_CHANNEL_POSITION_REAR_RIGHT, "rear-right" }, {PA_CHANNEL_POSITION_LFE, "lfe" }, {PA_CHANNEL_POSITION_SUBWOOFER, "subwoofer" }, {PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, "front-left-of-center" }, {PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, "front-right-of-center" }, {PA_CHANNEL_POSITION_SIDE_LEFT, "side-left" }, {PA_CHANNEL_POSITION_SIDE_RIGHT, "side-right" }, {PA_CHANNEL_POSITION_AUX0, "aux0" }, {PA_CHANNEL_POSITION_AUX1, "aux1" }, {PA_CHANNEL_POSITION_AUX2, "aux2" }, {PA_CHANNEL_POSITION_AUX3, "aux3" }, {PA_CHANNEL_POSITION_AUX4, "aux4" }, {PA_CHANNEL_POSITION_AUX5, "aux5" }, {PA_CHANNEL_POSITION_AUX6, "aux6" }, {PA_CHANNEL_POSITION_AUX7, "aux7" }, {PA_CHANNEL_POSITION_AUX8, "aux8" }, {PA_CHANNEL_POSITION_AUX9, "aux9" }, {PA_CHANNEL_POSITION_AUX10, "aux10" }, {PA_CHANNEL_POSITION_AUX11, "aux11" }, {PA_CHANNEL_POSITION_AUX12, "aux12" }, {PA_CHANNEL_POSITION_AUX13, "aux13" }, {PA_CHANNEL_POSITION_AUX14, "aux14" }, {PA_CHANNEL_POSITION_AUX15, "aux15" }, {PA_CHANNEL_POSITION_AUX16, "aux16" }, {PA_CHANNEL_POSITION_AUX17, "aux17" }, {PA_CHANNEL_POSITION_AUX18, "aux18" }, {PA_CHANNEL_POSITION_AUX19, "aux19" }, {PA_CHANNEL_POSITION_AUX20, "aux20" }, {PA_CHANNEL_POSITION_AUX21, "aux21" }, {PA_CHANNEL_POSITION_AUX22, "aux22" }, {PA_CHANNEL_POSITION_AUX23, "aux23" }, {PA_CHANNEL_POSITION_AUX24, "aux24" }, {PA_CHANNEL_POSITION_AUX25, "aux25" }, {PA_CHANNEL_POSITION_AUX26, "aux26" }, {PA_CHANNEL_POSITION_AUX27, "aux27" }, {PA_CHANNEL_POSITION_AUX28, "aux28" }, {PA_CHANNEL_POSITION_AUX29, "aux29" }, {PA_CHANNEL_POSITION_AUX30, "aux30" }, {PA_CHANNEL_POSITION_AUX31, "aux31" }, {PA_CHANNEL_POSITION_TOP_CENTER, "top-center" }, {PA_CHANNEL_POSITION_TOP_FRONT_LEFT, "top-front-left" }, {PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, "top-front-right" }, {PA_CHANNEL_POSITION_TOP_FRONT_CENTER, "top-front-center" }, {PA_CHANNEL_POSITION_TOP_REAR_LEFT, "top-rear-left" }, {PA_CHANNEL_POSITION_TOP_REAR_RIGHT, "top-rear-right" }, {PA_CHANNEL_POSITION_TOP_REAR_CENTER, "top-rear-center" }, {PA_CHANNEL_POSITION_MAX, "max" }, {PA_CHANNEL_POSITION_INVALID, NULL} }; /** Return a text label for the specified channel position */ const char* pa_channel_position_to_string(pa_channel_position_t pos) { int i; for (i = 0; _roar_po_chanpos[i].name != NULL; i++) if ( _roar_po_chanpos[i].pos == pos ) return _roar_po_chanpos[i].name; return NULL; } /** The maximum length of strings returned by pa_channel_map_snprint() */ #define PA_CHANNEL_MAP_SNPRINT_MAX 336 /** Make a humand readable string from the specified channel map */ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { const char * g; char * c = s; int i; size_t len; size_t todo = l; if ( map == NULL || s == NULL || l == 0 ) return NULL; *c = 0; for (i = 0; i < map->channels; i++) { g = pa_channel_position_to_string(map->map[i]); if ( g == NULL ) return NULL; len = strlen(g); if ( (len + 1) < todo ) { memcpy(c, g, len); c[len] = ','; c += len + 1; todo -= len + 1; } else { return NULL; } } c[-1] = 0; s[l-1] = 0; return s; } /** Parse a channel position list into a channel map structure. \since 0.8.1 */ pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s) { int i; char * c; size_t len; pa_channel_position_t * v; if ( map == NULL ) return NULL; map->channels = 0; if ( s == NULL ) return map; while (*s != 0) { c = strstr(s, ","); if ( c == NULL ) { len = strlen(s); } else { len = c - s; } v = &(map->map[map->channels++]); *v = PA_CHANNEL_POSITION_INVALID; for (i = 0; *v == PA_CHANNEL_POSITION_INVALID && _roar_po_chanpos[i].name != NULL; i++) { if ( !strncasecmp(_roar_po_chanpos[i].name, s, len) && _roar_po_chanpos[i].name[len] == 0 ) { *v = _roar_po_chanpos[i].pos; } } if ( c == NULL ) { break; } else { s = c + 1; } } return map; } /** Compare two channel maps. Return 1 if both match. */ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b); /** Return non-zero of the specified channel map is considered valid */ int pa_channel_map_valid(const pa_channel_map *map); //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/context.c����������������������������������������������������������0000644�0001750�0001750�00000023073�12264733600�017022� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//context.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> struct _roar_pa_cb_st { union { pa_context_success_cb_t scb; pa_context_notify_cb_t ncb; } cb; void * userdata; }; #define _call_cbs(x,c,s) ((x).cb.scb == NULL ? (void)0 : (x).cb.scb((c), (s), (x).userdata)) #define _call_cbn(x,c) ((x).cb.ncb == NULL ? (void)0 : (x).cb.ncb((c), (x).userdata)) struct pa_context { size_t refc; struct roar_connection con; char * server; char * name; int state; int errnum; struct { struct _roar_pa_cb_st set_name; struct _roar_pa_cb_st state_change; } cb; pa_mainloop_api * mainloop; }; // older versions: typedef struct pa_proplist pa_proplist; pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist); void pa_context_set_state(pa_context *c, pa_context_state_t st); pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) { return pa_context_new_with_proplist(mainloop, name, NULL); } pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist) { pa_context * c; if ( proplist != NULL ) return NULL; if ( (c = roar_mm_malloc(sizeof(pa_context))) == NULL ) return NULL; memset(c, 0, sizeof(pa_context)); c->refc = 1; c->state = PA_CONTEXT_UNCONNECTED; c->errnum = PA_OK; if ( name != NULL ) { c->name = roar_mm_strdup(name); } c->mainloop = mainloop; return c; } static void _context_free(pa_context *c) { pa_context_disconnect(c); if ( c->server != NULL ) roar_mm_free(c->server); if ( c->name != NULL ) roar_mm_free(c->name); roar_mm_free(c); } pa_context* pa_context_ref(pa_context *c) { c->refc++; return c; } void pa_context_unref(pa_context *c) { c->refc--; if ( c->refc < 1 ) _context_free(c); } int pa_context_connect( pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api) { pa_context_flags_t flags_left = flags; if ( c == NULL ) return -1; flags_left |= PA_CONTEXT_NOAUTOSPAWN; flags_left -= PA_CONTEXT_NOAUTOSPAWN; #ifdef PA_CONTEXT_NOFAIL flags_left |= PA_CONTEXT_NOFAIL; flags_left -= PA_CONTEXT_NOFAIL; #endif #ifdef PA_CONTEXT_NOFLAGS flags_left |= PA_CONTEXT_NOFLAGS; flags_left -= PA_CONTEXT_NOFLAGS; #endif if ( flags_left != 0 ) return -1; if ( c->state != PA_CONTEXT_UNCONNECTED ) { c->errnum = PA_ERR_BADSTATE; pa_context_set_state(c, PA_CONTEXT_FAILED); return -1; } // flags may contain the following values: #if 0 PA_CONTEXT_NOFLAGS = 0x0000U, /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ PA_CONTEXT_NOAUTOSPAWN = 0x0001U, /**< Disabled autospawning of the PulseAudio daemon if required */ PA_CONTEXT_NOFAIL = 0x0002U /**< Don't fail if the daemon is not available when pa_context_connect() is called, instead enter PA_CONTEXT_CONNECTING state and wait for the daemon to appear. \since 0.9.15 */ #endif // we do currently not support to spawn a daemon, so we ignore flags and api. server = roar_pa_find_server(server); if ( roar_simple_connect(&(c->con), server, c->name != NULL ? c->name : "libroarpulse [pa_context_connect()]") == -1 ) { c->errnum = PA_ERR_CONNECTIONREFUSED; pa_context_set_state(c, PA_CONTEXT_FAILED); #ifdef PA_CONTEXT_NOFAIL if ( flags & PA_CONTEXT_NOFAIL ) { pa_context_set_state(c, PA_CONTEXT_CONNECTING); return 0; } #endif return -1; } if ( server == NULL ) { c->server = NULL; } else { c->server = roar_mm_strdup(server); } pa_context_set_state(c, PA_CONTEXT_READY); _call_cbs(c->cb.set_name, c, 1); return 0; } void pa_context_disconnect(pa_context *c) { if ( c == NULL ) return; if ( c->state != PA_CONTEXT_READY ) return; roar_disconnect(&(c->con)); pa_context_set_state(c, PA_CONTEXT_TERMINATED); } struct roar_connection * roar_pa_context_get_con(pa_context * c) { if ( c == NULL ) return NULL; if ( c->state != PA_CONTEXT_READY ) return NULL; return &(c->con); } pa_mainloop_api * roar_pa_context_get_api(pa_context * c) { if ( c == NULL ) return NULL; return c->mainloop; } /** Set a callback function that is called whenever the context status changes */ void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { if ( c == NULL ) return; c->cb.state_change.cb.ncb = cb; c->cb.state_change.userdata = userdata; } void pa_context_set_state(pa_context *c, pa_context_state_t st) { if ( c == NULL ) return; c->state = st; _call_cbn(c->cb.state_change, c); } /** Return the error number of the last failed operation */ int pa_context_errno(pa_context *c) { if ( c == NULL ) return PA_ERR_INVALID; return c->errnum; } /** Return non-zero if some data is pending to be written to the connection */ int pa_context_is_pending(pa_context *c) { (void)c; return 0; } /** Return the current context status */ pa_context_state_t pa_context_get_state(pa_context *c) { if ( c == NULL ) return PA_CONTEXT_FAILED; return c->state; } /** Drain the context. If there is nothing to drain, the function returns NULL */ pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { if ( cb != NULL ) cb(c, userdata); return NULL; } /** Tell the daemon to exit. The returned operation is unlikely to * complete succesfully, since the daemon probably died before * returning a success notification */ pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) { int s = 1; if ( c == NULL ) return roar_pa_operation_new(PA_OPERATION_DONE); if ( c->state == PA_CONTEXT_READY ) { if ( roar_terminate(&(c->con), 0) == -1 ) { c->errnum = PA_ERR_INTERNAL; s = 0; } } else { c->errnum = PA_ERR_BADSTATE; s = 0; } if ( cb != NULL ) cb(c, s, userdata); return roar_pa_operation_new(PA_OPERATION_DONE); } /** Set the name of the default sink. \since 0.4 */ pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { if ( c != NULL ) c->errnum = PA_ERR_NOTSUPPORTED; if ( cb != NULL ) cb(c, strcasecmp(name, ROAR_PA_DEFAULT_SINK) == 0 ? 1 : 0, userdata); return roar_pa_operation_new(PA_OPERATION_DONE); } /** Set the name of the default source. \since 0.4 */ pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { if ( c != NULL ) c->errnum = PA_ERR_NOTSUPPORTED; if ( cb != NULL ) cb(c, strcasecmp(name, ROAR_PA_DEFAULT_SOURCE) == 0 ? 1 : 0, userdata); return roar_pa_operation_new(PA_OPERATION_DONE); } /** Returns 1 when the connection is to a local daemon. Returns negative when no connection has been made yet. \since 0.5 */ int pa_context_is_local(pa_context *c) { if ( c == NULL ) return -1; if ( c->state != PA_CONTEXT_READY ) return -1; // how is /local/ defined? return 0; } /** Set a different application name for context on the server. \since 0.5 */ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { if ( c == NULL ) return roar_pa_operation_new(PA_OPERATION_DONE); if ( c->state != PA_CONTEXT_UNCONNECTED ) { c->errnum = PA_ERR_BADSTATE; if ( cb != NULL ) cb(c, 0, userdata); return roar_pa_operation_new(PA_OPERATION_DONE); } if ( c->name != NULL ) roar_mm_free(c->name); c->name = roar_mm_strdup(name); c->cb.set_name.cb.scb = cb; c->cb.set_name.userdata = userdata; return roar_pa_operation_new(PA_OPERATION_DONE); } /** Return the server name this context is connected to. \since 0.7 */ const char* pa_context_get_server(pa_context *c) { if ( c == NULL ) return NULL; return c->server; } /** Return the protocol version of the library. \since 0.8 */ uint32_t pa_context_get_protocol_version(pa_context *c) { (void)c; return 0; } /** Return the protocol version of the connected server. \since 0.8 */ uint32_t pa_context_get_server_protocol_version(pa_context *c) { (void)c; return 0; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/error.c������������������������������������������������������������0000644�0001750�0001750�00000011323�12264733600�016462� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//error.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> static const struct { int error; int ra_error; const char * name; } _roar_pa_errors[] = { {PA_OK, ROAR_ERROR_NONE, "OK" }, {PA_ERR_ACCESS, ROAR_ERROR_PERM, "Access denied" }, {PA_ERR_COMMAND, ROAR_ERROR_BADRQC, "Unknown command" }, {PA_ERR_INVALID, ROAR_ERROR_INVAL, "Invalid argument" }, {PA_ERR_EXIST, ROAR_ERROR_EXIST, "Entity exists" }, {PA_ERR_NOENTITY, ROAR_ERROR_NOENT, "No such entity" }, {PA_ERR_CONNECTIONREFUSED, ROAR_ERROR_CONNREFUSED, "Connection refused" }, {PA_ERR_PROTOCOL, ROAR_ERROR_PROTO, "Protocol error" }, {PA_ERR_TIMEOUT, ROAR_ERROR_TIMEDOUT, "Timeout" }, {PA_ERR_AUTHKEY, ROAR_ERROR_PERM, "No authorization key" }, {PA_ERR_INTERNAL, ROAR_ERROR_UNKNOWN, "Internal error" }, {PA_ERR_CONNECTIONTERMINATED, ROAR_ERROR_IO, "Connection terminated" }, {PA_ERR_KILLED, ROAR_ERROR_IO, "Entity killed" }, {PA_ERR_INVALIDSERVER, ROAR_ERROR_INVAL, "Invalid server" }, {PA_ERR_MODINITFAILED, ROAR_ERROR_BADLIB, "Module initalization failed" }, {PA_ERR_BADSTATE, ROAR_ERROR_INVAL, "Bad state" }, {PA_ERR_NODATA, ROAR_ERROR_NODATA, "No data" }, {PA_ERR_VERSION, ROAR_ERROR_NSVERSION, "Incompatible protocol version" }, {PA_ERR_TOOLARGE, ROAR_ERROR_RANGE, "Too large" }, #ifdef PA_ERR_NOTSUPPORTED {PA_ERR_NOTSUPPORTED, ROAR_ERROR_NOTSUP, "Not supported"}, #endif #ifdef PA_ERR_UNKNOWN {PA_ERR_UNKNOWN, ROAR_ERROR_UNKNOWN, "Unknown error code"}, #endif #ifdef PA_ERR_NOEXTENSION {PA_ERR_UNKNOWN, ROAR_ERROR_NOENT, "No such extension"}, #endif #ifdef PA_ERR_OBSOLETE {PA_ERR_OBSOLETE, ROAR_ERROR_NOSYS, "Obsolete functionality"}, #endif #ifdef PA_ERR_NOTIMPLEMENTED {PA_ERR_NOTIMPLEMENTED, ROAR_ERROR_NOSYS, "Missing implementation"}, #endif #ifdef PA_ERR_FORKED {PA_ERR_FORKED, ROAR_ERROR_INVAL, "Client forked"}, #endif #ifdef PA_ERR_IO {PA_ERR_IO, ROAR_ERROR_IO, "Input/Output error"}, #endif #ifdef PA_ERR_BUSY {PA_ERR_BUSY, ROAR_ERROR_BUSY, "Device or resource busy"}, #endif {PA_ERR_MAX, ROAR_ERROR_UNKNOWN, "MAX" }, {-1, ROAR_ERROR_UNKNOWN, NULL} }; const char * pa_strerror(int error) { int i; for (i = 0; _roar_pa_errors[i].name != NULL; i++) if ( _roar_pa_errors[i].error == error ) return _roar_pa_errors[i].name; return NULL; } int roar_pa_raerror2paerror(int error) { int i; for (i = 0; _roar_pa_errors[i].name != NULL; i++) if ( _roar_pa_errors[i].ra_error == error ) return _roar_pa_errors[i].error; return PA_ERR_INVALID; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/introspect.c�������������������������������������������������������0000644�0001750�0001750�00000032345�12264733601�017533� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//introspect.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> /** Get information about a sink by its name */ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata) { struct roar_stream stream; pa_sink_info painfo; if ( c == NULL || cb == NULL ) return roar_pa_op_new_done(); memset(&painfo, 0, sizeof(painfo)); if ( !!strcasecmp(name, ROAR_PA_DEFAULT_SINK) ) return roar_pa_op_new_done(); if ( roar_server_oinfo(roar_pa_context_get_con(c), &stream, ROAR_DIR_PLAY) == -1 ) return roar_pa_op_new_done(); if ( roar_pa_auinfo2sspec(&(painfo.sample_spec), &(stream.info)) == -1 ) return roar_pa_op_new_done(); pa_channel_map_init_auto(&(painfo.channel_map), stream.info.channels, PA_CHANNEL_MAP_DEFAULT); // pa_cvolume_init(&(painfo.volume)); painfo.name = ROAR_PA_DEFAULT_SINK; painfo.index = 0; // fixme! painfo.description = "RoarAudio default mixer"; painfo.owner_module = PA_INVALID_INDEX; painfo.mute = 0; painfo.monitor_source = 0; painfo.monitor_source_name = ROAR_PA_DEFAULT_SOURCE; painfo.latency = 0; painfo.driver = "Waveform Mixer Core"; // painfo.pa_sink_flags_t = 0; cb(c, &painfo, 1, userdata); return roar_pa_op_new_done(); } /** Get information about a sink by its index */ pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t id, pa_sink_info_cb_t cb, void *userdata); /** Get the complete sink list */ pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata); /** Get information about a source by its name */ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata); /** Get information about a source by its index */ pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t id, pa_source_info_cb_t cb, void *userdata); /** Get the complete source list */ pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata); /** Get some information about the server */ pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata) { struct roar_stream stream; struct roar_client client; pa_server_info painfo; if ( c == NULL || cb == NULL ) return roar_pa_op_new_done(); if ( roar_server_oinfo(roar_pa_context_get_con(c), &stream, ROAR_DIR_PLAY) == -1 ) return roar_pa_op_new_done(); if ( roar_get_client(roar_pa_context_get_con(c), &client, 0) == -1 ) return roar_pa_op_new_done(); memset(&painfo, 0, sizeof(painfo)); if ( roar_pa_auinfo2sspec(&(painfo.sample_spec), &(stream.info)) == -1 ) return roar_pa_op_new_done(); painfo.user_name = "(none)"; painfo.host_name = pa_context_get_server(c); painfo.server_version = pa_get_library_version(); painfo.server_name = "pulseaudio"; painfo.default_sink_name = ROAR_PA_DEFAULT_SINK; painfo.default_source_name = ROAR_PA_DEFAULT_SOURCE; painfo.cookie = 0x524F4152; painfo.cookie ^= (client.pid & 0xFF) | (client.uid & 0xFF) << 8 | (client.gid & 0xFF) << 16; cb(c, &painfo, userdata); return roar_pa_op_new_done(); } /** Get some information about a module by its index */ pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata); /** Get the complete list of currently loaded modules */ pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata); /** Get information about a client by its index */ pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata); /** Get the complete client list */ pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata); /** Get some information about a sink input by its index */ pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) { pa_sink_input_info pa_info; // struct roar_stream_info info; struct roar_stream stream; struct roar_mixer_settings mixer; long long int s; int channels; char buf[256]; int i; memset(&pa_info, 0, sizeof(pa_info)); roar_get_stream(roar_pa_context_get_con(c), &stream, idx); roar_stream_get_name(roar_pa_context_get_con(c), &stream, buf, sizeof(buf)); if ( roar_get_vol(roar_pa_context_get_con(c), idx, &mixer, &channels) == -1 ) { channels = 1; mixer.mixer[0] = 65535; mixer.rpg_mul = mixer.rpg_div = 1; } // roar_stream_get_info(roar_pa_context_get_con(c), &stream, &info); pa_info.index = idx; pa_info.name = buf; pa_info.owner_module = PA_INVALID_INDEX; pa_info.client = PA_INVALID_INDEX; pa_info.sink = idx; //libroarpulse.c:int roar_pa_auinfo2sspec (pa_sample_spec * ss, const struct roar_audio_info * info) { roar_pa_auinfo2sspec(&(pa_info.sample_spec), &(stream.info)); pa_info.volume.channels = channels; for (i = 0; i < channels; i++) { s = mixer.mixer[i]; s *= mixer.rpg_mul; s *= PA_VOLUME_NORM; s /= mixer.rpg_div; s /= 65535; pa_info.volume.values[i] = s; } pa_info.resample_method = "server side"; pa_info.driver = "RoarAudio"; // pa_info.mute = (info.flags & ROAR_FLAG_MUTE) ? 1 : 0; cb(c, &pa_info, 1, userdata); return roar_pa_operation_new(PA_OPERATION_DONE); } /** Get the complete sink input list */ pa_operation* pa_context_get_sink_input_info_list(pa_context *c, pa_sink_input_info_cb_t cb, void *userdata); /** Get information about a source output by its index */ pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata); /** Get the complete list of source outputs */ pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata); /** Set the volume of a sink device specified by its index */ pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); /** Set the volume of a sink device specified by its name */ pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); /** Set the mute switch of a sink device specified by its index \since 0.8 */ pa_operation* pa_context_set_sink_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata); /** Set the mute switch of a sink device specified by its name \since 0.8 */ pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata); /** Set the volume of a sink input stream */ pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) { struct roar_mixer_settings mixer; long long int s; size_t i; mixer.rpg_mul = 1; mixer.rpg_div = 1; for (i = 0; i < volume->channels; i++) { s = volume->values[i]; s *= 65535; s /= PA_VOLUME_NORM; mixer.mixer[i] = s; } if ( roar_set_vol(roar_pa_context_get_con(c), idx, &mixer, volume->channels, ROAR_SET_VOL_ALL) == -1 ) { cb(c, 0, userdata); } else { cb(c, 1, userdata); } return roar_pa_operation_new(PA_OPERATION_DONE); } /** Set the volume of a source device specified by its index \since 0.8 */ pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); /** Set the volume of a source device specified by its name \since 0.8 */ pa_operation* pa_context_set_source_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); /** Set the mute switch of a source device specified by its index \since 0.8 */ pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata); /** Set the mute switch of a source device specified by its name \since 0.8 */ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata); /** Get daemon memory block statistics */ pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata); /** Get information about a sample by its name */ pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata); /** Get information about a sample by its index */ pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata); /** Get the complete list of samples stored in the daemon. */ pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata); /** Kill a client. \since 0.5 */ pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); /** Kill a sink input. \since 0.5 */ pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); /** Kill a source output. \since 0.5 */ pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); /** Load a module. \since 0.5 */ pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata); /** Unload a module. \since 0.5 */ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); /** Get info about a specific autoload entry. \since 0.6 */ pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata); /** Get info about a specific autoload entry. \since 0.6 */ pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata); /** Get the complete list of autoload entries. \since 0.5 */ pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata); /** Add a new autoload entry. \since 0.5 */ pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, pa_context_index_cb_t, void* userdata); /** Remove an autoload entry. \since 0.6 */ pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_context_success_cb_t cb, void* userdata); /** Remove an autoload entry. \since 0.6 */ pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata); /** Move the specified sink input to a different sink. \since 0.9.5 */ pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, ROAR_HAVE_ARG_SINK_NAME_OF_PA_CONTEXT_MOVE_SINK_INPUT_BY_NAME sink_name, pa_context_success_cb_t cb, void* userdata); /** Move the specified sink input to a different sink. \since 0.9.5 */ pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, uint32_t sink_idx, pa_context_success_cb_t cb, void* userdata); /** Move the specified source output to a different source. \since 0.9.5 */ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, ROAR_HAVE_ARG_SOURCE_NAME_OF_PA_CONTEXT_MOVE_SOURCE_OUTPUT_BY_NAME source_name, pa_context_success_cb_t cb, void* userdata); /** Move the specified source output to a different source. \since 0.9.5 */ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata); //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/libroarpulse.c�����������������������������������������������������0000644�0001750�0001750�00000007304�12264733603�020043� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarpulse.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> int roar_pa_sspec2auinfo (struct roar_audio_info * info, const pa_sample_spec * ss) { if ( ss == NULL || info == NULL ) return -1; info->rate = ss->rate; info->channels = ss->channels; switch (ss->format) { case PA_SAMPLE_U8: info->bits = 8; info->codec = ROAR_CODEC_PCM_U_LE; break; case PA_SAMPLE_ALAW: info->bits = 8; info->codec = ROAR_CODEC_ALAW; break; case PA_SAMPLE_ULAW: info->bits = 8; info->codec = ROAR_CODEC_MULAW; break; case PA_SAMPLE_S16LE: info->bits = 16; info->codec = ROAR_CODEC_PCM_S_LE; break; case PA_SAMPLE_S16BE: info->bits = 16; info->codec = ROAR_CODEC_PCM_S_BE; break; // invalid and not supported ones follow: case PA_SAMPLE_INVALID: case PA_SAMPLE_MAX: case PA_SAMPLE_FLOAT32LE: case PA_SAMPLE_FLOAT32BE: default: return -1; break; } return 0; } int roar_pa_auinfo2sspec (pa_sample_spec * ss, const struct roar_audio_info * info) { if ( ss == NULL || info == NULL ) return -1; ss->rate = info->rate; ss->channels = info->channels; switch (info->codec) { case ROAR_CODEC_ALAW: ss->format = PA_SAMPLE_ALAW; break; case ROAR_CODEC_MULAW: ss->format = PA_SAMPLE_ULAW; break; case ROAR_CODEC_PCM_S_LE: if ( info->bits != 16 ) return -1; ss->format = PA_SAMPLE_S16LE; break; case ROAR_CODEC_PCM_S_BE: if ( info->bits != 16 ) return -1; ss->format = PA_SAMPLE_S16BE; break; case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_BE: case ROAR_CODEC_PCM_U_PDP: if ( info->bits != 8 ) return -1; ss->format = PA_SAMPLE_U8; break; default: return -1; break; } return 0; } const char * roar_pa_find_server (const char * server) { struct roar_x11_connection * x11con; if ( server == NULL ) server = roar_env_get("PULSE_SERVER"); if ( server == NULL ) { if ( (x11con = roar_x11_connect(NULL)) != NULL ) { server = roar_x11_get_prop(x11con, "PULSE_SERVER"); roar_x11_disconnect(x11con); } } return server; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/libroarpulseinfo.c�������������������������������������������������0000644�0001750�0001750�00000004030�12264733603�020710� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarpulseinfo.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> int main (void) { struct { char * name; int len; } types[] = { // { "pa_simple", sizeof(pa_simple) }, { "pa_sample_spec", sizeof(pa_sample_spec) }, { NULL, 0 } }, * c = types - 1; printf("Types:\n"); while ((++c)->name != NULL) printf("%-20s = %3i Bytes = %4i Bits\n", c->name, c->len, c->len * 8); return 0; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/mainloop-signal.c��������������������������������������������������0000644�0001750�0001750�00000011574�12264733603�020435� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//mainloop-signal.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> #define MAX_SIG 64 /* there is no way to find out */ typedef void (*pa_signal_cb_t) (pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata); struct pa_signal_event { int used; int sig; pa_signal_cb_t cb; void * userdata; }; static int _roar_pa_signal_inited = 0; static struct { pa_mainloop_api * api; pa_signal_event sig[MAX_SIG]; #ifdef ROAR_HAVE_PIPE int pipefh[2]; pa_io_event * io_event; #endif } _roar_pa_signal; static void _roar_pa_signal_iocb( #ifndef ROAR_HAVE_PIPE int sig #else pa_mainloop_api * a, pa_io_event * e, int fd, pa_io_event_flags_t f, void *userdata #endif ) { pa_signal_event * se; #ifdef ROAR_HAVE_PIPE int sig; size_t ret; #endif (void)a, (void)e, (void)f, (void)userdata; #ifdef ROAR_HAVE_PIPE ret = read(fd, &sig, sizeof(sig)); if ( ret != sizeof(sig) ) return; #endif if ( sig >= MAX_SIG ) return; se = &(_roar_pa_signal.sig[sig]); if ( !se->used ) return; ROAR_DBG("_roar_pa_signal_iocb(*): sig=%s(%i), se->cb=%p", strsignal(sig), sig, se->cb); if ( se->cb != NULL ) se->cb(_roar_pa_signal.api, se, sig, se->userdata); } static void _roar_pa_signal_handler (int sig) { #ifdef ROAR_HAVE_PIPE write(_roar_pa_signal.pipefh[1], &sig, sizeof(sig)); #else _roar_pa_signal_iocb(sig); #endif } /** Initialize the UNIX signal subsystem and bind it to the specified main loop */ int pa_signal_init(pa_mainloop_api *api) { if ( _roar_pa_signal_inited ) return -1; memset(&_roar_pa_signal, 0, sizeof(_roar_pa_signal)); _roar_pa_signal.api = api; #ifdef ROAR_HAVE_PIPE if ( pipe(_roar_pa_signal.pipefh) == -1 ) return -1; _roar_pa_signal.io_event = api->io_new(api, _roar_pa_signal.pipefh[0], PA_IO_EVENT_INPUT, _roar_pa_signal_iocb, NULL); #endif _roar_pa_signal_inited = 1; return 0; } /** Cleanup the signal subsystem */ void pa_signal_done(void) { int i; for (i = 0; i < MAX_SIG; i++) { _roar_pa_signal.sig[i].used = 0; } #ifdef ROAR_HAVE_PIPE _roar_pa_signal.api->io_free(_roar_pa_signal.io_event); #endif _roar_pa_signal_inited = 0; } /** Create a new UNIX signal event source object */ pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t callback, void *userdata) { if ( !_roar_pa_signal_inited ) return NULL; if ( sig >= MAX_SIG ) return NULL; _roar_pa_signal.sig[sig].used = 1; _roar_pa_signal.sig[sig].sig = sig; _roar_pa_signal.sig[sig].cb = callback; _roar_pa_signal.sig[sig].userdata = userdata; signal(sig, _roar_pa_signal_handler); return &(_roar_pa_signal.sig[sig]); } /** Free a UNIX signal event source object */ void pa_signal_free(pa_signal_event *e) { if ( !_roar_pa_signal_inited ) return; if ( e == NULL ) return; signal(e->sig, SIG_DFL); e->used = 0; } /** Set a function that is called when the signal event source is destroyed. Use this to free the userdata argument if required */ void pa_signal_set_destroy(pa_signal_event *e, void (*callback) (pa_mainloop_api *api, pa_signal_event*e, void *userdata)); //ll ������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/mainloop-threaded.c������������������������������������������������0000644�0001750�0001750�00000006242�12264733603�020734� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//mainloop-threaded.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> struct pa_threaded_mainloop { pa_mainloop_api api; int started; size_t lockc; int retval; }; static void __quit(pa_mainloop_api*a, int retval) { pa_threaded_mainloop * m = a->userdata; m->retval = retval; pa_threaded_mainloop_stop(m); } static const pa_mainloop_api __api = { .quit = __quit }; pa_threaded_mainloop *pa_threaded_mainloop_new(void) { pa_threaded_mainloop * ret = roar_mm_malloc(sizeof(pa_threaded_mainloop)); if ( ret == NULL ) { // handle errors here. return NULL; } memset(ret, 0, sizeof(pa_threaded_mainloop)); ret->api = __api; ret->api.userdata = ret; return ret; } void pa_threaded_mainloop_free(pa_threaded_mainloop* m) { if ( m == NULL ) return; roar_mm_free(m); } int pa_threaded_mainloop_start(pa_threaded_mainloop *m) { m->started = 1; return 0; } void pa_threaded_mainloop_stop(pa_threaded_mainloop *m) { m->started = 1; } void pa_threaded_mainloop_lock(pa_threaded_mainloop *m) { m->lockc++; } void pa_threaded_mainloop_unlock(pa_threaded_mainloop *m) { if ( m->lockc != 0 ) m->lockc--; } void pa_threaded_mainloop_wait(pa_threaded_mainloop *m); void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept); void pa_threaded_mainloop_accept(pa_threaded_mainloop *m); int pa_threaded_mainloop_get_retval(pa_threaded_mainloop *m) { return m->retval; } pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m) { return &(m->api); } int pa_threaded_mainloop_in_thread(pa_threaded_mainloop *m) { (void)m; return 0; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/mainloop.c���������������������������������������������������������0000644�0001750�0001750�00000023651�12264733604�017162� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//mainloop.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> #ifdef ROAR_HAVE_H_POLL #include <poll.h> #endif #define MAX_IO_EVENTS 8 #ifndef ROAR_HAVE_H_POLL struct pollfd { int fd; short events, revents; }; typedef int nfds_t; #define POLLIN 0x001 /* There is data to read. */ #define POLLPRI 0x002 /* There is urgent data to read. */ #define POLLOUT 0x004 /* Writing now will not block. */ #define POLLERR 0x008 /* Error condition. */ #define POLLHUP 0x010 /* Hung up. */ #endif struct pa_io_event { int used; pa_mainloop_api *api; int fd; pa_io_event_flags_t events; pa_io_event_cb_t cb; void *userdata; pa_io_event_destroy_cb_t destroy; }; struct pa_mainloop { pa_mainloop_api api; pa_poll_func poll_func; void * poll_userdata; int poll_timeout; int quit; int quitval; pa_io_event io_event[MAX_IO_EVENTS]; struct pollfd pollfd[MAX_IO_EVENTS]; nfds_t pollfds; }; // IO EVENTS: static void _roar_pa_io_enable(pa_io_event* e, pa_io_event_flags_t events); /** Create a new IO event source object */ static pa_io_event* _roar_pa_io_new(pa_mainloop_api*a, int fd, pa_io_event_flags_t events, pa_io_event_cb_t cb, void *userdata) { pa_mainloop * mainloop = a->userdata; pa_io_event * ret = NULL; int i; for (i = 0; i < MAX_IO_EVENTS; i++) { if ( mainloop->io_event[i].used == 0 ) { ret = &(mainloop->io_event[i]); } } if ( ret == NULL ) return NULL; ret->used = 1; ret->api = a; ret->fd = fd; ret->cb = cb; ret->userdata = userdata; // Callbacks: ret->destroy = NULL; _roar_pa_io_enable(ret, events); return ret; } /** Enable or disable IO events on this object */ static void _roar_pa_io_enable(pa_io_event* e, pa_io_event_flags_t events) { if ( e == NULL ) return; e->events = events; } /** Free a IO event source object */ static void _roar_pa_io_free(pa_io_event* e) { if ( e == NULL ) return; if ( e->destroy != NULL ) e->destroy(e->api, e, e->userdata); e->used = 0; } /** Set a function that is called when the IO event source is destroyed. Use this to free the userdata argument if required */ static void _roar_pa_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t cb) { if ( e == NULL ) return; e->destroy = cb; } // API: void _roar_pa_mainloop_quit(pa_mainloop_api*a, int retval) { pa_mainloop * m = a->userdata; pa_mainloop_quit(m, retval); } /** Allocate a new main loop object */ pa_mainloop *pa_mainloop_new(void) { pa_mainloop * m = roar_mm_malloc(sizeof(pa_mainloop)); ROAR_DBG("pa_mainloop_new() = ?"); if ( m == NULL ) return NULL; memset(m, 0, sizeof(pa_mainloop)); m->api.userdata = m; m->api.quit = _roar_pa_mainloop_quit; m->api.io_new = _roar_pa_io_new; m->api.io_enable = _roar_pa_io_enable; m->api.io_free = _roar_pa_io_free; m->api.io_set_destroy = _roar_pa_io_set_destroy; ROAR_DBG("pa_mainloop_new() = %p", m); return m; } /** Free a main loop object */ void pa_mainloop_free(pa_mainloop* m) { ROAR_DBG("pa_mainloop_free(m=%p) = ?", m); if ( m == NULL ) return; roar_mm_free(m); ROAR_DBG("pa_mainloop_free(m=%p) = (void)", m); } /** Prepare for a single iteration of the main loop. Returns a negative value on error or exit request. timeout specifies a maximum timeout for the subsequent poll, or -1 for blocking behaviour. .*/ int pa_mainloop_prepare(pa_mainloop *m, int timeout) { short events; int i; ROAR_DBG("pa_mainloop_prepare(m=%p, timeout=%i) = ?", m, timeout); if ( m == NULL ) return -1; if ( m->quit ) return -2; m->pollfds = 0; for (i = 0; i < MAX_IO_EVENTS; i++) { if ( m->io_event[i].used ) { events = 0; if ( m->io_event[i].events & PA_IO_EVENT_INPUT ) events |= POLLIN; if ( m->io_event[i].events & PA_IO_EVENT_OUTPUT ) events |= POLLOUT; if ( m->io_event[i].events & PA_IO_EVENT_HANGUP ) events |= POLLHUP; if ( m->io_event[i].events & PA_IO_EVENT_ERROR ) events |= POLLERR; if ( events == 0 ) continue; m->pollfd[m->pollfds].fd = m->io_event[i].fd; m->pollfd[m->pollfds].events = events; m->pollfds++; } } m->poll_timeout = timeout; ROAR_DBG("pa_mainloop_prepare(m=%p, timeout=%i) = 0", m, timeout); return 0; } /** Execute the previously prepared poll. Returns a negative value on error.*/ int pa_mainloop_poll(pa_mainloop *m) { int ret; int alive = 1; ROAR_DBG("pa_mainloop_poll(m=%p) = ?", m); if ( m == NULL ) return -1; if ( m->quit ) return -2; while (alive) { if ( m->poll_func != NULL ) { ret = m->poll_func(m->pollfd, m->pollfds, m->poll_timeout, m->poll_userdata); } else { #ifdef ROAR_HAVE_H_POLL ret = poll(m->pollfd, m->pollfds, m->poll_timeout); #else ret = -1; #endif } if ( ret != -1 || ( errno != EAGAIN && errno != EINTR ) ) { alive = 0; } } ROAR_DBG("pa_mainloop_poll(m=%p) = %i", m, ret); return ret; } /** Dispatch timeout, io and deferred events from the previously executed poll. Returns a negative value on error. On success returns the number of source dispatched. */ int pa_mainloop_dispatch(pa_mainloop *m) { pa_io_event_flags_t events; int count = 0; int h; nfds_t i; ROAR_DBG("pa_mainloop_dispatch(m=%p) = ?", m); if ( m == NULL ) return -1; if ( m->quit ) return -2; for (i = 0; i < m->pollfds; i++) { if ( m->pollfd[i].revents != 0 ) { for (h = 0; h < MAX_IO_EVENTS; h++) { if ( m->io_event[h].fd == m->pollfd[i].fd ) { events = PA_IO_EVENT_NULL; if ( m->pollfd[i].revents & POLLIN ) events |= PA_IO_EVENT_INPUT; if ( m->pollfd[i].revents & POLLOUT ) events |= PA_IO_EVENT_OUTPUT; if ( m->pollfd[i].revents & POLLHUP ) events |= PA_IO_EVENT_HANGUP; if ( m->pollfd[i].revents & POLLERR ) events |= PA_IO_EVENT_ERROR; if ( m->io_event[h].cb != NULL ) m->io_event[h].cb(&(m->api), &(m->io_event[h]), m->pollfd[i].fd, events, m->io_event[h].userdata); count++; } } } } ROAR_DBG("pa_mainloop_dispatch(m=%p) = %i", m, count); return count; } /** Return the return value as specified with the main loop's quit() routine. */ int pa_mainloop_get_retval(pa_mainloop *m) { if ( m == NULL ) return -1; return m->quitval; } /** Run a single iteration of the main loop. This is a convenience function for pa_mainloop_prepare(), pa_mainloop_poll() and pa_mainloop_dispatch(). Returns a negative value on error or exit request. If block is nonzero, block for events if none are queued. Optionally return the return value as specified with the main loop's quit() routine in the integer variable retval points to. On success returns the number of sources dispatched in this iteration. */ int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) { int r; ROAR_DBG("pa_mainloop_iterate(m=%p, block=%i, retval=%p) = ?", m, block, retval); if ( m == NULL ) return -1; r = pa_mainloop_prepare(m, block ? -1 : 0); if ( r >= 0 ) r = pa_mainloop_poll(m); if ( r > 0 ) r = pa_mainloop_dispatch(m); if ( r == -2 && retval != NULL ) { *retval = m->quitval; } ROAR_DBG("pa_mainloop_iterate(m=%p, block=%i, retval=%p) = %i", m, block, retval, r); return r; } /** Run unlimited iterations of the main loop object until the main loop's quit() routine is called. */ int pa_mainloop_run(pa_mainloop *m, int *retval) { int r = 1; ROAR_DBG("pa_mainloop_run(m=%p, retval=%p) = ?", m, retval); if ( m == NULL ) return -1; while (!(m->quit) && r > 0) { r = pa_mainloop_iterate(m, 1, retval); } ROAR_DBG("pa_mainloop_run(m=%p, retval=%p): r=%i", m, retval, r); if ( r == -2 ) return 1; if ( r < 0 ) return -1; return 0; } /** Return the abstract main loop abstraction layer vtable for this main loop. */ pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) { if ( m == NULL ) return NULL; return &(m->api); } /** Shutdown the main loop */ void pa_mainloop_quit(pa_mainloop *m, int r) { if ( m == NULL ) return; m->quitval = r; m->quit = 1; } /** Interrupt a running poll (for threaded systems) */ void pa_mainloop_wakeup(pa_mainloop *m); /** Change the poll() implementation */ void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) { if ( m == NULL ) return; m->poll_func = poll_func; m->poll_userdata = userdata; } //ll ���������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/operation.c��������������������������������������������������������0000644�0001750�0001750�00000005442�12264733604�017342� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//operation.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> /** An asynchronous operation object */ struct pa_operation { size_t refc; pa_operation_state_t state; }; pa_operation *roar_pa_operation_new(pa_operation_state_t initstate) { pa_operation * o = roar_mm_malloc(sizeof(pa_operation)); if ( o == NULL ) return NULL; memset(o, 0, sizeof(pa_operation)); o->refc = 1; o->state = initstate; return o; } static void _operation_free(pa_operation *o) { roar_mm_free(o); } /** Increase the reference count by one */ pa_operation *pa_operation_ref(pa_operation *o) { if ( o == NULL ) return NULL; o->refc++; return o; } /** Decrease the reference count by one */ void pa_operation_unref(pa_operation *o) { if ( o == NULL ) return; o->refc--; if ( o->refc < 1 ) _operation_free(o); } /** Cancel the operation. Beware! This will not necessarily cancel the execution of the operation on the server side. */ void pa_operation_cancel(pa_operation *o) { // we ignore this (void)o; } /** Return the current status of the operation */ pa_operation_state_t pa_operation_get_state(pa_operation *o) { if ( o == NULL ) return -1; return o->state; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/sample.c�����������������������������������������������������������0000644�0001750�0001750�00000013415�12264733604�016622� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//sample.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> /** Return the amount of bytes playback of a second of audio with the specified sample type takes */ size_t pa_bytes_per_second(const pa_sample_spec *spec) { return pa_sample_size(spec) * spec->channels * spec->rate; } /** Return the size of a frame with the specific sample type */ size_t pa_frame_size(const pa_sample_spec *spec) { if ( spec == NULL ) return 0; return pa_sample_size(spec) * spec->channels; } /** Return the size of a sample with the specific sample type */ size_t pa_sample_size(const pa_sample_spec *spec) { if ( spec == NULL ) return -1; switch (spec->format) { case PA_SAMPLE_ALAW: case PA_SAMPLE_ULAW: case PA_SAMPLE_U8: return 1; break; case PA_SAMPLE_S16LE: case PA_SAMPLE_S16BE: return 2; break; #ifdef PA_SAMPLE_S24LE case PA_SAMPLE_S24LE: case PA_SAMPLE_S24BE: return 3; break; #endif #ifdef PA_SAMPLE_S32LE case PA_SAMPLE_S32LE: case PA_SAMPLE_S32BE: case PA_SAMPLE_S24_32LE: case PA_SAMPLE_S24_32BE: return 4; break; #endif default: return 0; break; } return 0; } /** Calculate the time the specified bytes take to play with the specified sample type */ pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) { if ( spec == NULL ) return 0; return (pa_usec_t) (((double) length/pa_frame_size(spec)*1000000)/spec->rate); } /** Calculates the number of bytes that are required for the specified time. \since 0.9 */ size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) { if ( spec == NULL ) return 0; return (size_t) (((double) t * spec->rate / 1000000))*pa_frame_size(spec); } /** Return non-zero when the sample type specification is valid */ int pa_sample_spec_valid(const pa_sample_spec *spec) { if ( spec == NULL ) return 0; if ( spec->channels < 1 || spec->channels > ROAR_MAX_CHANNELS ) return 0; if ( spec->format < 0 || spec->format > PA_SAMPLE_MAX ) return 0; return 1; } /** Return non-zero when the two sample type specifications match */ int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) { if ( a->rate != b->rate ) return 0; if ( a->channels != b->channels ) return 0; if ( a->format != b->format ) return 0; return 1; } /** Return a descriptive string for the specified sample format. \since 0.8 */ static struct { pa_sample_format_t format; const char * name; } _roar_pa_format[] = { {PA_SAMPLE_U8, "u8" }, {PA_SAMPLE_ALAW, "aLaw" }, {PA_SAMPLE_ULAW, "uLaw" }, {PA_SAMPLE_S16LE, "s16le" }, {PA_SAMPLE_S16BE, "s16be" }, {PA_SAMPLE_FLOAT32LE, "float32le"}, {PA_SAMPLE_FLOAT32BE, "float32be"}, {PA_SAMPLE_INVALID, NULL } }; const char *pa_sample_format_to_string(pa_sample_format_t f) { int i; for (i = 0; _roar_pa_format[i].name != NULL; i++) if ( _roar_pa_format[i].format == f ) return _roar_pa_format[i].name; return NULL; } /** Parse a sample format text. Inverse of pa_sample_format_to_string() */ pa_sample_format_t pa_parse_sample_format(const char *format) { int i; for (i = 0; _roar_pa_format[i].name != NULL; i++) if ( !strcasecmp(_roar_pa_format[i].name, format) ) return _roar_pa_format[i].format; return PA_SAMPLE_INVALID; } /** Maximum required string length for pa_sample_spec_snprint() */ #define PA_SAMPLE_SPEC_SNPRINT_MAX 32 /** Pretty print a sample type specification to a string */ char* pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) { if ( s == NULL || l == 0 || spec == NULL ) return NULL; if ( pa_sample_spec_valid(spec) ) { snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate); } else { snprintf(s, l, "Invalid"); } return s; } /** Pretty print a byte size value. (i.e. "2.5 MiB") */ char* pa_bytes_snprint(char *s, size_t l, unsigned v) { double val = v; int i; const char pre[] = "KMGTP"; if ( v <= 1024 ) { snprintf(s, l, "%u B", v); return s; } for (i = 0; pre[i] != 0; i++) { val /= 1024; if ( val <= 1024 ) { snprintf(s, l, "%0.1f %ciB", val, pre[i]); return s; } } snprintf(s, l, "%0.1f %ciB", val*1024., pre[i-1]); return s; } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/simple.c�����������������������������������������������������������0000644�0001750�0001750�00000012356�12264733605�016636� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//simple.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> #define _seterr() if ( error != NULL ) { *error = roar_pa_raerror2paerror(err); } /** Create a new connection to the server */ pa_simple* pa_simple_new( const char *server, /**< Server name, or NULL for default */ const char *name, /**< A descriptive name for this client (application name, ...) */ pa_stream_direction_t dir, /**< Open this stream for recording or playback? */ const char *dev, /**< Sink (resp. source) name, or NULL for default */ const char *stream_name, /**< A descriptive name for this client (application name, song title, ...) */ const pa_sample_spec *ss, /**< The sample type to use */ const pa_channel_map *map, /**< The channel map to use, or NULL for default */ const pa_buffer_attr *attr, /**< Buffering attributes, or NULL for default */ int *error /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */ ) { struct roar_keyval kv[1]; roar_vs_t * vss = NULL; struct roar_audio_info info; int roar_dir; int err = ROAR_ERROR_NONE; if ( dev != NULL || map != NULL || attr != NULL ) return NULL; if ( dir == PA_STREAM_PLAYBACK ) { roar_dir = ROAR_DIR_PLAY; } else if ( dir == PA_STREAM_RECORD ) { roar_dir = ROAR_DIR_RECORD; } else { return NULL; } if ( roar_pa_sspec2auinfo(&info, ss) == -1 ) { return NULL; } server = roar_pa_find_server((char*)server); vss = roar_vs_new(server, name, &err); if ( vss == NULL ) { _seterr(); return NULL; } if ( roar_vs_stream(vss, &info, roar_dir, &err) == -1 ) { roar_vs_close(vss, ROAR_VS_TRUE, NULL); _seterr(); return NULL; } if ( stream_name != NULL && stream_name[0] != 0 ) { kv[0].key = "DESCRIPTION"; kv[0].value = (char*)stream_name; roar_vs_meta(vss, kv, 1, NULL); } return (pa_simple*) vss; } /** Close and free the connection to the server. The connection objects becomes invalid when this is called. */ void pa_simple_free(pa_simple *s) { if ( s == NULL ) return; roar_vs_close((roar_vs_t*)s, ROAR_VS_FALSE, NULL); } /** Write some data to the server */ int pa_simple_write(pa_simple *s, const void*data, size_t length, int *error) { int ret; int err = ROAR_ERROR_NONE; if ( s == NULL ) return -1; ret = roar_vs_write((roar_vs_t*)s, data, length, &err); _seterr(); return ret; } /** Wait until all data already written is played by the daemon */ int pa_simple_drain(pa_simple *s, int *error) { int ret; int err = ROAR_ERROR_NONE; if ( s == NULL ) return -1; ret = roar_vs_sync((roar_vs_t*)s, ROAR_VS_WAIT, &err); _seterr(); return ret; } /** Read some data from the server */ int pa_simple_read(pa_simple *s, void*data, size_t length, int *error) { int ret; int err = ROAR_ERROR_NONE; if ( s == NULL ) return -1; ret = roar_vs_read((roar_vs_t*)s, data, length, &err); _seterr(); return ret; } /** Return the playback latency. \since 0.5 */ pa_usec_t pa_simple_get_latency(pa_simple *s, int *error) { roar_mus_t ret; int err = ROAR_ERROR_NONE; if ( s == NULL ) return -1; ret = roar_vs_latency((roar_vs_t*)s, ROAR_VS_BACKEND_DEFAULT, ROAR_VS_WAIT, &err); if ( ret < 0 ) ret *= -1; if ( ret == 0 && err != ROAR_ERROR_NONE ) { _seterr(); return -1; } return ret; } /** Flush the playback buffer. \since 0.5 */ int pa_simple_flush(pa_simple *s, int *error) { int ret; int err = ROAR_ERROR_NONE; if ( s == NULL ) return -1; ret = roar_vs_sync((roar_vs_t*)s, ROAR_VS_NOWAIT, &err); _seterr(); return ret; } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/stream.c�����������������������������������������������������������0000644�0001750�0001750�00000063374�12264733605�016646� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stream.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> struct _roar_pa_stream_cb { union { pa_stream_notify_cb_t ncb; pa_stream_request_cb_t rcb; pa_stream_success_cb_t scb; } cb; void * userdata; }; struct pa_stream { size_t refc; pa_context * c; struct roar_vio_calls vio; struct roar_stream stream; pa_stream_state_t state; pa_sample_spec sspec; pa_io_event * io_event; pa_timing_info timinginfo; pa_buffer_attr bufattr; pa_stream_direction_t dir; struct roar_buffer * iobuffer; struct { size_t size; size_t num; } fragments; struct { struct _roar_pa_stream_cb change_state; struct _roar_pa_stream_cb write; struct _roar_pa_stream_cb read; struct _roar_pa_stream_cb overflow; struct _roar_pa_stream_cb underflow; struct _roar_pa_stream_cb latency; struct _roar_pa_stream_cb drain; } cb; struct { pa_operation * drain; } op; }; typedef struct pa_proplist pa_proplist; void pa_stream_set_state(pa_stream *s, pa_stream_state_t st); pa_stream* pa_stream_new_with_proplist( pa_context *c , const char *name , const pa_sample_spec *ss , const pa_channel_map *map , pa_proplist *p ); /** Create a new, unconnected stream with the specified name and sample type */ pa_stream* pa_stream_new( pa_context *c /**< The context to create this stream in */, const char *name /**< A name for this stream */, const pa_sample_spec *ss /**< The desired sample format */, const pa_channel_map *map /**< The desired channel map, or NULL for default */) { return pa_stream_new_with_proplist(c, name, ss, map, NULL); } pa_stream* pa_stream_new_with_proplist( pa_context *c , const char *name , const pa_sample_spec *ss , const pa_channel_map *map , pa_proplist *p ) { pa_stream * s; ROAR_DBG("pa_stream_new_with_proplist(c=%p, name='%s', ss=%p, map=%p, p=%p) = ?", c, name, ss, map, p); if ( p != NULL ) return NULL; if ( (s = roar_mm_malloc(sizeof(pa_stream))) == NULL ) return NULL; memset(s, 0, sizeof(pa_stream)); memcpy(&(s->sspec), ss, sizeof(pa_sample_spec)); ROAR_DBG("pa_stream_new_with_proplist(c=%p, name='%s', ss=%p, map=%p, p=%p) = ?", c, name, ss, map, p); s->fragments.num = 4; s->fragments.size = 2048; s->state = PA_STREAM_UNCONNECTED; s->c = c; pa_context_ref(c); ROAR_DBG("pa_stream_new_with_proplist(c=%p, name='%s', ss=%p, map=%p, p=%p) = ?", c, name, ss, map, p); return s; } static void _pa_stream_free(pa_stream * s) { pa_stream_disconnect(s); pa_context_unref(s->c); roar_mm_free(s); } /** Decrease the reference counter by one */ void pa_stream_unref(pa_stream *s) { if ( s == NULL ) return; s->refc--; if (s->refc < 1 ) _pa_stream_free(s); } /** Increase the reference counter by one */ pa_stream *pa_stream_ref(pa_stream *s) { if ( s == NULL ) return NULL; s->refc++; return s; } /** Return the current state of the stream */ pa_stream_state_t pa_stream_get_state(pa_stream *p) { if ( p == NULL ) return PA_STREAM_FAILED; return p->state; } /** Return the context this stream is attached to */ pa_context* pa_stream_get_context(pa_stream *p) { if ( p == NULL ) return NULL; return p->c; } /** Return the device (sink input or source output) index this stream is connected to */ uint32_t pa_stream_get_index(pa_stream *s) { struct roar_stream_info info; if ( roar_stream_get_info(roar_pa_context_get_con(s->c), &(s->stream), &info) == -1 ) return 0; if ( info.mixer == -1 ) return 0; return info.mixer; } static void _roar_pa_stream_ioecb(pa_mainloop_api * ea, pa_io_event * e, int fd, pa_io_event_flags_t events, void * userdata) { struct roar_buffer * buf; pa_stream * s = userdata; void * data; size_t len; ssize_t ret; int bufret; (void)fd, (void)events; ROAR_DBG("_roar_pa_stream_ioecb(*) = ?"); switch (s->dir) { case PA_STREAM_PLAYBACK: if ( s->iobuffer != NULL ) { if ( roar_buffer_get_data(s->iobuffer, &data) == -1 ) return; if ( roar_buffer_get_len(s->iobuffer, &len) == -1 ) return; if ( (ret = roar_vio_write(&(s->vio), data, len)) == -1 ) return; ROAR_DBG("_roar_pa_stream_ioecb(*): vio write() = %lli", (long long int) ret); // TODO: handle errors if ( ret == (ssize_t)len ) { bufret = roar_buffer_next(&(s->iobuffer)); } else { bufret = roar_buffer_set_offset(s->iobuffer, ret); } if ( bufret == -1 ) { ROAR_WARN("_roar_pa_stream_ioecb(*): Altering buffer after write failed. Bad."); return; } } if ( s->iobuffer == NULL ) { ROAR_DBG("_roar_pa_stream_ioecb(*): disable IO events"); ea->io_enable(e, PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR); if ( s->cb.write.cb.rcb != NULL ) s->cb.write.cb.rcb(s, pa_stream_writable_size(s), s->cb.write.userdata); if ( s->cb.drain.cb.scb != NULL ) s->cb.drain.cb.scb(s, 1, s->cb.drain.userdata); } break; case PA_STREAM_RECORD: if ( roar_buffer_new_data(&buf, s->fragments.size, &data) == -1 ) return; if ( (ret = roar_vio_read(&(s->vio), data, s->fragments.size)) < 1 ) { roar_buffer_free(buf); return; } if ( roar_buffer_set_len(buf, ret) == -1 ) { // bad error roar_buffer_free(buf); return; } if ( s->iobuffer == NULL ) { s->iobuffer = buf; } else { if ( roar_buffer_moveinto(s->iobuffer, &buf) == -1 ) { roar_buffer_free(buf); return; } } if ( s->cb.read.cb.rcb != NULL ) s->cb.read.cb.rcb(s, pa_stream_readable_size(s), s->cb.read.userdata); break; default: return; } ROAR_DBG("_roar_pa_stream_ioecb(*) = (void)"); } static int _roar_pa_stream_open (pa_stream *s, const char *dev, const pa_buffer_attr *attr, pa_stream_flags_t flags, pa_cvolume *volume, pa_stream *sync_stream, pa_stream_direction_t dir) { struct roar_connection * con; pa_mainloop_api * api; pa_io_event_flags_t event_flags = PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR; int fh; int ctl = -1; ROAR_DBG("_roar_pa_stream_open(s=%p, dev='%s', attr=%p, flags=%i, volume=%p, sync_stream=%p, dir=%i) = ?", s, dev, attr, flags, volume, sync_stream, dir); if ( s == NULL ) return -1; volume = NULL; if ( dev != NULL || attr != NULL || flags != 0 || volume != NULL || sync_stream != NULL ) { pa_stream_set_state(s, PA_STREAM_FAILED); return -1; } if ( (con = roar_pa_context_get_con(s->c)) == NULL ) { pa_stream_set_state(s, PA_STREAM_FAILED); return -1; } s->dir = dir; switch (dir) { case PA_STREAM_PLAYBACK: s->stream.dir = ROAR_DIR_PLAY; ctl = ROAR_VIO_CTL_GET_SELECT_WRITE_FH; event_flags |= PA_IO_EVENT_OUTPUT; break; case PA_STREAM_RECORD: s->stream.dir = ROAR_DIR_RECORD; ctl = ROAR_VIO_CTL_GET_SELECT_READ_FH; event_flags |= PA_IO_EVENT_INPUT; break; default: pa_stream_set_state(s, PA_STREAM_FAILED); return -1; break; } if ( roar_pa_sspec2auinfo(&(s->stream.info), &(s->sspec)) == -1 ) { pa_stream_set_state(s, PA_STREAM_FAILED); return -1; } if ( roar_vio_simple_new_stream_obj(&(s->vio), con, &(s->stream), s->stream.info.rate, s->stream.info.channels, s->stream.info.bits, s->stream.info.codec, s->stream.dir, -1 /* TODO: FIXME: set to requested mixer */ ) == -1 ) { pa_stream_set_state(s, PA_STREAM_FAILED); return -1; } api = roar_pa_context_get_api(s->c); if ( api != NULL && api->io_new != NULL ) { if ( roar_vio_ctl(&(s->vio), ctl, &fh) != -1 ) { s->io_event = api->io_new(api, fh, event_flags, _roar_pa_stream_ioecb, s); } } // TODO: update s->fragments. s->bufattr.maxlength = s->fragments.size * s->fragments.num; s->bufattr.tlength = s->fragments.size; s->bufattr.prebuf = 0; s->bufattr.minreq = 1; s->bufattr.fragsize = s->fragments.size; pa_stream_set_state(s, PA_STREAM_READY); return 0; } /** Connect the stream to a sink */ int pa_stream_connect_playback( pa_stream *s /**< The stream to connect to a sink */, const char *dev /**< Name of the sink to connect to, or NULL for default */ , const pa_buffer_attr *attr /**< Buffering attributes, or NULL for default */, pa_stream_flags_t flags /**< Additional flags, or 0 for default */, ROAR_HAVE_ARG_VOLUME_OF_PA_STREAM_CONNECT_PLAYBACK volume /**< Initial volume, or NULL for default */, pa_stream *sync_stream /**< Synchronize this stream with the specified one, or NULL for a standalone stream*/) { return _roar_pa_stream_open(s, dev, attr, flags, (pa_cvolume*)volume, sync_stream, PA_STREAM_PLAYBACK); } /** Connect the stream to a source */ int pa_stream_connect_record( pa_stream *s /**< The stream to connect to a source */ , const char *dev /**< Name of the source to connect to, or NULL for default */, const pa_buffer_attr *attr /**< Buffer attributes, or NULL for default */, pa_stream_flags_t flags /**< Additional flags, or 0 for default */) { return _roar_pa_stream_open(s, dev, attr, flags, NULL, NULL, PA_STREAM_RECORD); } /** Disconnect a stream from a source/sink */ int pa_stream_disconnect(pa_stream *s) { pa_mainloop_api * api; if ( s == NULL ) return -1; if ( s->state != PA_STREAM_READY ) return -1; if ( s->io_event != NULL ) { api = roar_pa_context_get_api(s->c); if ( api != NULL && api->io_free != NULL ) { api->io_free(s->io_event); s->io_event = NULL; } } roar_vio_close(&(s->vio)); pa_stream_set_state(s, PA_STREAM_TERMINATED); return 0; } /** Write some data to the server (for playback sinks), if free_cb is * non-NULL this routine is called when all data has been written out * and an internal reference to the specified data is kept, the data * is not copied. If NULL, the data is copied into an internal * buffer. The client my freely seek around in the output buffer. For * most applications passing 0 and PA_SEEK_RELATIVE as arguments for * offset and seek should be useful.*/ int pa_stream_write( pa_stream *p /**< The stream to use */, const void *data /**< The data to write */, size_t length /**< The length of the data to write */, pa_free_cb_t free_cb /**< A cleanup routine for the data or NULL to request an internal copy */, int64_t offset, /**< Offset for seeking, must be 0 for upload streams */ pa_seek_mode_t seek /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */) { pa_mainloop_api * api; struct roar_buffer * buf; void * bufdata; ROAR_DBG("pa_stream_write(p=%p, data=%p, length=%llu, free_cb=%p, offset=%lli, seek=%i) = ?", p, data, (long long unsigned int) length, free_cb, offset, seek); // TODO: implement seeking in output buffer if ( p == NULL ) return -1; if ( offset != 0 || seek != PA_SEEK_RELATIVE ) return -1; if ( data == NULL ) { if ( length == 0 ) { if ( free_cb != NULL ) free_cb(NULL); return 0; } else { return -1; } } // seems we have a valid write from here. if ( roar_buffer_new_data(&buf, length, &bufdata) == -1 ) { if ( free_cb != NULL ) free_cb((void*)data); return -1; } memcpy(bufdata, data, length); if ( free_cb != NULL ) free_cb((void*)data); if ( p->iobuffer == NULL ) { p->iobuffer = buf; } else { if ( roar_buffer_moveinto(p->iobuffer, &buf) == -1 ) { roar_buffer_free(buf); return -1; } } if ( p->io_event != NULL ) { api = roar_pa_context_get_api(p->c); if ( api != NULL ) { ROAR_DBG("pa_stream_write(*): enable IO events"); api->io_enable(p->io_event, PA_IO_EVENT_OUTPUT|PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR); } } ROAR_DBG("pa_stream_write(p=%p, data=%p, length=%llu, free_cb=%p, offset=%lli, seek=%i) = 0", p, data, (long long unsigned int) length, free_cb, offset, seek); return 0; } /** Read the next fragment from the buffer (for recording). * data will point to the actual data and length will contain the size * of the data in bytes (which can be less than a complete framgnet). * Use pa_stream_drop() to actually remove the data from the * buffer. If no data is available will return a NULL pointer \since 0.8 */ int pa_stream_peek( pa_stream *p /**< The stream to use */, const void **data /**< Pointer to pointer that will point to data */, size_t *length /**< The length of the data read */) { if ( data == NULL || length == NULL ) return -1; *data = NULL; *length = 0; if ( p == NULL ) return -1; if ( p->iobuffer == NULL ) return 0; if ( roar_buffer_get_len(p->iobuffer, length) == -1 ) { *length = 0; return -1; } if ( roar_buffer_get_data(p->iobuffer, (void**)data) == -1 ) { *length = 0; *data = NULL; return -1; } return 0; } /** Remove the current fragment on record streams. It is invalid to do this without first * calling pa_stream_peek(). \since 0.8 */ int pa_stream_drop(pa_stream *p) { if ( p == NULL ) return -1; if ( p->iobuffer == NULL ) return -1; return roar_buffer_next(&(p->iobuffer)); } /** Return the nember of bytes that may be written using pa_stream_write() */ size_t pa_stream_writable_size(pa_stream *p) { struct roar_buffer_stats stats; ROAR_DBG("pa_stream_writable_size(p=%p) = ?", p); if ( p == NULL ) { ROAR_DBG("pa_stream_writable_size(p=%p) = 0", p); return 0; } if ( p->iobuffer == NULL ) { ROAR_DBG("pa_stream_writable_size(p=%p) = %llu", p, (long long unsigned)(p->fragments.num*p->fragments.size)); return p->fragments.num * p->fragments.size / 2; } if ( roar_buffer_ring_stats(p->iobuffer, &stats) == -1 ) { ROAR_DBG("pa_stream_writable_size(p=%p) = 0", p); return 0; } ROAR_DBG("pa_stream_writable_size(p=%p): stats={.parts=%i, .bytes=%i, ...}", p, stats.parts, stats.bytes); if ( stats.parts > p->fragments.num ) { ROAR_DBG("pa_stream_writable_size(p=%p) = 0", p); return 0; } if ( stats.parts > (p->fragments.num/2) ) stats.parts = p->fragments.num / 2; ROAR_DBG("pa_stream_writable_size(p=%p) = %llu", p, (long long unsigned)((p->fragments.num - stats.parts)*p->fragments.size)); return (p->fragments.num - stats.parts)*p->fragments.size; } /** Return the number of bytes that may be read using pa_stream_read() \since 0.8 */ size_t pa_stream_readable_size(pa_stream *p) { struct roar_buffer_stats stats; if ( p == NULL ) return 0; if ( p->iobuffer == NULL ) return 0; if ( roar_buffer_ring_stats(p->iobuffer, &stats) == -1 ) return 0; return stats.bytes; } /** Drain a playback stream. Use this for notification when the buffer is empty */ pa_operation* pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { if ( s == NULL ) return NULL; s->cb.drain.cb.scb = cb; s->cb.drain.userdata = userdata; if ( s->op.drain == NULL ) { s->op.drain = roar_pa_operation_new(PA_OPERATION_RUNNING); } pa_operation_ref(s->op.drain); return s->op.drain; } /** Request a timing info structure update for a stream. Use * pa_stream_get_timing_info() to get access to the raw timing data, * or pa_stream_get_time() or pa_stream_get_latency() to get cleaned * up values. */ pa_operation* pa_stream_update_timing_info(pa_stream *p, pa_stream_success_cb_t cb, void *userdata) { int suc = 1; if ( p == NULL ) return NULL; if ( roar_get_stream(roar_pa_context_get_con(p->c), &(p->stream), p->stream.id) == -1 ) { suc = 0; } // p->timinginfo pa_gettimeofday(&(p->timinginfo.timestamp)); // we should interpolate between time before call and after p->timinginfo.synchronized_clocks = 0; p->timinginfo.sink_usec = 0; p->timinginfo.source_usec = 0; p->timinginfo.transport_usec = 0; p->timinginfo.playing = p->iobuffer != NULL; p->timinginfo.write_index_corrupt = 1; p->timinginfo.write_index = p->stream.pos * pa_frame_size(&(p->sspec)); p->timinginfo.read_index_corrupt = 1; p->timinginfo.read_index = p->stream.pos * pa_frame_size(&(p->sspec)); #if 0 /* newer versions */ p->timinginfo.configured_sink_usec = p->timinginfo.sink_usec; p->timinginfo.configured_source_usec = p->timinginfo.source_usec; p->timinginfo.since_underrun = 0; #endif if ( cb != NULL ) { cb(p, suc, userdata); } return roar_pa_op_new_done(); } /** Set the callback function that is called whenever the state of the stream changes */ void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { ROAR_DBG("pa_stream_set_state_callback(s=%p, cb=%p, userdata=%p) = ?", s, cb, userdata); if ( s == NULL ) return; s->cb.change_state.cb.ncb = cb; s->cb.change_state.userdata = userdata; } void pa_stream_set_state(pa_stream *s, pa_stream_state_t st) { if ( s == NULL ) return; ROAR_DBG("pa_stream_set_state(s=%p, st=%i): State: %i->%i", s, st, s->state, st); s->state = st; if ( s->cb.change_state.cb.ncb != NULL ) { ROAR_DBG("pa_stream_set_state(s=%p, st=%i): calling callback at %p", s, st, s->cb.change_state.cb.ncb); s->cb.change_state.cb.ncb(s, s->cb.change_state.userdata); } ROAR_DBG("pa_stream_set_state(s=%p, st=%i) = (void)", s, st); } /** Set the callback function that is called when new data may be * written to the stream. */ void pa_stream_set_write_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata) { if ( p == NULL ) return; p->cb.write.cb.rcb = cb; p->cb.write.userdata = userdata; } /** Set the callback function that is called when new data is available from the stream. * Return the number of bytes read. \since 0.8 */ void pa_stream_set_read_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata) { if ( p == NULL ) return; p->cb.read.cb.rcb = cb; p->cb.read.userdata = userdata; } /** Set the callback function that is called when a buffer overflow happens. (Only for playback streams) \since 0.8 */ void pa_stream_set_overflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata) { if ( p == NULL ) return; p->cb.overflow.cb.ncb = cb; p->cb.overflow.userdata = userdata; } /** Set the callback function that is called when a buffer underflow happens. (Only for playback streams) \since 0.8 */ void pa_stream_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata) { if ( p == NULL ) return; p->cb.underflow.cb.ncb = cb; p->cb.underflow.userdata = userdata; } /** Set the callback function that is called whenever a latency information update happens. Useful on PA_STREAM_AUTO_TIMING_UPDATE streams only. (Only for playback streams) \since 0.8.2 */ void pa_stream_set_latency_update_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata) { if ( p == NULL ) return; p->cb.latency.cb.ncb = cb; p->cb.latency.userdata = userdata; } /** Pause (or resume) playback of this stream temporarily. Available on both playback and recording streams. \since 0.3 */ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata) { int action = b ? ROAR_SET_FLAG : ROAR_RESET_FLAG; if ( roar_stream_set_flags(roar_pa_context_get_con(s->c), &(s->stream), ROAR_FLAG_PAUSE, action) == -1 ) { cb(s, 0, userdata); } else { cb(s, 1, userdata); } return roar_pa_operation_new(PA_OPERATION_DONE); } /** Return 1 if the this stream has been corked. This will return 0 if * not, and negative on error. \since 0.9.11 */ int pa_stream_is_corked(pa_stream *s) { struct roar_stream_info info; if ( roar_stream_get_info(roar_pa_context_get_con(s->c), &(s->stream), &info) == -1 ) return -1; return (info.flags & ROAR_FLAG_PAUSE) ? 1 : 0; } /** Flush the playback buffer of this stream. Most of the time you're * better off using the parameter delta of pa_stream_write() instead of this * function. Available on both playback and recording streams. \since 0.3 */ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { return pa_stream_drain(s, cb, userdata); // where is the differance to drain? } /** Reenable prebuffering as specified in the pa_buffer_attr * structure. Available for playback streams only. \since 0.6 */ pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *userdata); /** Request immediate start of playback on this stream. This disables * prebuffering as specified in the pa_buffer_attr * structure, temporarily. Available for playback streams only. \since 0.3 */ pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata); /** Rename the stream. \since 0.5 */ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_success_cb_t cb, void *userdata); /** Return the current playback/recording time. This is based on the * data in the timing info structure returned by * pa_stream_get_timing_info(). This function will usually only return * new data if a timing info update has been recieved. Only if timing * interpolation has been requested (PA_STREAM_INTERPOLATE_TIMING) * the data from the last timing update is used for an estimation of * the current playback/recording time based on the local time that * passed since the timing info structure has been acquired. The time * value returned by this function is guaranteed to increase * monotonically. (that means: the returned value is always greater or * equal to the value returned on the last call) This behaviour can * be disabled by using PA_STREAM_NOT_MONOTONOUS. This may be * desirable to deal better with bad estimations of transport * latencies, but may have strange effects if the application is not * able to deal with time going 'backwards'. \since 0.6 */ int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec) { if ( s == NULL || r_usec == NULL ) return -1; *r_usec = s->stream.pos * 1000000 / s->stream.info.rate / s->stream.info.channels; return 0; } /** Return the total stream latency. This function is based on * pa_stream_get_time(). In case the stream is a monitoring stream the * result can be negative, i.e. the captured samples are not yet * played. In this case *negative is set to 1. \since 0.6 */ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) { // TODO: Fix this: // sinks: lateny of stream, mixer, output... // sources: mixer, output, negative if ( r_usec != NULL ) *r_usec = 0; if ( negative != NULL ) *negative = 0; return 0; } /** Return the latest raw timing data structure. The returned pointer * points to an internal read-only instance of the timing * structure. The user should make a copy of this structure if he * wants to modify it. An in-place update to this data structure may * be requested using pa_stream_update_timing_info(). If no * pa_stream_update_timing_info() call was issued before, this * function will fail with PA_ERR_NODATA. Please note that the * write_index member field (and only this field) is updated on each * pa_stream_write() call, not just when a timing update has been * recieved. \since 0.8 */ const pa_timing_info* pa_stream_get_timing_info(pa_stream *s) { if ( s == NULL ) return NULL; return &(s->timinginfo); } /** Return a pointer to the stream's sample specification. \since 0.6 */ const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s) { if ( s == NULL ) return NULL; return &(s->sspec); } /** Return a pointer to the stream's channel map. \since 0.8 */ const pa_channel_map* pa_stream_get_channel_map(pa_stream *s); /** Return the buffer metrics of the stream. Only valid after the * stream has been connected successfuly and if the server is at least * PulseAudio 0.9. \since 0.9.0 */ const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s) { if ( s == NULL ) return NULL; return &(s->bufattr); } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/timeval.c����������������������������������������������������������0000644�0001750�0001750�00000004616�12264733606�017007� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//timeval.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> struct timeval *pa_gettimeofday(struct timeval *tv) { #ifdef ROAR_HAVE_GETTIMEOFDAY if ( gettimeofday(tv, NULL) == -1 ) { return NULL; } else { return tv; } #else return NULL; #endif } pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b); int pa_timeval_cmp(const struct timeval *a, const struct timeval *b); pa_usec_t pa_timeval_age(const struct timeval *tv); struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { unsigned long long int secs; if ( tv == NULL ) return NULL; secs = v/1000000LLU; tv->tv_sec += secs; v -= secs*1000000LLU; tv->tv_usec += v; while ( tv->tv_usec > 1000000LL ) { tv->tv_usec -= 1000000LL; tv->tv_sec += 1; } return tv; } //ll ������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/utf8.c�������������������������������������������������������������0000644�0001750�0001750�00000006432�12264733606�016232� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//utf8.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> #ifdef ROAR_HAVE_H_ICONV #include <iconv.h> #endif /** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */ ROAR_HAVE_TYPE_PA_UTF8_VALID pa_utf8_valid(const char *str); /** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */ char *pa_utf8_filter(const char *str); static char * _roar_pa_iconv(const char * str, const char * from, const char * to) { #ifdef ROAR_HAVE_H_ICONV iconv_t cd; char * out; char * ip, * op; size_t il, ol; size_t inlen; size_t outlen; size_t ret; if ( str == NULL ) return NULL; if ( from == NULL ) from = ""; if ( to == NULL ) to = ""; inlen = strlen(str); outlen = inlen * 1.2; if ( (out = pa_xmalloc(outlen)) == NULL ) return NULL; if ( (cd = iconv_open(from, to)) == (iconv_t)(-1) ) return NULL; while (1) { ip = (char*) str; op = out; il = inlen; ol = outlen; ret = iconv(cd, &ip, &il, &op, &ol); if ( ret != (size_t)-1 ) break; if ( errno != E2BIG ) { pa_xfree(out); out = NULL; break; } outlen += il * 1.2; out = pa_xrealloc(out, outlen); } iconv_close(cd); return out; #else return NULL; #endif } /** Convert a UTF-8 string to the current locale. Free the string using pa_xfree(). */ char* pa_utf8_to_locale (const char *str) { return _roar_pa_iconv(str, "UTF-8", NULL); } /** Convert a string in the current locale to UTF-8. Free the string using pa_xfree(). */ char* pa_locale_to_utf8 (const char *str) { return _roar_pa_iconv(str, NULL, "UTF-8"); } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/util.c�������������������������������������������������������������0000644�0001750�0001750�00000011443�12264733606�016317� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//util.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> /** Return the binary file name of the current process. This is not * supported on all architectures, in which case NULL is returned. */ char *pa_get_binary_name(char *s, size_t l) { #ifdef __linux__ int ret; char path[PATH_MAX]; if ( (ret = readlink("/proc/self/exe", path, PATH_MAX-1)) != -1 ) { path[ret] = 0; return strncpy(s, pa_path_get_filename(path), l); } #endif return NULL; } /** Return a pointer to the filename inside a path (which is the last * component). */ // some versions declare this as const char * f(...) // and newer(?) versions as char * f(...)... ROAR_HAVE_TYPE_PA_PATH_GET_FILENAME pa_path_get_filename(const char *p) { char * r; if ( (r = strrchr(p, '/')) ) { return (ROAR_HAVE_TYPE_PA_PATH_GET_FILENAME) r+1; } else { return (ROAR_HAVE_TYPE_PA_PATH_GET_FILENAME) p; } } /** Return the current username in the specified string buffer. */ char *pa_get_user_name(char *s, size_t l) { const char * user = NULL; if ( s == NULL ) { roar_err_set(ROAR_ERROR_FAULT); roar_err_to_errno(); return NULL; } if ( user == NULL ) user = roar_env_get("USER"); if ( user == NULL ) user = roar_env_get("LOGNAME"); if ( user == NULL ) user = roar_env_get("USERNAME"); #ifdef ROAR_HAVE_GETUID if ( user == NULL ) if ( getuid() == 0 ) user = "root"; #endif if ( user == NULL ) { roar_err_set(ROAR_ERROR_NOENT); roar_err_to_errno(); return NULL; } strncpy(s, user, l); s[l-1] = 0; return s; } /** Return the current hostname in the specified buffer. */ char *pa_get_host_name(char *s, size_t l) { #ifdef ROAR_HAVE_GETHOSTNAME if (gethostname(s, l) == -1) return NULL; s[l-1] = 0; return s; #else roar_err_set(ROAR_ERROR_NOSYS); roar_err_to_errno(); return NULL; #endif } /** Return the fully qualified domain name in s */ char *pa_get_fqdn(char *s, size_t l); /** Return the home directory of the current user */ char *pa_get_home_dir(char *s, size_t l) { if ( roar_env_render_path_r(s, l, "~/") == -1 ) return NULL; return s; } /** Wait t milliseconds */ int pa_msleep(unsigned long t) { roar_usleep((uint_least32_t)1000*(uint_least32_t)t); return 0; } /* Format the specified data as a hexademical string */ char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) { const char table[] = "0123456789abcdef"; char * p = s; size_t i; for (i = 0; i < dlength && slength > 2; i++, slength -= 2, d++) { *(p++) = table[*d >> 4]; *(p++) = table[*d & 0x0F]; } *p = 0; return s; } /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */ size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) { size_t have = 0; register int low_nibble = 0; register char c; if ( dlength == 0 ) return 0; for (; (c = *p); p++) { if ( c >= '0' && c <= '9' ) { c -= '0'; } else if ( c >= 'a' && c <= 'f' ) { c -= 'a' - 10; } else if ( c >= 'A' && c <= 'F' ) { c -= 'A' - 10; } else { return (size_t)-1; } if ( low_nibble ) { *d |= c & 0x0F; low_nibble = 0; d++; have++; dlength--; if ( dlength == 0 ) return have; } else { *d = (c & 0x0F) << 4; low_nibble = 1; } } return have; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/version-script�����������������������������������������������������0000644�0001750�0001750�00000000036�11756014234�020076� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������PULSE_0 { global: pa_*; }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/version.c����������������������������������������������������������0000644�0001750�0001750�00000003422�12264733607�017026� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//version.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> const char * pa_get_library_version (void) { return pa_get_headers_version(); } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/volume.c�����������������������������������������������������������0000644�0001750�0001750�00000010470�12264733607�016651� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//volume.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> /** Return non-zero when *a == *b */ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) { int i; if ( a == b ) return 1; if ( a == NULL || b == NULL ) return 0; if ( a->channels != b->channels ) return 0; for (i = 0; i < a->channels; i++) if ( a->values[i] != b->values[i] ) return 0; return 1; } /** Set the volume of all channels to the specified parameter */ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) { unsigned int i; if ( a == NULL ) return NULL; if ( channels > PA_CHANNELS_MAX ) return NULL; a->channels = channels; for (i = 0; i < channels; i++) { a->values[i] = v; } return a; } /** Pretty print a volume structure */ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c); /** Return the average volume of all channels */ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) { int64_t sum = 0; int i; #ifndef PA_VOLUME_INVALID #define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX) #endif if ( a == NULL ) return PA_VOLUME_INVALID; for (i = 0; i < a->channels; i++) sum += a->values[i]; return sum/a->channels; } /** Return TRUE when the passed cvolume structure is valid, FALSE otherwise */ int pa_cvolume_valid(const pa_cvolume *v) { if ( v == NULL ) return 0; if ( v->channels <= 0 ) return 0; if ( v->channels > PA_CHANNELS_MAX ) return 0; return 1; } /** Return non-zero if the volume of all channels is equal to the specified value */ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) { int i; if ( a == NULL ) return 0; for (i = 0; i < a->channels; i++) if ( a->values[i] != v ) return 0; return 1; } /** Multiply two volumes specifications, return the result. This uses PA_VOLUME_NORM as neutral element of multiplication. This is only valid for software volumes! */ pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b); /** Multiply to per-channel volumes and return the result in *dest. This is only valid for software volumes! */ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b); /** Convert a decibel value to a volume. This is only valid for software volumes! \since 0.4 */ pa_volume_t pa_sw_volume_from_dB(double f); /** Convert a volume to a decibel value. This is only valid for software volumes! \since 0.4 */ double pa_sw_volume_to_dB(pa_volume_t v); /** Convert a linear factor to a volume. This is only valid for software volumes! \since 0.8 */ pa_volume_t pa_sw_volume_from_linear(double v); /** Convert a volume to a linear factor. This is only valid for software volumes! \since 0.8 */ double pa_sw_volume_to_linear(pa_volume_t v); //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/x11.c��������������������������������������������������������������0000644�0001750�0001750�00000005165�12264733607�015760� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//x11.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> #ifndef ROAR_HAVE_LIBX11 typedef void Display; #endif void pa_x11_set_prop(Display *d, const char *name, const char *data) { struct roar_x11_connection * x11con = roar_x11_connect_display(d); if ( x11con == NULL ) return; roar_x11_set_prop(x11con, name, data); roar_x11_disconnect(x11con); } void pa_x11_del_prop(Display *d, const char *name) { struct roar_x11_connection * x11con = roar_x11_connect_display(d); if ( x11con == NULL ) return; roar_x11_delete_prop(x11con, name); roar_x11_disconnect(x11con); } char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) { struct roar_x11_connection * x11con = roar_x11_connect_display(d); char * val; size_t len; if ( x11con == NULL ) return NULL; val = roar_x11_get_prop(x11con, name); roar_x11_disconnect(x11con); if ( val == NULL ) return NULL; len = strlen(val); if ( (l - 1) < len ) len = l - 1; memcpy(p, val, len); p[len] = 0; return p; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarpulse/xmalloc.c����������������������������������������������������������0000644�0001750�0001750�00000005602�12264733610�016774� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//xmalloc.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from libpulse*. They are mostly copyrighted by: * Lennart Poettering <poettering@users.sourceforge.net> and * Pierre Ossman <drzeus@drzeus.cx> * * This file is part of libroarpulse a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this libroar * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #include <libroarpulse/libroarpulse.h> /** Allocate the specified number of bytes, just like malloc() does. However, in case of OOM, terminate */ void* pa_xmalloc(size_t l) { return roar_mm_malloc(l); } /** Same as pa_xmalloc(), but initialize allocated memory to 0 */ void *pa_xmalloc0(size_t l) { void * data = roar_mm_malloc(l); if ( data == NULL ) return NULL; memset(data, 0, l); return data; } /** The combination of pa_xmalloc() and realloc() */ void *pa_xrealloc(void *ptr, size_t size) { return roar_mm_realloc(ptr, size); } /** Free allocated memory */ void pa_xfree(void *p) { roar_mm_free(p); } /** Duplicate the specified string, allocating memory with pa_xmalloc() */ char *pa_xstrdup(const char *s) { return roar_mm_strdup(s); } /** Duplicate the specified string, but truncate after l characters */ char *pa_xstrndup(const char *s, size_t l) { size_t i; char * data; for (i = 0; i < l && s[i] != 0; i++); if ( (data = roar_mm_malloc(i+1)) == NULL ) return NULL; memcpy(data, s, i); data[i] = 0; return data; } /** Duplicate the specified memory block */ void* pa_xmemdup(const void *p, size_t l) { void * data = roar_mm_malloc(l); if ( data == NULL ) return NULL; memcpy(data, p, l); return data; } //ll ������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarrsound/������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553176�015362� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarrsound/Makefile����������������������������������������������������������0000644�0001750�0001750�00000001345�12072565215�017014� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc BASENAME=libroarrsound LIB=$(BASENAME)$(SHARED_SUFFIX) ALIB=$(BASENAME).a TARGETS=$(SLIB) $(ALIB) $(IMPLIB) OBJS=libroarrsound.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroarrsound CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) $(LDPATH) -L../lib/ LIBS = $(LIBROAR) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(COMMON_SOVERSION) -o $(SLIB) ${OBJS} ${LIBS} $(ALIB): ${OBJS} ${AR} cru $(ALIB) ${OBJS} ${RANLIB} $(ALIB) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarrsound/libroarrsound.c���������������������������������������������������0000644�0001750�0001750�00000031562�12264733610�020410� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarrsound.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from RSound. * They are copyrighted by Hans-Kristian 'maister' Arntzen. * * This file is part of libroarrsound a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #define RSD_EXPOSE_STRUCT #include "libroarrsound.h" #if defined(RSD_S32_LE) && defined(RSD_S32_BE) && defined(RSD_S32_NE) && defined(RSD_U32_LE) && defined(RSD_U32_BE) && defined(RSD_U32_NE) #define _HAVE_32BIT_SUPPORT #endif static size_t libroarrsound_fmt2fs (enum rsd_format format) { switch (format) { #ifdef _HAVE_32BIT_SUPPORT case RSD_S32_LE: case RSD_S32_BE: case RSD_S32_NE: case RSD_U32_LE: case RSD_U32_BE: case RSD_U32_NE: return 32; break; #endif case RSD_S16_LE: case RSD_S16_BE: case RSD_S16_NE: case RSD_U16_LE: case RSD_U16_BE: case RSD_U16_NE: return 16; break; case RSD_U8: case RSD_S8: case RSD_ALAW: case RSD_MULAW: return 8; break; default: return 0; break; } } int rsd_init (rsound_t **rd) { struct libroarrsound * self; ROAR_DBG("rsd_init(rd=%p) = ?", rd); if ( rd == NULL ) return -1; self = roar_mm_malloc(sizeof(struct libroarrsound)); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct libroarrsound)); *rd = (rsound_t*)self; self->rsound.conn.socket = -1; self->rsound.conn.ctl_socket = -1; self->rsound.channels = ROAR_CHANNELS_DEFAULT; self->rsound.rate = ROAR_RATE_DEFAULT; self->rsound.format = RSD_S16_LE; strncpy(self->rsound.identity, "libroarrsound client", sizeof(self->rsound.identity) - 1); self->rsound.identity[sizeof(self->rsound.identity)-1] = 0; return 0; } /* This is a simpler function that initializes an rsound struct, sets params as given, and starts the stream. Should this function fail, the structure will stay uninitialized. Should NULL be passed in either host, port or ident, defaults will be used. */ int rsd_simple_start (rsound_t **rd, const char* host, const char* port, const char* ident, int rate, int channels, enum rsd_format format) { rsound_t * rsound; if ( rsd_init(rd) == -1 ) return -1; if ( *rd == NULL ) return -1; rsound = *rd; if ( host != NULL ) { if ( rsd_set_param(rsound, RSD_HOST, (void*)host) == -1 ) { rsd_free(rsound); return -1; } } if ( port != NULL ) { if ( rsd_set_param(rsound, RSD_PORT, (void*)port) == -1 ) { rsd_free(rsound); return -1; } } if ( ident != NULL ) { if ( rsd_set_param(rsound, RSD_IDENTITY, (void*)ident) == -1 ) { rsd_free(rsound); return -1; } } if ( rsd_set_param(rsound, RSD_FORMAT, &format) == -1 ) { rsd_free(rsound); return -1; } if ( rsd_set_param(rsound, RSD_CHANNELS, &channels) == -1 ) { rsd_free(rsound); return -1; } if ( rsd_set_param(rsound, RSD_SAMPLERATE, &rate) == -1 ) { rsd_free(rsound); return -1; } if ( rsd_start(rsound) == -1 ) { rsd_free(rsound); return -1; } return 0; } /* Frees an rsound_t struct. */ int rsd_free (rsound_t *rd) { struct libroarrsound * self = (struct libroarrsound *)rd; int ret = 0; if ( self == NULL ) return -1; if ( self->flags & LIBROARRSOUND_FLAGS_CONNECTED ) if ( roar_disconnect(&(self->con)) == -1 ) ret = -1; if ( self->flags & LIBROARRSOUND_FLAGS_STREAMING ) if ( roar_vio_close(&(self->vio)) == -1 ) ret = -1; if ( self->rsound.host != NULL ) roar_mm_free(self->rsound.host); if ( self->rsound.port != NULL ) roar_mm_free(self->rsound.port); roar_mm_free(self); return ret; } int rsd_set_param (rsound_t *rd, enum rsd_settings option, void* param) { struct libroarrsound * self = (struct libroarrsound *)rd; ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = ?", rd, option, param); if ( self == NULL || param == NULL ) return -1; switch (option) { // connection settings: case RSD_HOST: if ( self->rsound.host != NULL ) roar_mm_free(self->rsound.host); self->rsound.host = roar_mm_strdup(param); break; case RSD_PORT: if ( self->rsound.port != NULL ) roar_mm_free(self->rsound.port); self->rsound.port = roar_mm_strdup(param); break; #ifdef RSD_IDENTITY case RSD_IDENTITY: strncpy(self->rsound.identity, param, sizeof(self->rsound.identity) - 1); self->rsound.identity[sizeof(self->rsound.identity)-1] = 0; break; #endif // stream settings: case RSD_SAMPLERATE: self->rsound.rate = *(int*)param; break; case RSD_CHANNELS: self->rsound.channels = *(int*)param; break; case RSD_FORMAT: self->rsound.format = *(int*)param; #ifdef ROAR_HAVE_RSOUND_SAMPLESIZE self->rsound.samplesize = libroarrsound_fmt2fs(self->rsound.format); #else self->rsound.framesize = libroarrsound_fmt2fs(self->rsound.format); #endif break; default: /* RSD_BUFSIZE, RSD_LATENCY, */ ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = -1", rd, option, param); return -1; break; } ROAR_DBG("rsd_set_param(rd=%p, option=%i, param=%p) = 0", rd, option, param); return 0; } static int libroarrsound_connect (struct libroarrsound * self) { const char * host; if ( self->flags & LIBROARRSOUND_FLAGS_CONNECTED ) return 0; host = self->rsound.host; if ( host == NULL ) host = roar_env_get("RSD_SERVER"); // FIXME: we currently ignore the port. :( ROAR_DBG("libroarrsound_connect(self=%p): try to connect to: %s", self, host); if ( roar_simple_connect(&(self->con), host, self->rsound.identity) == -1 ) { ROAR_DBG("libroarrsound_connect(self=%p) = -1 // can not connect to server", self); return -1; } self->flags |= LIBROARRSOUND_FLAGS_CONNECTED; ROAR_DBG("libroarrsound_connect(self=%p) = 0", self); return 0; } /* Establishes connection to server. Might fail if connection can't be established or that one of the mandatory options isn't set in rsd_set_param(). This needs to be called after params have been set with rsd_set_param(), and before rsd_write(). */ int rsd_start (rsound_t *rd) { struct libroarrsound * self = (struct libroarrsound *)rd; int bits = 16; int codec; ROAR_DBG("rsd_start(rd=%p) = ?", rd); if ( self == NULL ) return -1; if ( self->flags & LIBROARRSOUND_FLAGS_STREAMING ) return 0; ROAR_DBG("rsd_start(rd=%p) = ?", rd); if ( !(self->flags & LIBROARRSOUND_FLAGS_CONNECTED) ) { if ( libroarrsound_connect(self) == -1 ) return -1; } ROAR_DBG("rsd_start(rd=%p) = ?", rd); switch (self->rsound.format) { case RSD_S16_LE: case RSD_S32_LE: codec = ROAR_CODEC_PCM_S_LE; break; case RSD_S16_BE: case RSD_S32_BE: codec = ROAR_CODEC_PCM_S_BE; break; case RSD_S16_NE: case RSD_S32_NE: codec = ROAR_CODEC_PCM_S; break; case RSD_U16_LE: case RSD_U32_LE: codec = ROAR_CODEC_PCM_U_LE; break; case RSD_U16_BE: case RSD_U32_BE: codec = ROAR_CODEC_PCM_U_BE; break; case RSD_U16_NE: case RSD_U32_NE: codec = ROAR_CODEC_PCM_U; break; case RSD_S8: codec = ROAR_CODEC_PCM_S; break; case RSD_U8: codec = ROAR_CODEC_PCM_U; break; case RSD_ALAW: codec = ROAR_CODEC_ALAW; break; case RSD_MULAW: codec = ROAR_CODEC_MULAW; break; default: return -1; break; } bits = libroarrsound_fmt2fs(self->rsound.format); ROAR_DBG("rsd_start(rd=%p) = ?", rd); if ( roar_vio_simple_new_stream_obj(&(self->vio), &(self->con), &(self->stream), self->rsound.rate, self->rsound.channels, bits, codec, ROAR_DIR_PLAY, -1) == -1 ) return -1; ROAR_DBG("rsd_start(rd=%p) = ?", rd); self->flags |= LIBROARRSOUND_FLAGS_STREAMING; ROAR_DBG("rsd_start(rd=%p) = 0", rd); return 0; } /* Shuts down the rsound data structures, but returns the file descriptor associated with the connection. The control socket will be shut down. If this function returns a negative number, the exec failed, but the data structures will not be teared down. Should a valid file descriptor be returned, it will always be non-blocking. <<-- FIXME? */ int rsd_exec (rsound_t *rd) { struct libroarrsound * self = (struct libroarrsound *)rd; int fh; ROAR_DBG("rsd_exec(rd=%p) = ?", rd); if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) ) if ( rsd_start(rd) == -1 ) return -1; ROAR_DBG("rsd_exec(rd=%p) = ?", rd); if ( roar_vio_ctl(&(self->vio), ROAR_VIO_CTL_GET_FH, &fh) == -1 ) return -1; ROAR_DBG("rsd_exec(rd=%p) = ?", rd); if ( fh == -1 ) return -1; ROAR_DBG("rsd_exec(rd=%p) = ?", rd); if ( roar_stream_exec(&(self->con), &(self->stream)) == -1 ) return -1; ROAR_DBG("rsd_exec(rd=%p) = ?", rd); // reset flags: if ( self->flags & LIBROARRSOUND_FLAGS_CONNECTED ) self->flags -= LIBROARRSOUND_FLAGS_CONNECTED; if ( self->flags & LIBROARRSOUND_FLAGS_STREAMING ) self->flags -= LIBROARRSOUND_FLAGS_STREAMING; ROAR_DBG("rsd_exec(rd=%p) = ?", rd); // we hope nothing goes wrong here: rsd_free(rd); ROAR_DBG("rsd_exec(rd=%p) = %i", rd, fh); return fh; } /* Disconnects from server. All audio data still in network buffer and other buffers will be dropped. To continue playing, you will need to rsd_start() again. */ int rsd_stop (rsound_t *rd) { struct libroarrsound * self = (struct libroarrsound *)rd; int ret; if ( self == NULL ) return -1; if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) ) return 0; ret = roar_vio_close(&(self->vio)); self->flags -= LIBROARRSOUND_FLAGS_STREAMING; return ret; } /* Writes from buf to the internal buffer. Might fail if no connection is established, or there was an unexpected error. This function will block until all data has been written to the buffer. This function will return the number of bytes written to the buffer, or 0 should it fail (disconnection from server). You will have to restart the stream again should this occur. */ size_t rsd_write (rsound_t *rd, const void * buf, size_t size) { struct libroarrsound * self = (struct libroarrsound *)rd; ssize_t ret; if ( self == NULL ) return -1; if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) ) return 0; ret = roar_vio_write(&(self->vio), (void*)buf, size); if ( ret == -1 ) return 0; return ret; } /* Gets the position of the buffer pointer. Not really interesting for normal applications. Might be useful for implementing rsound on top of other blocking APIs. */ size_t rsd_pointer (rsound_t *rd); /* Aquires how much data can be written to the buffer without blocking */ size_t rsd_get_avail (rsound_t *rd); /* Aquires the latency at the moment for the audio stream. It is measured in bytes. Useful for syncing video and audio. */ size_t rsd_delay (rsound_t *rd) { (void)rd; return 0; // TODO: FIXME: write some code to read pos from server. } /* Utility for returning latency in milliseconds. */ size_t rsd_delay_ms (rsound_t *rd) { if ( rd == NULL ) return -1; if ( rd->rate <= 0 || rd->channels <= 0 ) return -1; #ifdef ROAR_HAVE_RSOUND_SAMPLESIZE return (rsd_delay(rd) * 1000) / (rd->rate * rd->channels * rd->samplesize); #else return (rsd_delay(rd) * 1000) / (rd->rate * rd->channels * rd->framesize); #endif } /* Returns bytes per sample */ int rsd_samplesize( rsound_t *rd ) { if ( rd == NULL ) return -1; #ifdef ROAR_HAVE_RSOUND_SAMPLESIZE return rd->samplesize; #else return rd->framesize; #endif } /* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY Useful for hard headed blocking I/O design where user defined latency is needed. If rsd_set_param hasn't been set with RSD_LATENCY, this function will do nothing. */ void rsd_delay_wait(rsound_t *rd); /* Pauses or unpauses a stream. pause -> enable = 1 This function essentially calls on start() and stop(). This behavior might be changed later. */ int rsd_pause (rsound_t *rd, int enable) { struct libroarrsound * self = (struct libroarrsound *)rd; if ( self == NULL ) return -1; if ( !(self->flags & LIBROARRSOUND_FLAGS_STREAMING) ) return -1; return roar_stream_set_flags(&(self->con), &(self->stream), ROAR_FLAG_PAUSE, enable ? ROAR_SET_FLAG : ROAR_RESET_FLAG); } //ll ����������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarsndio/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�015157� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarsndio/Makefile�����������������������������������������������������������0000644�0001750�0001750�00000001366�12072575524�016625� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf include ../Makefile.inc SLIB=libroarsndio$(SHARED_SUFFIX) TARGETS=$(SLIB) libroarsndio.a OBJS=libroarsndio.o para.o stream.o events.o volume.o midi.o #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroarsndio CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) -L../lib/ $(LDPATH) LIBS = $(LIBROAR) all: ${TARGETS} rm -f ../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all $(SLIB): ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,$(SLIB).$(COMMON_SOVERSION) -o $(SLIB) ${OBJS} ${LIBS} libroarsndio.a: ${OBJS} ${AR} cru libroarsndio.a ${OBJS} ${RANLIB} libroarsndio.a ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarsndio/events.c�����������������������������������������������������������0000644�0001750�0001750�00000006675�12264733610�016640� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//events.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #define ROAR_USE_OWN_SNDIO_HDL #include "libroarsndio.h" #define _CHECK() if ( hdl == NULL ) return 0 int sio_nfds (struct sio_hdl * hdl) { #ifdef ROAR_HAVE_H_POLL int fh = -1; _CHECK(); if ( hdl->stream_opened != 1 ) return 0; if ( roar_vio_ctl(&(hdl->svio), ROAR_VIO_CTL_GET_FH, &fh) == -1 ) return 0; if ( fh == -1 ) return 0; return 1; #else (void)hdl; return 0; #endif } int sio_pollfd (struct sio_hdl * hdl, struct pollfd * pfd, int events) { #ifdef ROAR_HAVE_H_POLL int num; int fh; _CHECK(); if ( (num = sio_nfds(hdl)) == 0 ) return 0; // not supportet currently: if ( num > 1 ) return 0; memset(pfd, 0, num*sizeof(struct pollfd)); // if stream is ok is tested by sio_nfds() if ( roar_vio_ctl(&(hdl->svio), ROAR_VIO_CTL_GET_FH, &fh) == -1 ) return 0; if ( fh == -1 ) return 0; pfd->fd = fh; pfd->events = events; pfd->revents = 0; return num; #else (void)hdl, (void)pfd, (void)events; return 0; #endif } int sio_revents(struct sio_hdl * hdl, struct pollfd * pfd) { #ifdef ROAR_HAVE_H_POLL short revents = 0; int num; int i; _CHECK(); if ( (num = sio_nfds(hdl)) == 0 ) return 0; for (i = 0; i < num; i++) revents |= pfd[i].revents; return revents; #else (void)hdl, (void)pfd; return 0; #endif } //ll �������������������������������������������������������������������roaraudio-1.0beta11/libroarsndio/libroarsndio.c�����������������������������������������������������0000644�0001750�0001750�00000012700�12264733610�020005� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroarsndio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #define ROAR_USE_OWN_SNDIO_HDL #include "libroarsndio.h" static char * sndio_to_roar_names (char * name) { char * unitoffset = NULL; char * optsoffset = NULL; int unit; if ( name == NULL ) return NULL; if ( !strncmp(name, "sun:", 4) ) { unitoffset = name + 4; } else if ( !strncmp(name, "aucat:", 6) ) { unitoffset = name + 6; } else if ( !strncmp(name, "rmidi:", 6) ) { unitoffset = name + 6; } else if ( !strncmp(name, "midithru:", 9) ) { unitoffset = name + 9; } else { return name; } if ( (optsoffset = strstr(unitoffset, "/")) != NULL ) { *optsoffset = 0; return unitoffset; } else if ( (optsoffset = strstr(unitoffset, ".")) != NULL ) { // TODO: add some code to strip the options of the end return name; } else { unit = atoi(unitoffset); switch (unit) { // use defaulst case 0: return NULL; break; // use UNIX user sock, TODO: need some code here... case 1: return NULL; break; // use UNIX global sock: case 2: return ROAR_DEFAULT_SOCK_GLOBAL; break; // use DECnet localnode: case 3: return "::"; break; // use IPv4 localhost: case 4: return ROAR_DEFAULT_INET4_HOST; break; // reserved for DECnet Phase V: case 5: return name; break; // use IPv6 localhost: case 6: return ROAR_DEFAULT_INET6_HOST; break; // default: default: return name; } } return name; } struct sio_hdl * sio_open(const char * name, unsigned mode, int nbio_flag) { struct sio_hdl * hdl = NULL; int is_midi = 0; char * tmp; if ( (hdl = roar_mm_malloc(sizeof(struct sio_hdl))) == NULL ) return NULL; memset(hdl, 0, sizeof(struct sio_hdl)); hdl->device = NULL; switch (mode) { case SIO_PLAY: hdl->dir = ROAR_DIR_PLAY; break; case SIO_REC: hdl->dir = ROAR_DIR_PLAY; break; case MIO_OUT: is_midi = 1; hdl->dir = ROAR_DIR_MIDI_IN; break; case MIO_IN: is_midi = 1; hdl->dir = ROAR_DIR_MIDI_OUT; break; // unsupported: case SIO_PLAY|SIO_REC: case MIO_OUT|MIO_IN: // illigal: default: roar_mm_free(hdl); return NULL; } if ( name == NULL ) { if ( is_midi ) { name = roar_env_get("MIDIDEVICE"); } else { name = roar_env_get("AUDIODEVICE"); } } if ( name != NULL ) { tmp = roar_mm_strdup(name); name = sndio_to_roar_names(tmp); if ( name != NULL ) hdl->device = roar_mm_strdup(name); roar_mm_free(tmp); } if ( roar_simple_connect(&(hdl->con), hdl->device, "libroarsndio") == -1 ) { roar_mm_free(hdl->device); roar_mm_free(hdl); return NULL; } sio_initpar(&(hdl->para)); hdl->stream_opened = 0; if ( is_midi ) { hdl->info.codec = ROAR_CODEC_MIDI; hdl->info.bits = ROAR_MIDI_BITS; hdl->info.channels = ROAR_MIDI_CHANNELS_DEFAULT; hdl->info.rate = ROAR_MIDI_TICKS_PER_BEAT; if ( !sio_start(hdl) ) { sio_close(hdl); return NULL; } } hdl->nonblock = nbio_flag; return hdl; } void sio_close (struct sio_hdl * hdl) { if ( hdl == NULL ) return; sio_stop(hdl); roar_disconnect(&(hdl->con)); if ( hdl->device != NULL ) roar_mm_free(hdl->device); roar_mm_free(hdl); } int sio_eof (struct sio_hdl * hdl) { return hdl->ioerror; } void sio_onmove (struct sio_hdl * hdl, void (*cb)(void * arg, int delta), void * arg) { if ( hdl == NULL ) return; hdl->on_move = cb; hdl->on_move_arg = arg; } //ll ����������������������������������������������������������������roaraudio-1.0beta11/libroarsndio/midi.c�������������������������������������������������������������0000644�0001750�0001750�00000006064�12264733610�016246� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//midi.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #define ROAR_USE_OWN_SNDIO_HDL #include "libroarsndio.h" struct mio_hdl * mio_open (const char * name, unsigned mode, int nbio_flag) { return sio_open(name, mode, nbio_flag); } void mio_close (struct mio_hdl * hdl) { return sio_close(hdl); } size_t mio_write (struct mio_hdl * hdl, const void * addr, size_t nbytes) { return sio_write(hdl, addr, nbytes); } size_t mio_read (struct mio_hdl * hdl, void * addr, size_t nbytes) { return sio_read(hdl, addr, nbytes); } int mio_nfds (struct mio_hdl * hdl) { return mio_nfds(hdl); } int mio_pollfd (struct mio_hdl * hdl, struct pollfd * pfd, int events) { return sio_pollfd(hdl, pfd, events); } int mio_revents(struct mio_hdl * hdl, struct pollfd * pfd) { return sio_revents(hdl, pfd); } int mio_eof (struct mio_hdl * hdl) { return sio_eof(hdl); } //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarsndio/para.c�������������������������������������������������������������0000644�0001750�0001750�00000013353�12264733611�016247� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//para.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #define ROAR_USE_OWN_SNDIO_HDL #include "libroarsndio.h" //#ifndef DEBUG //#define DEBUG //#endif void sio_initpar(struct sio_par * par) { if ( par == NULL ) return; memset(par, 0, sizeof(struct sio_par)); par->bits = ROAR_BITS_DEFAULT; par->sig = 1; par->le = SIO_LE_NATIVE; par->msb = 1; par->rchan = 0; par->pchan = ROAR_CHANNELS_DEFAULT; par->rate = ROAR_RATE_DEFAULT; par->bufsz = ROAR_BITS_DEFAULT * ROAR_CHANNELS_DEFAULT * ROAR_RATE_DEFAULT / 800.0; par->round = 1; par->xrun = SIO_IGNORE; return; } int sio_setpar (struct sio_hdl * hdl, struct sio_par * par) { if ( hdl == NULL || par == NULL ) { ROAR_DBG("sio_setpar(*): Invalid handle or parameter pointer"); return 0; } if ( par->bits == 0 || par->bits > ROAR_BITS_MAX ) { ROAR_DBG("sio_setpar(*): Invalid number of bits: %i Bit", par->bits); return 0; } if ( par->bps == 0 ) par->bps = SIO_BPS(par->bits); if ( par->bps > ROAR_BITS_MAX/8 ) { ROAR_DBG("sio_setpar(*): Invalid number of bytes: %i Byte", par->bps); return 0; } if ( SIO_BPS(par->bits) > par->bps ) { ROAR_DBG("sio_setpar(*): Number of bits/8 > number of bytes: %i/8 > %i", par->bits, par->bps); return 0; } hdl->info.bits = par->bps * 8; switch ((par->sig << 4) | par->le) { case 0x00: hdl->info.codec = ROAR_CODEC_PCM_U_BE; break; case 0x01: hdl->info.codec = ROAR_CODEC_PCM_U_LE; break; case 0x10: hdl->info.codec = ROAR_CODEC_PCM_S_BE; break; case 0x11: hdl->info.codec = ROAR_CODEC_PCM_S_LE; break; default: ROAR_DBG("sio_setpar(*): Invalid codec: sig=%i, le=%i", par->sig, par->le); return 0; } if ( par->msb == 0 ) { ROAR_DBG("sio_setpar(*): LSM alignment not supported"); return 0; } if ( par->rchan != 0 ) { /* not supported yet */ ROAR_DBG("sio_setpar(*): Recording not supported"); return 0; } if ( par->pchan == 0 || par->pchan > ROAR_MAX_CHANNELS ) { ROAR_DBG("sio_setpar(*): Invalid number of playback channels: %i", par->pchan); return 0; } hdl->info.channels = par->pchan; if ( par->rate == 0 ) { ROAR_DBG("sio_setpar(*): Invalid sample rate: %iHz", par->rate); return 0; } hdl->info.rate = par->rate; if ( par->xrun != SIO_IGNORE ) { ROAR_DBG("sio_setpar(*): Unsupported xrun mode: %i", par->xrun); return 0; } memcpy(&(hdl->para), par, sizeof(struct sio_par)); return 1; } int sio_getpar (struct sio_hdl * hdl, struct sio_par * par) { if ( hdl == NULL || par == NULL ) return 0; memcpy(par, &(hdl->para), sizeof(struct sio_par)); return 1; } int sio_getcap (struct sio_hdl * hdl, struct sio_cap * cap) { struct roar_stream s; unsigned int i; unsigned int bytes; unsigned int sign; unsigned int le; unsigned int mask = 0; if ( cap == NULL ) return 0; if ( roar_server_oinfo(&(hdl->con), &s, ROAR_DIR_PLAY) == -1 ) return 0; i = 0; for (bytes = 1; bytes <= s.info.bits/8; bytes++) { for (sign = 0; sign < 2; sign++) { for (le = 0; le < 2; le++) { cap->enc[i].bits = 8*bytes; cap->enc[i].bps = bytes; cap->enc[i].sig = sign; cap->enc[i].le = le; cap->enc[i].msb = 1; mask |= 1 << i; i++; } } } // TODO: fix this (at least include server channels, // do nit include confusing setups) if ( s.info.channels > SIO_NCHAN ) { s.info.channels = SIO_NCHAN; } for (i = 0; i < s.info.channels; i++) { cap->rchan[i] = i+1; cap->pchan[i] = i+1; } cap->rate[0] = s.info.rate; cap->nconf = 1; cap->confs[0].enc = mask; cap->confs[0].rchan = mask; cap->confs[0].pchan = mask; cap->confs[0].rate = 0x0001; return 1; } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroarsndio/stream.c�����������������������������������������������������������0000644�0001750�0001750�00000011717�12264733611�016621� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stream.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #define ROAR_USE_OWN_SNDIO_HDL #include "libroarsndio.h" // this is void because we do not care about if this failed... static void send_vol_event (struct sio_hdl * hdl) { int channels; struct roar_mixer_settings mixer; int i; unsigned vol; // in case of no event handler we do not send the event at all ;) if ( hdl->on_vol == NULL ) return; if ( roar_get_vol(&(hdl->con), roar_stream_get_id(&(hdl->stream)), &mixer, &channels) == -1 ) return; ROAR_DBG("send_vol_event(*): channels=%i", channels); switch (channels) { case 1: ROAR_DBG("send_vol_event(*): mixer.scale=%i, mixer.mixer={%i,...}", mixer.scale, mixer.mixer[0]); vol = mixer.mixer[0] * SIO_MAXVOL; vol /= mixer.scale; ROAR_DBG("send_vol_event(*): vol=%u", vol); break; case 2: vol = (mixer.mixer[0] + mixer.mixer[1]) * SIO_MAXVOL / mixer.scale / 2; break; default: vol = 0; for (i = 0; i < channels; i++) vol += mixer.mixer[i]; vol /= channels; vol *= SIO_MAXVOL; vol /= mixer.scale; break; } ROAR_DBG("send_vol_event(*): vol=%u", vol); hdl->on_vol(hdl->on_vol_arg, vol); } #define _i(x) (hdl->info.x) int sio_start (struct sio_hdl * hdl) { // TODO: FIXME: use full VIO support here, not fh->vio! if ( hdl == NULL ) return 0; if ( hdl->stream_opened ) return 0; if ( roar_vio_simple_new_stream_obj(&(hdl->svio), &(hdl->con), &(hdl->stream), _i(rate), _i(channels), _i(bits), _i(codec), hdl->dir, -1) == -1 ) return 0; ROAR_DBG("sio_start(hdl=%p): rate=%i, channels=%i, bits=%i, codec=%i", hdl, _i(rate), _i(channels), _i(bits), _i(codec)); if ( hdl->nonblock ) { if ( roar_vio_nonblock(&(hdl->svio), ROAR_SOCKET_NONBLOCK) == -1 ) { roar_vio_close(&(hdl->svio)); return 0; } } send_vol_event(hdl); hdl->stream_opened = 1; hdl->ioerror = 0; return 1; } #undef _i int sio_stop (struct sio_hdl * hdl) { if ( hdl == NULL ) return 0; if ( !hdl->stream_opened ) return 0; roar_vio_close(&(hdl->svio)); hdl->stream_opened = -1; return 1; } size_t sio_read (struct sio_hdl * hdl, void * addr, size_t nbytes) { ssize_t ret; if ( hdl == NULL ) return 0; if ( !hdl->stream_opened ) return 0; if ( (ret = roar_vio_read(&(hdl->svio), addr, nbytes)) < 0 ) { hdl->ioerror = 1; return 0; } if ( hdl->nonblock ) hdl->ioerror = 0; return ret; } size_t sio_write (struct sio_hdl * hdl, const void * addr, size_t nbytes) { ssize_t ret; if ( hdl == NULL ) return 0; if ( !hdl->stream_opened ) return 0; if ( (ret = roar_vio_write(&(hdl->svio), (void*) addr, nbytes)) < 0 ) { hdl->ioerror = 1; return 0; } if ( hdl->nonblock ) hdl->ioerror = 0; if ( hdl->on_move != NULL ) { hdl->on_move(hdl->on_move_arg, 8*ret/(hdl->info.channels * hdl->info.bits)); } return ret; } //ll �������������������������������������������������roaraudio-1.0beta11/libroarsndio/volume.c�����������������������������������������������������������0000644�0001750�0001750�00000006076�12264733612�016640� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//volume.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * The code (may) include prototypes and comments (and maybe * other code fragements) from OpenBSD's sndio. * See 'Copyright for sndio' below for more information on * code fragments taken from OpenBSD's sndio. * * --- Copyright for sndio --- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * --- End of Copyright for sndio --- * * This file is part of libroaresd a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. */ #define ROAR_USE_OWN_SNDIO_HDL #include "libroarsndio.h" int sio_setvol (struct sio_hdl * hdl, unsigned vol) { struct roar_mixer_settings mixer; unsigned int i; if ( hdl == NULL ) return 0; if ( vol > SIO_MAXVOL ) return 0; mixer.scale = SIO_MAXVOL; mixer.rpg_mul = 1; mixer.rpg_div = 1; mixer.mixer[0] = vol; if ( roar_set_vol(&(hdl->con), roar_stream_get_id(&(hdl->stream)), &mixer, 0, ROAR_SET_VOL_UNMAPPED) == -1 ) return 0; for (i = 0; i < hdl->info.channels; i++) mixer.mixer[i] = vol; if ( roar_set_vol(&(hdl->con), roar_stream_get_id(&(hdl->stream)), &mixer, hdl->info.channels, ROAR_SET_VOL_ALL) == -1 ) return 0; if ( hdl->on_vol != NULL ) hdl->on_vol(hdl->on_vol_arg, vol); return 1; } void sio_onvol (struct sio_hdl * hdl, void (*cb)(void * arg, unsigned vol), void * arg) { if ( hdl == NULL ) return; hdl->on_vol = cb; hdl->on_vol_arg = arg; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�015000� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/Makefile������������������������������������������������������������0000644�0001750�0001750�00000001231�12072575524�016435� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������TARGETS=libroaryiff.so OBJS=libroaryiff.o connection.o playback.o audiocd.o ctl.o stub.o file.o events.o include ../Makefile.conf include ../Makefile.inc #DEFINES = -DDEBUG INCLUDE = -I../include -I../include/libroaryiff CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(Wextra) $(SHARED) $(LDPATH) -L../lib/ LIBS = $(LIBROAR) all: ${TARGETS} cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all libroaryiff.so: ${OBJS} ${CC} ${LDFLAGS} -Wl,-soname,libroaryiff$(SHARED_SUFFIX).$(COMMON_SOVERSION) -o libroaryiff$(SHARED_SUFFIX) ${OBJS} ${LIBS} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/audiocd.c�����������������������������������������������������������0000644�0001750�0001750�00000004526�12264733612�016560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//audiocd.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> struct { int is_open; int is_playing; struct roar_cdrom cdrom[1]; } _g_roaryiff_cdrom = {0, 0, {}}; int YEjectAudioCD(YConnection *con) { YStopAudioCD(con); return system("eject") == 0 ? 0 : -1; } int YPlayAudioCDTrack(YConnection *con, int track_number) { struct roar_connection rcon; if ( con == NULL ) return -1; roar_connect_fh(&rcon, con->fd); if ( ! _g_roaryiff_cdrom.is_open ) { if ( roar_cdrom_open(&rcon, _g_roaryiff_cdrom.cdrom, NULL, -1) == -1 ) return -1; } return roar_cdrom_play(_g_roaryiff_cdrom.cdrom, track_number); } int YStopAudioCD(YConnection *con) { struct roar_connection rcon; if ( con == NULL ) return -1; roar_connect_fh(&rcon, con->fd); if ( _g_roaryiff_cdrom.is_playing ) { roar_cdrom_stop(_g_roaryiff_cdrom.cdrom); _g_roaryiff_cdrom.is_playing = 0; } if ( _g_roaryiff_cdrom.is_open ) { roar_cdrom_close(_g_roaryiff_cdrom.cdrom); _g_roaryiff_cdrom.is_open = 0; } return 0; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/connection.c��������������������������������������������������������0000644�0001750�0001750�00000006027�12264733612�017305� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//connection.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> YConnection *YOpenConnection (const char *start_arg, const char *con_arg) { YConnection * ycon = roar_mm_malloc(sizeof(YConnection)); struct roar_connection con; const char * server = (char *)con_arg; const char * name = "libroaryiff client"; memset(ycon, 0, sizeof(YConnection)); // there is no symbolic value for default con_arg // in the heder files. So we use a hard coded value from the docs if ( server != NULL ) { if ( strcmp(server, "127.0.0.1:9433") == 0 || strcmp(server, "127.0.0.1") == 0 || // \\ // strcmp(server, "localhost") == 0 || // => Don't know if this is valid for libY // strcmp(server, "localhost:9433") == 0 ) { // // but we support it. // server = NULL; // try default locations } } if (roar_simple_connect(&con, server, name) == -1) { // Handle start_arg here! roar_mm_free(ycon); return NULL; } if ( (ycon->fd = roar_get_connection_fh(&con)) == -1 ) { roar_disconnect(&con); roar_mm_free(ycon); return NULL; } return ycon; } void YCloseConnection (YConnection *connection, Boolean no_shutdown) { struct roar_vio_calls vio; // in case we started the server by using +fork we can not keep it running // as it will terminate anyway. If there are any other clients (I guess // this is what this option is about) it will keep running. (void)no_shutdown; if ( connection == NULL ) return; // roard will clean up all other sockets if the close the main one. if ( roar_vio_open_fh_socket(&vio, connection->fd) != -1 ) { roar_vio_close(&vio); } roar_mm_free(connection); } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/ctl.c���������������������������������������������������������������0000644�0001750�0001750�00000003153�12264733612�015725� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ctl.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> void YShutdownServer(YConnection *con) { struct roar_connection rcon; if ( !con ) return; roar_connect_fh(&rcon, con->fd); _LIBROAR_IGNORE_RET(roar_terminate(&rcon, 0)); YCloseConnection(con, 1); } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/events.c������������������������������������������������������������0000644�0001750�0001750�00000004333�12264733613�016451� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//events.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> // RoarAudio isn't event based, so we need to trick a lot here // Maybe this can be overcome with the notify API int YGetNextEvent (YConnection *con, YEvent *event, Boolean block) { struct roar_connection rcon; struct roar_stream s; (void)block; if ( con == NULL || event == NULL ) return -1; roar_connect_fh(&rcon, con->fd); if ( con->prev_generated_yid != YIDNULL ) { if ( roar_get_stream(&rcon, &s, ROARYIFF_YID2ROAR(con->prev_generated_yid)) == -1 ) { // ok, we know something happened. if ( roar_error == ROAR_ERROR_PROTO ) { // the server died event->type = YDisconnect; return 1; } else { // the stream died event->type = YSoundObjectKill; event->kill.yid = con->prev_generated_yid; return 1; } } // else { nothing interesting happened } } return 0; } //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/file.c��������������������������������������������������������������0000644�0001750�0001750�00000003767�12264733613�016076� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//file.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> int YGetSoundObjectAttributes (YConnection *con, const char *path, YEventSoundObjectAttributes *buf) { (void)con; if ( buf == NULL ) return -1; buf->format = SndObjTypeDSP; // RoarAudio doesn't make a hard diffrence here // TODO: maybe we should check for the codec // as we do not know anything we fill with defaults: buf->sample_size = ROAR_BITS_DEFAULT; // don't know, but seems to be in bits not bytes buf->channels = ROAR_CHANNELS_DEFAULT; buf->sample_rate = ROAR_RATE_DEFAULT; buf->length = 0; strncpy(buf->path, path, YPathMax); return 0; } //ll ���������roaraudio-1.0beta11/libroaryiff/libroaryiff.c�������������������������������������������������������0000644�0001750�0001750�00000002642�12264733613�017456� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//libroaryiff.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> //ll ����������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/playback.c����������������������������������������������������������0000644�0001750�0001750�00000010027�12264733614�016731� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//playback.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> #define BUFFERSIZE 8192 #ifdef ROAR_HAVE_IO_POSIX #define _CAN_OPERATE #endif YID YStartPlaySoundObjectSimple (YConnection *con, const char *path) { return YStartPlaySoundObject(con, path, NULL); } static inline ssize_t _file_play (struct roar_connection * con, const char * file, struct roar_stream * s) { #ifdef _CAN_OPERATE int codec = -1; int in, out = -1; ssize_t r = 0; int seek; int len; char buf[BUFFERSIZE]; int rate = ROAR_RATE_DEFAULT, channels = ROAR_CHANNELS_DEFAULT, bits = ROAR_BITS_DEFAULT; // FIXME: check error cases ROAR_DBG("roar_file_play_full(*) = ?"); #ifdef ROAR_TARGET_WIN32 if ( (in = open(file, O_RDONLY|O_BINARY, 0644)) == -1 ) { #else if ( (in = open(file, O_RDONLY, 0644)) == -1 ) { #endif roar_err_from_errno(); return -1; } if ((len = read(in, buf, BUFFERSIZE)) < 1) { roar_err_from_errno(); close(in); return -1; } codec = roar_file_codecdetect(buf, len); ROAR_DBG("roar_file_play_full(*): codec=%i(%s)", codec, roar_codec2str(codec)); seek = lseek(in, 0, SEEK_SET) == (off_t) -1 ? 0 : 1; if ( codec == -1 ) { ROAR_WARN("roar_file_play_full(*): Unknown codec of file: %s", file); close(in); roar_err_set(ROAR_ERROR_BADMAGIC); return -1; } if ( !seek ) { ROAR_WARN("roar_file_play_full(*): passfh on non seekable file: this may produce incorrect playback"); close(in); roar_err_set(ROAR_ERROR_NOSEEK); return -1; } if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) { close(in); return -1; } if ( roar_stream_connect(con, s, ROAR_DIR_PLAY, -1) == -1 ) { close(in); return -1; } if ( roar_stream_passfh(con, s, in) == -1 ) { close(in); roar_kick(con, ROAR_OT_STREAM, roar_stream_get_id(s)); return -1; } close(out); close(in); return 0; return r; #else roar_err_set(ROAR_ERROR_NOSYS); return -1; #endif } YID YStartPlaySoundObject (YConnection *con, const char *path, YEventSoundPlay *value) { struct roar_connection rcon; struct roar_stream stream[1]; if ( con == NULL ) return YIDNULL; if ( path == NULL ) return YIDNULL; roar_connect_fh(&rcon, con->fd); // hm,... find out how to do this. // need to start ssize_t roar_file_play (struct roar_connection * con, char * file, int exec) // in background if ( _file_play(&rcon, path, stream) == -1 ) { ROAR_ERR("Can not start playback"); return YIDNULL; } return con->prev_generated_yid = ROARYIFF_ROAR2YID(stream->id); } void YDestroyPlaySoundObject(YConnection *con, YID yid) { struct roar_connection rcon; if ( !con ) return ; if ( yid == YIDNULL ) return; roar_connect_fh(&rcon, con->fd); roar_kick(&rcon, ROAR_OT_STREAM, ROARYIFF_YID2ROAR(yid)); } //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/libroaryiff/stub.c��������������������������������������������������������������0000644�0001750�0001750�00000003032�12264733614�016116� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//stub.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * The code (may) include prototypes and comments (and maybe * other code fragements) from the yiff sound system. * According to the debian/copyright file upstream author is * Tara Milana <learfox@twu.net>. Also copyright is listed as: * Copyright (C) 1997-2003 WolfPack Entertainment * * This file is part of libroaryiff a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroaryiff is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE: code fragments (like prototypes) taken from the yiff package * are 'GPLv2 or later' and are upgraded to GPLv3 by being used * within this document. * */ #include <libroaryiff.h> // in here only some stub functions are delcared void YSyncAll(YConnection *con, Boolean block) { (void)con, (void)block; } //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553244�014152� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553176�015076� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/Makefile�����������������������������������������������������������0000644�0001750�0001750�00000002500�12072575524�016526� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BASENAME=libasound_module_pcm_roar SLIB=$(BASENAME)$(SHARED_SUFFIX) TARGET=$(SLIB) INSTALL_DIR=$(PREFIX_LIB)/alsa-lib/ OBJS=pcm_roar.o roar.o thread.o include ../../Makefile.conf include ../../Makefile.inc #include Makefile.conf #DEBUG=-DDEBUG -DXXX DEFINES=-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"alsa-plugins\" -DVERSION=\"1.0.13\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DSTDC_HEADERS=1 -DHAVE_LIBASOUND=1 -D_REENTRANT -DPIC CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) -I../../include $(DEFINES) $(DEBUG) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) -I/usr/include/alsa -D_GNU_SOURCE $(pthread) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) $(LDPATH) -L../../lib $(pthread) LIBS = $(LIBROAR) $(lib_m) $(lib_dl) -lrt $(lib_asound) all: ${TARGET} clean: rm -f ${TARGET} *.o tests tests.c new: clean all install: ${TARGET} mkdir -p ${DESTDIR}${INSTALL_DIR} cp ${TARGET} ${DESTDIR}${INSTALL_DIR} semi-install: ${TARGET} mkdir -p ${DESTDIR}${INSTALL_DIR} ln -fs `pwd`/$(SLIB) ${DESTDIR}${INSTALL_DIR} $(SLIB): $(OBJS) $(CC) $(LDFLAGS) -Wl,-soname -Wl,$(SLIB) -o $(SLIB) $(OBJS) $(LIBS) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/mixer.c������������������������������������������������������������0000644�0001750�0001750�00000002213�12264733616�016360� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//mixer.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * */ #include "roar.h" //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/pcm.c��������������������������������������������������������������0000644�0001750�0001750�00000027670�12264733617�016032� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//pcm.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * */ #include "roar.h" // Equvivalent to prepare(). Starts a stream. Also needs to reset the writec since pointer() will do funny // things without it. Will be called several times during a program! static int roar_pcm_start (snd_pcm_ioplug_t * io) { struct roar_alsa_pcm * self = io->private_data; int fh; ROAR_DBG("roar_pcm_start(*) = ?"); // If start is called several times in a row, just ignore it. if (self->stream_opened) return 0; if ( roar_vio_simple_new_stream_obj(&(self->stream_vio), &(self->roar.con), &(self->stream), self->info.rate, self->info.channels, self->info.bits, self->info.codec, io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR ) == -1 ) { return -EINVAL; } if ( roar_vio_ctl(&(self->stream_vio), io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_VIO_CTL_GET_SELECT_WRITE_FH : ROAR_VIO_CTL_GET_SELECT_READ_FH, &fh) != -1 ) { io->poll_fd = fh; io->poll_events = io->stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN; snd_pcm_ioplug_reinit_status(io); } // Stream is now active, yay. self->stream_opened = 1; self->writec = 0; return 0; } // Simply stopping the stream. Will need to be restarted to play more. // Will be called several times together with roar_pcm_start() static int roar_pcm_stop (snd_pcm_ioplug_t *io) { struct roar_alsa_pcm * self = io->private_data; ROAR_DBG("roar_pcm_stop(*) = ?"); // If this is called several times in a row, just ignore. if ( !self->stream_opened ) return 0; roar_vio_close(&(self->stream_vio)); self->stream_opened = 0; ROAR_DBG("roar_pcm_stop(*) = 0"); return 0; } static int roar_hw_constraint(struct roar_alsa_pcm * self) { snd_pcm_ioplug_t *io = &(self->io); static const snd_pcm_access_t access_list[] = { SND_PCM_ACCESS_RW_INTERLEAVED }; static const unsigned int formats[] = { SND_PCM_FORMAT_S8, SND_PCM_FORMAT_U8, SND_PCM_FORMAT_A_LAW, SND_PCM_FORMAT_MU_LAW, SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_U16_LE, SND_PCM_FORMAT_U16_BE, SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_BE, SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_U32_BE, SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3BE, SND_PCM_FORMAT_U24_3LE, SND_PCM_FORMAT_U24_3BE, }; int ret; ROAR_DBG("roar_hw_constraint(*) = ?"); if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, _as(access_list), access_list)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT, _as(formats), formats)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, 1, ROAR_MAX_CHANNELS)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 192000)) < 0 ) return ret; #if 0 if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1, 4294967295U)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 4294967295U)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1, 4294967295U)) < 0 ) return ret; #else // We shouldn't let ALSA use extremely low or high values, it will kill a kitty most likely. :v if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1 << 6, 1 << 18)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 1024)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1 << 13, 1 << 24)) < 0 ) return ret; #endif ROAR_DBG("roar_hw_constraint(*) = 0"); return 0; } /////////////////////////////// /// TODO: Needs to be implemented /////////////////////////////// // This hacky hack should not be used, since apparently, using this, ALSA will think the audio buffer is always empty (?), // leading to completely broken blocking audio which will only work with audio players. // Will need a method to determine how much buffer data is available to write to the roar buffer without blocking. // We therefore also need to know the buffersize that ALSA uses. // Referring to alsa-lib/src/pcm/pcm_ioplug.c : snd_pcm_ioplug_hw_ptr_update static snd_pcm_sframes_t roar_pcm_pointer(snd_pcm_ioplug_t *io) { struct roar_alsa_pcm * self = io->private_data; ROAR_DBG("roar_pcm_pointer(*) = ?"); return snd_pcm_bytes_to_frames(io->pcm, self->writec); } // TODO: FIXME: add support for reading data! static snd_pcm_sframes_t roar_pcm_transfer(snd_pcm_ioplug_t *io, const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) { struct roar_alsa_pcm * self = io->private_data; char * buf; size_t len = size * self->info.channels * self->info.bits / 8; ssize_t ret; ROAR_DBG("roar_pcm_transfer(*) = ?"); ROAR_DBG("roar_pcm_transfer(*): len=%lu", (long unsigned int) len); // Weird ALSA stuff. buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8; ret = roar_vio_write(&(self->stream_vio), buf, len); if ( ret != -1 ) { // We increment the written counter so that subsequent calls to pointer() will not cause // the library to hang due to several quirks that ALSA uses to determine available size. // This approach is bad, but is needed until pointer() is implemented correctly. self->writec += ret; } else { return -EIO; } ROAR_DBG("roar_pcm_transfer(*) = %lli", (long long int)size); return size; } /////////////////////////////// /// TODO: Needs to be implemented /////////////////////////////// static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) { (void)io; ROAR_DBG("roar_pcm_delay(*) = ?"); // TODO: We need to set *delayp the latency in frames. *delayp = 0; return 0; } static int roar_pcm_prepare(snd_pcm_ioplug_t *io) { ROAR_DBG("roar_pcm_prepare(*) = ?"); return roar_pcm_start(io); } static int roar_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) { struct roar_alsa_pcm * self = io->private_data; (void) params; ROAR_DBG("roar_pcm_hw_params(*) = ?"); self->info.channels = io->channels; self->info.rate = io->rate; switch (io->format) { case SND_PCM_FORMAT_S8: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 8; break; case SND_PCM_FORMAT_U8: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 8; break; case SND_PCM_FORMAT_A_LAW: self->info.codec = ROAR_CODEC_ALAW; self->info.bits = 8; break; case SND_PCM_FORMAT_MU_LAW: self->info.codec = ROAR_CODEC_MULAW; self->info.bits = 8; break; case SND_PCM_FORMAT_S16_LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 16; break; case SND_PCM_FORMAT_S16_BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 16; break; case SND_PCM_FORMAT_U16_LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 16; break; case SND_PCM_FORMAT_U16_BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 16; break; case SND_PCM_FORMAT_S32_LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 32; break; case SND_PCM_FORMAT_S32_BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 32; break; case SND_PCM_FORMAT_U32_LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 32; break; case SND_PCM_FORMAT_U32_BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 32; break; case SND_PCM_FORMAT_S24_3LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 24; break; case SND_PCM_FORMAT_S24_3BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 24; break; case SND_PCM_FORMAT_U24_3LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 24; break; case SND_PCM_FORMAT_U24_3BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 24; break; default: return-EINVAL; } ROAR_DBG("roar_pcm_hw_params(*) = 0"); return 0; } static int roar_pcm_close (snd_pcm_ioplug_t * io) { struct roar_alsa_pcm * self = io->private_data; ROAR_DBG("roar_pcm_close(*) = ?"); roar_disconnect(&(self->roar.con)); roar_mm_free(self); return 0; } static snd_pcm_ioplug_callback_t roar_pcm_callback = { .start = roar_pcm_start, .stop = roar_pcm_stop, .drain = NULL, .pointer = roar_pcm_pointer, .transfer = roar_pcm_transfer, .delay = roar_pcm_delay, .poll_descriptors_count = NULL, .poll_descriptors = NULL, .poll_revents = NULL, .prepare = roar_pcm_prepare, .hw_params = roar_pcm_hw_params, .hw_free = NULL, .sw_params = NULL, .pause = NULL, .resume = NULL, .dump = NULL, .close = roar_pcm_close, }; SND_PCM_PLUGIN_DEFINE_FUNC(roar) { struct roar_alsa_pcm * self; snd_config_iterator_t i, next; snd_config_t * n; const char * para; const char * server = NULL; int ret; (void)root; ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = ?"); snd_config_for_each(i, next, conf) { n = snd_config_iterator_entry(i); if ( snd_config_get_id(n, ¶) < 0 ) continue; if ( !strcmp(para, "type") || !strcmp(para, "comment") ) continue; if ( !strcmp(para, "server") ) { if (snd_config_get_string(n, &server) < 0) { return -EINVAL; } } else { return -EINVAL; } } errno = ENOSYS; if ( (self = roar_mm_malloc(sizeof(struct roar_alsa_pcm))) == NULL ) return -errno; memset(self, 0, sizeof(struct roar_alsa_pcm)); errno = ENOSYS; if ( roar_simple_connect(&(self->roar.con), (char*)server, "ALSA Plugin") == -1 ) { roar_mm_free(self); return -errno; } self->io.version = SND_PCM_IOPLUG_VERSION; self->io.name = "RoarAudio Plugin"; self->io.poll_fd = -1; self->io.poll_events = 0; self->io.mmap_rw = 0; self->io.callback = &roar_pcm_callback; self->io.private_data = self; if ( (ret = snd_pcm_ioplug_create(&(self->io), name, stream, mode)) < 0 ) { roar_disconnect(&(self->roar.con)); roar_mm_free(self); return ret; } if ( (ret = roar_hw_constraint(self)) < 0 ) { snd_pcm_ioplug_delete(&(self->io)); roar_disconnect(&(self->roar.con)); roar_mm_free(self); return ret; } *pcmp = self->io.pcm; ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = 0"); return 0; } SND_PCM_PLUGIN_SYMBOL(roar); int __snd_pcm_roar_open_dlsym_pcm_001 (void) { ROAR_DBG("__snd_pcm_roar_open_dlsym_pcm_001(void) = 0"); return 0; } //ll ������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/pcm_roar.c���������������������������������������������������������0000644�0001750�0001750�00000036602�12264733617�017050� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//pcm_roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ //#define DEBUG #include "roar.h" // Equvivalent to prepare(). Starts a stream. Might/will be called several times during a program! ///////////////////////////////////////////////// // Status: Should be mostly complete. // Condition for invalid fh is not solved here. //////////////////////////////////////////////// static int roar_pcm_start (snd_pcm_ioplug_t * io) { struct roar_alsa_pcm * self = io->private_data; int fh; #if 0 #if defined(SOL_SOCKET) && defined(SO_SNDBUF) struct roar_vio_sysio_sockopt sockopt; int val; #endif #endif ROAR_DBG("roar_pcm_start(*) = ?"); // If start is called several times in a row, just ignore it. if (self->stream_opened) return 0; if ( roar_vio_simple_new_stream_obj(&(self->stream_vio), &(self->roar.con), &(self->stream), self->info.rate, self->info.channels, self->info.bits, self->info.codec, io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR ) == -1 ) { return -EINVAL; } if ( self->stream_role != ROAR_ROLE_UNKNOWN ) { if ( roar_stream_set_role(&(self->roar.con), &(self->stream), self->stream_role) == -1 ) { ROAR_WARN("roar_pcm_start(*): Can not set stream role: %i: %s", self->stream_role, roar_error2str(roar_error)); } } if ( roar_vio_ctl(&(self->stream_vio), io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_VIO_CTL_GET_SELECT_WRITE_FH : ROAR_VIO_CTL_GET_SELECT_READ_FH, &fh) != 1 ) { io->poll_fd = fh; io->poll_events = io->stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN; #if 0 #if defined(SOL_SOCKET) && defined(SO_SNDBUF) val = self->bufsize > 4096 ? 4096 : self->bufsize; sockopt.level = SOL_SOCKET; sockopt.optname = SO_SNDBUF; sockopt.optval = &val; sockopt.optlen = sizeof(val); roar_vio_ctl(&(self->stream_vio), ROAR_VIO_CTL_GET_SYSIO_SOCKOPT, &sockopt); #endif #endif } // Oh, no, what should we do here if roar_vio_ctl() fails to grab a valid fh to poll? // In any case, ALSA will error out the next time it tries to poll() if we don't give it a valid fh. snd_pcm_ioplug_reinit_status(io); // Stream is now active, yay. self->stream_opened = 1; self->bufptr = 0; self->thread_active = 1; // We have to activate the thread before starting it, because the thread lives on that thread_active is 1. if ( pthread_create(&(self->thread), NULL, roar_plugin_thread, self) < 0 ) { self->thread_active = 0; return -1; } return 0; } void roar_plugin_reset(struct roar_alsa_pcm *self) { if ( !self->stream_opened ) return; roar_vio_close(&(self->stream_vio)); self->stream_opened = 0; self->thread_active = 0; self->bufptr = 0; self->last_ptr = 0; self->total_written = 0; self->has_written = 0; } // Simply stopping the stream. Will need to be restarted to play more. // Will be called several times together with roar_pcm_start() /////////////////////////////////////////////////// // Status: Still needs some error checking for the pthread calls, but // should work. ////////////////////////////////////////////////// static int roar_pcm_stop (snd_pcm_ioplug_t *io) { struct roar_alsa_pcm * self = io->private_data; // If this is called several times in a row, just ignore. ROAR_DBG("roar_pcm_stop(*) = 0"); if ( self->thread_active ) { self->thread_active = 0; pthread_cond_signal(&(self->cond)); pthread_join(self->thread, NULL); } roar_plugin_reset(self); return 0; } /////////////////////////////// // Status: Should be complete. /////////////////////////////// static int roar_hw_constraint(struct roar_alsa_pcm * self) { snd_pcm_ioplug_t *io = &(self->io); static const snd_pcm_access_t access_list[] = { SND_PCM_ACCESS_RW_INTERLEAVED }; static const unsigned int formats[] = { SND_PCM_FORMAT_S8, SND_PCM_FORMAT_U8, SND_PCM_FORMAT_A_LAW, SND_PCM_FORMAT_MU_LAW, SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_U16_LE, SND_PCM_FORMAT_U16_BE, SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_BE, SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_U32_BE, SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3BE, SND_PCM_FORMAT_U24_3LE, SND_PCM_FORMAT_U24_3BE, }; int ret; ROAR_DBG("roar_hw_constraint(*) = ?"); if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, _as(access_list), access_list)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT, _as(formats), formats)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, 1, ROAR_MAX_CHANNELS)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 192000)) < 0 ) return ret; // We shouldn't let ALSA use extremely low or high values, it will kill a kitty most likely. :v if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1 << 6, 1 << 18)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 1024)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1 << 13, 1 << 24)) < 0 ) return ret; ROAR_DBG("roar_hw_constraint(*) = 0"); return 0; } // Referring to alsa-lib/src/pcm/pcm_ioplug.c : snd_pcm_ioplug_hw_ptr_update /////////////////////////////////////////////////////////// // Status: Mostly complete, but uses a really nasty hack! /////////////////////////////////////////////////////////// static snd_pcm_sframes_t roar_pcm_pointer(snd_pcm_ioplug_t *io) { struct roar_alsa_pcm * self = io->private_data; int ptr; ROAR_DBG("roar_pcm_pointer(*) = ?"); // Did ALSA just call snd_pcm_reset() or something like that without calling the plugin? // We should restart our stream as well. if ( io->appl_ptr < self->last_ptr ) { roar_pcm_stop(io); roar_pcm_start(io); } // ALSA has a weird way of calculating how much data can be written to the audio buffer. // It uses the formula: // avail = bufsize + ptr - io->appl_ptr; (??!?) // We really want this: // avail = bufsize - ptr; // This is the obvious way, so we have to manipulate ptr like this: // ptr = io->appl_ptr - ptr; pthread_mutex_lock(&(self->lock)); ptr = snd_pcm_bytes_to_frames(io->pcm, self->bufptr); pthread_mutex_unlock(&(self->lock)); ptr = io->appl_ptr - ptr; self->last_ptr = io->appl_ptr; ROAR_DBG("roar_pcm_pointer(*) appl_ptr: %i, ptr: %i, calculated avail frames: %i", (int)io->appl_ptr, (int)ptr, (int)(io->appl_ptr - ptr)); ROAR_DBG("roar_pcm_pointer(*) = %i", ptr); return ptr; } // TODO: FIXME: add support for reading data! ////////////////////////////////////////////////// // Status: For writing, this should be complete. ////////////////////////////////////////////////// static snd_pcm_sframes_t roar_pcm_transfer(snd_pcm_ioplug_t *io, const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) { struct roar_alsa_pcm * self = io->private_data; char * buf; size_t len = size * self->info.channels * self->info.bits / 8; ssize_t ret; ROAR_DBG("roar_pcm_transfer(*) = ?"); ROAR_DBG("roar_pcm_transfer(*): len=%lu", (long unsigned int) len); // Weird ALSA stuff. buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8; ret = roar_plugin_write(self, buf, len); if ( ret == -1 ) return -EIO; ROAR_DBG("roar_pcm_transfer(*) = %lli", (long long int)size); return size; } /////////////////////////////////////////////////////////////////// // Status: Still missing proper delay measurements from the roar server. // Only uses a blind timer now. In ideal conditions, this will work well. /////////////////////////////////////////////////////////////////// static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) { struct roar_alsa_pcm * self = io->private_data; ROAR_DBG("roar_pcm_delay(*) = ?"); // TODO: We need to set *delayp the latency in frames. pthread_mutex_lock(&(self->lock)); roar_plugin_drain(self); *delayp = snd_pcm_bytes_to_frames(io->pcm, self->bytes_in_buffer); pthread_mutex_unlock(&(self->lock)); return 0; } //////////////////// // Status: Complete //////////////////// static int roar_pcm_prepare(snd_pcm_ioplug_t *io) { ROAR_DBG("roar_pcm_prepare(*) = ?"); return roar_pcm_start(io); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Status: This should be mostly complete. // I'm not sure if hw_params can be called several times during one stream without stop() start() in between. // This will mean a memory leak, and possibly breakage should the buffer size change itself. /////////////////////////////////////////////////////////////////////////////////////////////////////////////// static int roar_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) { struct roar_alsa_pcm * self = io->private_data; snd_pcm_uframes_t buffersize; int err; ROAR_DBG("roar_pcm_hw_params(*) = ?"); self->info.channels = io->channels; self->info.rate = io->rate; switch (io->format) { case SND_PCM_FORMAT_S8: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 8; break; case SND_PCM_FORMAT_U8: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 8; break; case SND_PCM_FORMAT_A_LAW: self->info.codec = ROAR_CODEC_ALAW; self->info.bits = 8; break; case SND_PCM_FORMAT_MU_LAW: self->info.codec = ROAR_CODEC_MULAW; self->info.bits = 8; break; case SND_PCM_FORMAT_S16_LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 16; break; case SND_PCM_FORMAT_S16_BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 16; break; case SND_PCM_FORMAT_U16_LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 16; break; case SND_PCM_FORMAT_U16_BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 16; break; case SND_PCM_FORMAT_S32_LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 32; break; case SND_PCM_FORMAT_S32_BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 32; break; case SND_PCM_FORMAT_U32_LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 32; break; case SND_PCM_FORMAT_U32_BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 32; break; case SND_PCM_FORMAT_S24_3LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 24; break; case SND_PCM_FORMAT_S24_3BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 24; break; case SND_PCM_FORMAT_U24_3LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 24; break; case SND_PCM_FORMAT_U24_3BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 24; break; default: return -EINVAL; } if ((err = snd_pcm_hw_params_get_buffer_size(params, &buffersize) < 0)) return err; ROAR_DBG("roar_pcm_hw_params(*) buffersize (bytes): %i", (int)buffersize); //self->bufsize = snd_pcm_frames_to_bytes(io->pcm, buffersize); self->bufsize = self->info.bits * self->info.channels * buffersize / 8; self->buffer = malloc(self->bufsize); if (self->buffer == NULL) return -1; self->bufptr = 0; ROAR_DBG("roar_pcm_hw_params(*) Setting buffersize (bytes): %i", (int)self->bufsize); ROAR_DBG("roar_pcm_hw_params(*) = 0"); return 0; } /////////////////////////////////// // Status: This should be complete. // This is the last cleanup function to be called by ALSA. /////////////////////////////////// static int roar_pcm_close (snd_pcm_ioplug_t * io) { struct roar_alsa_pcm * self = io->private_data; ROAR_DBG("roar_pcm_close(*) = ?"); roar_disconnect(&(self->roar.con)); pthread_mutex_destroy(&(self->lock)); pthread_mutex_destroy(&(self->cond_lock)); pthread_cond_destroy(&(self->cond)); free(self->buffer); free(self); return 0; } static snd_pcm_ioplug_callback_t roar_pcm_callback = { .start = roar_pcm_start, .stop = roar_pcm_stop, .pointer = roar_pcm_pointer, .transfer = roar_pcm_transfer, .delay = roar_pcm_delay, .prepare = roar_pcm_prepare, .hw_params = roar_pcm_hw_params, .close = roar_pcm_close, }; SND_PCM_PLUGIN_DEFINE_FUNC(roar) { struct roar_alsa_pcm * self; snd_config_iterator_t i, next; snd_config_t * n; const char * para; const char * server = NULL; const char * tmp; int role = ROAR_ROLE_UNKNOWN; int ret; (void)root; ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = ?"); snd_config_for_each(i, next, conf) { n = snd_config_iterator_entry(i); if ( snd_config_get_id(n, ¶) < 0 ) continue; if ( !strcmp(para, "type") || !strcmp(para, "comment") || !strcmp(para, "hint") ) continue; if ( !strcmp(para, "server") ) { if (snd_config_get_string(n, &server) < 0) { return -EINVAL; } } else if ( !strcmp(para, "role") ) { if (snd_config_get_string(n, &tmp) < 0) { return -EINVAL; } if ( (role = roar_str2role(tmp)) == -1 ) { return -EINVAL; } } else { return -EINVAL; } } errno = ENOSYS; if ( (self = malloc(sizeof(struct roar_alsa_pcm))) == NULL ) return -errno; memset(self, 0, sizeof(struct roar_alsa_pcm)); self->stream_role = role; errno = ENOSYS; if ( roar_simple_connect(&(self->roar.con), (char*)server, "ALSA Plugin") == -1 ) { free(self); return -errno; } self->io.version = SND_PCM_IOPLUG_VERSION; self->io.name = "RoarAudio Plugin"; self->io.poll_fd = -1; self->io.poll_events = POLLOUT; self->io.mmap_rw = 0; self->io.callback = &roar_pcm_callback; self->io.private_data = self; if ( (ret = snd_pcm_ioplug_create(&(self->io), name, stream, mode)) < 0 ) { roar_disconnect(&(self->roar.con)); free(self); return ret; } pthread_mutex_init(&(self->lock), NULL); pthread_mutex_init(&(self->cond_lock), NULL); pthread_cond_init(&(self->cond), NULL); if ( (ret = roar_hw_constraint(self)) < 0 ) { snd_pcm_ioplug_delete(&(self->io)); roar_disconnect(&(self->roar.con)); free(self); return ret; } *pcmp = self->io.pcm; ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = 0"); return 0; } SND_PCM_PLUGIN_SYMBOL(roar); //ll ������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/roar.c�������������������������������������������������������������0000644�0001750�0001750�00000002263�12264733617�016205� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * */ #include "roar.h" struct snd_dlsym_link *snd_dlsym_start; //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/roar.h�������������������������������������������������������������0000644�0001750�0001750�00000005456�12264733620�016213� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roar.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _ROARAUDIO_PLUGINS_ALSA_ROAR_H_ #define _ROARAUDIO_PLUGINS_ALSA_ROAR_H_ #include <roaraudio.h> #include <errno.h> #include <alsa/asoundlib.h> #include <alsa/global.h> #include <alsa/pcm_external.h> #include <alsa/control_external.h> #include <pthread.h> #include <time.h> #define _as(x) (sizeof((x))/sizeof(*(x))) struct roar_alsa { struct roar_connection con; }; struct roar_alsa_pcm { snd_pcm_ioplug_t io; struct roar_alsa roar; struct roar_audio_info info; struct roar_stream stream; struct roar_vio_calls stream_vio; int stream_role; int stream_opened; size_t writec; size_t last_ptr; char* buffer; size_t bufsize; volatile size_t bufptr; pthread_t thread; pthread_mutex_t lock; pthread_mutex_t cond_lock; pthread_cond_t cond; volatile int thread_active; int bytes_in_buffer; volatile int64_t total_written; int has_written; struct timespec start_tv; }; void roar_plugin_reset(struct roar_alsa_pcm * self); void* roar_plugin_thread (void * thread_data); size_t roar_plugin_write(struct roar_alsa_pcm * self, const char * buf, size_t size); void roar_plugin_drain(struct roar_alsa_pcm * self); #endif //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsa/thread.c�����������������������������������������������������������0000644�0001750�0001750�00000015111�12264733621�016500� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//thread.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ //#define DEBUG #include "roar.h" #define CHUNK_SIZE 2048 //#define CHUNK_SIZE 256 // Writes to the FIFO buffer. Waits until there is room to write. size_t roar_plugin_write(struct roar_alsa_pcm *self, const char *buf, size_t size) { ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu) = ?", self, buf, (long long unsigned int)size); /* Wait until we have a ready buffer */ while (1) { /* Should the thread be shut down while we're running, return with error */ if ( !self->thread_active ) return 0; //fprintf(stderr, "%d + %d : %d\n", (int)self->bufptr, (int)size, (int)self->bufsize); pthread_mutex_lock(&(self->lock)); if (self->bufptr + size <= self->bufsize) { pthread_mutex_unlock(&(self->lock)); break; } pthread_mutex_unlock(&(self->lock)); pthread_cond_signal(&(self->cond)); /* Sleeps until we can write to the FIFO. */ pthread_mutex_lock(&(self->cond_lock)); pthread_cond_wait(&(self->cond), &(self->cond_lock)); pthread_mutex_unlock(&(self->cond_lock)); } pthread_mutex_lock(&(self->lock)); memcpy(self->buffer + self->bufptr, buf, size); self->bufptr += (int)size; pthread_mutex_unlock(&(self->lock)); /* Send signal to thread that buffer has been updated */ pthread_cond_signal(&(self->cond)); return size; } #define _TEST_CANCEL() do { \ if ( !self->thread_active ) \ goto test_quit; \ } while(0) // Attemps to drain the buffer at all times and write to libroar. // If there is no data, it will wait for roar_plugin_write() to fill up more data. void * roar_plugin_thread (void * thread_data) { /* We share data between thread and callable functions */ struct roar_alsa_pcm *self = thread_data; int rc; /* Plays back data as long as there is data in the buffer. Else, sleep until it can. */ /* Two loops! :3 Beware! */ while(1) { ROAR_DBG("roar_plugin_thread(thread_data=%p): got woken up.", thread_data); while(1) { _TEST_CANCEL(); // We ask the server to send its latest backend data. Do not really care about errors atm. // We only bother to check after 1 sec of audio has been played, as it might be quite inaccurate in the start of the stream. /* If the buffer is empty or we've stopped the stream. Jump out of this for loop */ pthread_mutex_lock(&(self->lock)); if ( self->bufptr < CHUNK_SIZE ) { pthread_mutex_unlock(&(self->lock)); break; } pthread_mutex_unlock(&(self->lock)); ROAR_DBG("roar_plugin_thread(thread_data=%p): Start writing.", thread_data); rc = roar_vio_write(&(self->stream_vio), self->buffer, CHUNK_SIZE); ROAR_DBG("roar_plugin_thread(thread_data=%p): wrote %lli bytes.", thread_data, (long long int)rc); /* If this happens, we should make sure that subsequent and current calls to rsd_write() will fail. */ if ( rc < 0 ) { _TEST_CANCEL(); roar_plugin_reset(self); /* Wakes up a potentially sleeping fill_buffer() */ pthread_cond_signal(&(self->cond)); /* This thread will not be joined, so detach. */ pthread_detach(pthread_self()); pthread_exit(NULL); } if ( !self->has_written ) { pthread_mutex_lock(&(self->lock)); clock_gettime(CLOCK_MONOTONIC, &(self->start_tv)); self->has_written = 1; pthread_mutex_unlock(&(self->lock)); } pthread_mutex_lock(&(self->lock)); self->total_written += rc; pthread_mutex_unlock(&(self->lock)); /* "Drains" the buffer. This operation looks kinda expensive with large buffers, but hey. D: */ pthread_mutex_lock(&(self->lock)); memmove(self->buffer, self->buffer + rc, self->bufsize - rc); self->bufptr -= rc; pthread_mutex_unlock(&(self->lock)); ROAR_DBG("roar_plugin_thread(*): Wrote data to vio. New bufptr: %i", (int)self->bufptr); /* Buffer has decreased, signal fill_buffer() */ pthread_cond_signal(&(self->cond)); } /* If we're still good to go, sleep. We are waiting for fill_buffer() to fill up some data. */ test_quit: if ( self->thread_active ) { pthread_cond_signal(&(self->cond)); pthread_mutex_lock(&(self->cond_lock)); pthread_cond_wait(&(self->cond), &(self->cond_lock)); pthread_mutex_unlock(&(self->cond_lock)); } else { /* Abandon the ship, chap. */ pthread_cond_signal(&(self->cond)); pthread_exit(NULL); } } } void roar_plugin_drain(struct roar_alsa_pcm *self) { struct timespec now_tv; int64_t temp, temp2; /* If the audio playback has started on the server we need to use timers. */ if ( self->has_written ) { /* Falls back to gettimeofday() when CLOCK_MONOTONIC is not supported */ /* Calculates the amount of bytes that the server has consumed. */ clock_gettime(CLOCK_MONOTONIC, &now_tv); temp = (int64_t)now_tv.tv_sec - (int64_t)self->start_tv.tv_sec; temp *= self->info.rate * self->info.channels * self->info.bits / 8; temp2 = (int64_t)now_tv.tv_nsec - (int64_t)self->start_tv.tv_nsec; temp2 *= self->info.rate * self->info.channels * self->info.bits / 8; temp2 /= 1000000000LL; temp += temp2; /* Calculates the amount of data we have in our virtual buffer. Only used to calculate delay. */ self->bytes_in_buffer = (int)((int64_t)self->total_written + (int64_t)self->bufptr - temp); } else { self->bytes_in_buffer = self->bufptr; } } //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/Makefile����������������������������������������������������������������0000644�0001750�0001750�00000000233�11172151640�015574� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../Makefile.conf all: for i in */; do cd $$i; $(MAKE) all; cd ..; done clean: for i in */; do cd $$i; $(MAKE) clean; cd ..; done new: clean all ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/configure.inc�����������������������������������������������������������0000644�0001750�0001750�00000001760�11204073756�016625� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # check for bash... if [ "$(echo -n)" = '-n' ] then SHELL=$(which bash ksh sh 2> /dev/null | grep ^/ | head -n 1) exec $SHELL $0 "$@" fi TF_C=test.c TF=./test check_cc() { echo -n 'testing for C compiler... ' CC=$(which gcc cc 2> /dev/null | head -n 1) if [ -x "$CC" ] then echo $CC else echo no. on_error; fi } check_pkg_config() { echo -n "checking for pkg-config... " if [ "$PKG_CONFIG" = '' ] then PKG_CONFIG=$(which pkg-config false 2> /dev/null | grep ^/ | head -n 1) if $PKG_CONFIG --help > /dev/null 2> /dev/null then echo $PKG_CONFIG else PKG_CONFIG='' echo no on_error; fi else echo $PKG_CONFIG '(forced)' fi } check_libroar() { echo -n 'testing for libroar... ' if $HAVE_ROAR then echo 'yes (forced)' else cat > $TF_C << EOF #include <roaraudio.h> int main (void) { return 0; } EOF $CC -o $TF $TF_C -lroar 2> /dev/null $TF 2> /dev/null if [ "$?" = '0' ] then echo yes else echo no. on_error fi fi } #ll ����������������roaraudio-1.0beta11/plugins/alsavs/�����������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553244�015443� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsavs/Makefile���������������������������������������������������������0000644�0001750�0001750�00000003065�12072575524�017106� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������BASENAME0=libasound_module_pcm_roar BASENAME1=libasound_module_ctl_roar SLIB0=$(BASENAME0)$(SHARED_SUFFIX) SLIB1=$(BASENAME1)$(SHARED_SUFFIX) TARGET=$(SLIB0) $(SLIB1) INSTALL_DIR=$(PREFIX_LIB)/alsa-lib/ OBJS0=pcm_roar.o roar.o OBJS1=ctl_roar.o roar.o include ../../Makefile.conf include ../../Makefile.inc #include Makefile.conf #DEBUG=-DDEBUG -DXXX DEFINES=-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"alsa-plugins\" -DVERSION=\"1.0.13\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DSTDC_HEADERS=1 -DHAVE_LIBASOUND=1 -D_REENTRANT -DPIC CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) -I../../include $(DEFINES) $(DEBUG) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) -I/usr/include/alsa -D_GNU_SOURCE $(pthread) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) $(LDPATH) -L../../lib $(pthread) LIBS = $(LIBROAR) $(lib_m) $(lib_dl) -lrt $(lib_asound) all: ${TARGET} clean: rm -f ${TARGET} *.o tests tests.c new: clean all install: ${TARGET} mkdir -p ${DESTDIR}${INSTALL_DIR} cp ${TARGET} ${DESTDIR}${INSTALL_DIR} semi-install: ${TARGET} mkdir -p ${DESTDIR}${INSTALL_DIR} ln -fs `pwd`/$(SLIB0) ${DESTDIR}${INSTALL_DIR} ln -fs `pwd`/$(SLIB1) ${DESTDIR}${INSTALL_DIR} $(SLIB0): $(OBJS0) $(CC) $(LDFLAGS) -Wl,-soname -Wl,$(SLIB0) -o $(SLIB0) $(OBJS0) $(LIBS) $(SLIB1): $(OBJS1) $(CC) $(LDFLAGS) -Wl,-soname -Wl,$(SLIB1) -o $(SLIB1) $(OBJS1) $(LIBS) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsavs/ctl_roar.c�������������������������������������������������������0000644�0001750�0001750�00000021543�12264733621�017415� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ctl_roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ //#define DEBUG #include "roar.h" #include <string.h> #ifdef DEBUG static struct roar_vio_calls DEBUG_FH; #endif static void roar_plugin_close(snd_ctl_ext_t * ext) { struct roar_alsa_ctl * self = ext->private_data; roar_disconnect(&(self->roar.con)); free(self); } static int roar_plugin_elem_count(snd_ctl_ext_t *ext) { struct roar_alsa_ctl * self = ext->private_data; int ret = 0; for (; self->streams[ret].id != -1; ret++); return ret; } static int roar_plugin_elem_list(snd_ctl_ext_t *ext, unsigned int offset, snd_ctl_elem_id_t *id) { struct roar_alsa_ctl * self = ext->private_data; snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_name(id, self->streams[offset].name); return 0; } // ALSA is strange here, this function makes keys (stream ID) from non-unique stream names... static snd_ctl_ext_key_t roar_plugin_find_elem(snd_ctl_ext_t *ext, const snd_ctl_elem_id_t *id) { struct roar_alsa_ctl * self = ext->private_data; // int numid = snd_ctl_elem_id_get_numid(id); const char * name; int i; // ROAR_DBG("roar_plugin_find_elem(ext=%p, id=%p): numid=%i", ext, id, numid); // return self->streams[numid].id; name = snd_ctl_elem_id_get_name(id); for (i = 0; i < MAX_STREAMS; i++) { if ( !strcmp(self->streams[i].name, name) ) { return self->streams[i].id; } } return SND_CTL_EXT_KEY_NOT_FOUND; } static int roar_plugin_get_attribute(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int *type, unsigned int *acc, unsigned int *count) { struct roar_alsa_ctl * self = ext->private_data; int i; *type = SND_CTL_ELEM_TYPE_INTEGER; *acc = SND_CTL_EXT_ACCESS_READWRITE; for (i = 0; i < MAX_STREAMS && self->streams[i].id != (int)key; i++) if ( i == MAX_STREAMS ) return -EIO; *count = self->streams[i].channels; return 0; } static int roar_plugin_get_integer_info(snd_ctl_ext_t *ext ATTRIBUTE_UNUSED, snd_ctl_ext_key_t key ATTRIBUTE_UNUSED, long *imin, long *imax, long *istep) { *istep = 0; *imin = 0; *imax = 65535; return 0; } static int roar_plugin_read_integer(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value) { struct roar_alsa_ctl * self = ext->private_data; struct roar_mixer_settings mixer; int channels; int i; for (i = 0; i < MAX_STREAMS && self->streams[i].id != (int)key; i++) if ( i == MAX_STREAMS ) return -EIO; roar_err_clear_all(); if ( roar_get_vol(&(self->roar.con), key, &mixer, &channels) == -1 ) { roar_err_update(); return -errno; } if ( channels != (int)self->streams[i].channels ) return -EIO; for (i = 0; i < channels; i++) value[i] = ((unsigned long int)mixer.mixer[i] * 65535LU) / mixer.scale; return 0; } static int roar_plugin_write_integer(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value) { struct roar_alsa_ctl * self = ext->private_data; struct roar_mixer_settings mixer; int sid; int i; ROAR_DBG("roar_plugin_write_integer(ext=%p, key=%i, value=%p) = ?", ext, (int)key, value); for (sid = 0; sid < MAX_STREAMS && self->streams[sid].id != (int)key; sid++) if ( sid == MAX_STREAMS ) return -EIO; mixer.scale = 65535; mixer.rpg_mul = 1; mixer.rpg_div = 1; for (i = 0; i < (int)self->streams[i].channels; i++) mixer.mixer[i] = value[i]; roar_err_clear_all(); if ( roar_set_vol(&(self->roar.con), key, &mixer, self->streams[sid].channels, ROAR_SET_VOL_ALL) == -1 ) { roar_err_update(); return -errno; } return 0; } static int roar_plugin_read_event(snd_ctl_ext_t *ext ATTRIBUTE_UNUSED, snd_ctl_elem_id_t *id ATTRIBUTE_UNUSED, unsigned int *event_mask ATTRIBUTE_UNUSED) { return -EAGAIN; } static void roar_plugin__handle_stream(struct roar_alsa_ctl * self, int id) { struct roar_mixerstream * cs = NULL; struct roar_stream s; char name[1024]; int i; if ( roar_get_stream(&(self->roar.con), &s, id) == -1 ) return; switch (s.dir) { case ROAR_DIR_OUTPUT: case ROAR_DIR_MIXING: case ROAR_DIR_BRIDGE: if ( roar_stream_get_name(&(self->roar.con), &s, name, sizeof(name)) != 0 ) snprintf(name, sizeof(name), "Stream %i", id); break; default: return; break; } switch (s.dir) { case ROAR_DIR_MIXING: case ROAR_DIR_BRIDGE: if ( strstr(name, "MIDI") != NULL || strstr(name, "Light") != NULL ) return; break; } for (i = 0; cs == NULL && i < (int)(sizeof(self->streams)/sizeof(*self->streams)); i++) if (self->streams[i].id == -1 ) cs = &(self->streams[i]); if ( cs == NULL ) return; cs->id = id; cs->channels = s.info.channels; strncpy(cs->name, name, sizeof(cs->name) - 1); } static int roar_plugin__find_streams(struct roar_alsa_ctl * self) { int id[ROAR_STREAMS_MAX]; int num; int i; for (i = 0; i < (int)(sizeof(self->streams)/sizeof(*self->streams)); i++) self->streams[i].id = -1; roar_err_clear_all(); if ( (num = roar_list_streams(&(self->roar.con), id, ROAR_STREAMS_MAX)) == -1 ) { roar_err_update(); return -errno; } for (i = 0; i < num; i++) roar_plugin__handle_stream(self, i); return 0; } static snd_ctl_ext_callback_t roar_ext_callback = { .close = roar_plugin_close, .elem_count = roar_plugin_elem_count, .elem_list = roar_plugin_elem_list, .find_elem = roar_plugin_find_elem, .get_attribute = roar_plugin_get_attribute, .get_integer_info = roar_plugin_get_integer_info, .read_integer = roar_plugin_read_integer, .write_integer = roar_plugin_write_integer, .read_event = roar_plugin_read_event }; SND_CTL_PLUGIN_DEFINE_FUNC(roar) { struct roar_alsa_ctl * self; snd_config_iterator_t i, next; snd_config_t * n; const char * para; const char * server = NULL; int error; const char * ext_id = "ROAR"; const char * ext_name = "RoarAudio"; (void)root; #ifdef DEBUG roar_vio_open_dstr_simple(&DEBUG_FH, "/tmp/alsamixer-roar.log", O_WRONLY|O_CREAT|O_APPEND); roar_debug_set_stderr_vio(&DEBUG_FH); roar_debug_set_stderr_mode(ROAR_DEBUG_MODE_VIO); #endif snd_config_for_each(i, next, conf) { n = snd_config_iterator_entry(i); if ( snd_config_get_id(n, ¶) < 0 ) continue; if ( !strcmp(para, "type") || !strcmp(para, "comment") || !strcmp(para, "hint") ) continue; if ( !strcmp(para, "server") ) { if (snd_config_get_string(n, &server) < 0) { return -EINVAL; } } else { return -EINVAL; } } if ( (self = malloc(sizeof(struct roar_alsa_ctl))) == NULL ) return -errno; memset(self, 0, sizeof(struct roar_alsa_ctl)); errno = ENOSYS; if ( roar_simple_connect(&(self->roar.con), server, "ALSA Plugin") == -1 ) { free(self); return -errno; } if ( (error = roar_plugin__find_streams(self)) < 0 ) { roar_disconnect(&(self->roar.con)); free(self); return error; } self->ext.version = SND_CTL_EXT_VERSION; self->ext.card_idx = 0; /* FIXME */ strncpy(self->ext.id, ext_id, sizeof(self->ext.id) - 1); strcpy(self->ext.driver, "OSS-Emulation"); strncpy(self->ext.name, ext_name, sizeof(self->ext.name) - 1); strncpy(self->ext.longname, ext_name, sizeof(self->ext.longname) - 1); strncpy(self->ext.mixername, ext_name, sizeof(self->ext.mixername) - 1); self->ext.poll_fd = -1; self->ext.callback = &roar_ext_callback; self->ext.private_data = self; if ( (error = snd_ctl_ext_create(&(self->ext), name, mode)) < 0 ) { roar_disconnect(&(self->roar.con)); free(self); return error; } *handlep = self->ext.handle; return 0; } SND_CTL_PLUGIN_SYMBOL(roar); �������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsavs/pcm_roar.c�������������������������������������������������������0000644�0001750�0001750�00000036345�12264733621�017420� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//pcm_roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010-2011 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ //#define DEBUG #include "roar.h" // Equvivalent to prepare(). Starts a stream. Might/will be called several times during a program! ///////////////////////////////////////////////// // Status: Should be mostly complete. // Condition for invalid fh is not solved here. //////////////////////////////////////////////// static int roar_pcm_start (snd_pcm_ioplug_t * io) { struct roar_alsa_pcm * self = io->private_data; int fh; int val; int err; ROAR_DBG("roar_pcm_start(*) = ?"); // If start is called several times in a row, just ignore it. if (self->stream_opened) return 0; if ( (self->vss = roar_vs_new_from_con(&(self->roar.con), &err)) == NULL ) { roar_err_set(err); roar_err_update(); return -errno; } if ( roar_vs_stream(self->vss, &(self->info), io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR, &err) == -1 ) { roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); self->vss = NULL; roar_err_set(err); roar_err_update(); return -errno; } // ALSA really expects there to be self->bufsize writable bytes. if ( roar_vs_buffer(self->vss, self->bufsize + 1, &err) == -1 ) { roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); self->vss = NULL; roar_err_set(err); roar_err_update(); return -errno; } val = ROAR_VS_ASYNCLEVEL_AUTO; if ( roar_vs_ctl(self->vss, ROAR_VS_CMD_SET_ASYNC, &val, &err) == -1 ) { roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); self->vss = NULL; roar_err_set(err); roar_err_update(); return -errno; } if ( self->stream_role != ROAR_ROLE_UNKNOWN ) { if ( roar_vs_role(self->vss, self->stream_role, &err) == -1 ) { ROAR_WARN("roar_pcm_start(*): Can not set stream role: %s(%i): %s", roar_role2str(self->stream_role), self->stream_role, roar_error2str(roar_error)); } } if ( roar_vio_ctl(roar_vs_vio_obj(self->vss, NULL), io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_VIO_CTL_GET_SELECT_WRITE_FH : ROAR_VIO_CTL_GET_SELECT_READ_FH, &fh) != 1 ) { io->poll_fd = fh; io->poll_events = io->stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN; } // Oh, no, what should we do here if roar_vio_ctl() fails to grab a valid fh to poll? // In any case, ALSA will error out the next time it tries to poll() if we don't give it a valid fh. snd_pcm_ioplug_reinit_status(io); // Stream is now active, yay. self->stream_opened = 1; ROAR_DBG("roar_pcm_start(*) = 0"); return 0; } void roar_plugin_reset(struct roar_alsa_pcm *self) { if ( !self->stream_opened ) return; roar_vs_close(self->vss, ROAR_VS_TRUE, NULL); self->vss = NULL; self->stream_opened = 0; self->last_ptr = 0; } // Simply stopping the stream. Will need to be restarted to play more. // Will be called several times together with roar_pcm_start() /////////////////////////////////////////////////// // Status: Still needs some error checking for the pthread calls, but // should work. ////////////////////////////////////////////////// static int roar_pcm_stop (snd_pcm_ioplug_t *io) { struct roar_alsa_pcm * self = io->private_data; // If this is called several times in a row, just ignore. ROAR_DBG("roar_pcm_stop(*) = 0"); roar_plugin_reset(self); return 0; } /////////////////////////////// // Status: Should be complete. /////////////////////////////// static int roar_hw_constraint(struct roar_alsa_pcm * self) { snd_pcm_ioplug_t *io = &(self->io); static const snd_pcm_access_t access_list[] = { SND_PCM_ACCESS_RW_INTERLEAVED }; static const unsigned int formats[] = { SND_PCM_FORMAT_S8, SND_PCM_FORMAT_U8, SND_PCM_FORMAT_A_LAW, SND_PCM_FORMAT_MU_LAW, SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_U16_LE, SND_PCM_FORMAT_U16_BE, SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S32_BE, SND_PCM_FORMAT_U32_LE, SND_PCM_FORMAT_U32_BE, SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3BE, SND_PCM_FORMAT_U24_3LE, SND_PCM_FORMAT_U24_3BE, }; int ret; ROAR_DBG("roar_hw_constraint(*) = ?"); if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, _as(access_list), access_list)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT, _as(formats), formats)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS, 1, ROAR_MAX_CHANNELS)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 192000)) < 0 ) return ret; // We shouldn't let ALSA use extremely low or high values, it will kill a kitty most likely. :v if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1 << 6, 1 << 18)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 1, 1024)) < 0 ) return ret; if ( (ret = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1 << 13, 1 << 24)) < 0 ) return ret; ROAR_DBG("roar_hw_constraint(*) = 0"); return 0; } // Referring to alsa-lib/src/pcm/pcm_ioplug.c : snd_pcm_ioplug_hw_ptr_update /////////////////////////////////////////////////////////// // Status: Mostly complete, but uses a really nasty hack! /////////////////////////////////////////////////////////// static snd_pcm_sframes_t roar_pcm_pointer(snd_pcm_ioplug_t *io) { struct roar_alsa_pcm * self = io->private_data; int ptr; int buffered; ssize_t avail; ROAR_DBG("roar_pcm_pointer(*) = ?"); // Did ALSA just call snd_pcm_reset() or something like that without calling the plugin? // We should restart our stream as well. if ( io->appl_ptr < self->last_ptr ) { roar_pcm_stop(io); roar_pcm_start(io); } // ALSA expects return value to be equal to the amount of data written on the hardware side. // It uses this to calculate writable amount. (Because hey, just calling a get_avail() is too hard.) // Return value is thus io->appl_ptr - buffered_amount; while ( roar_vs_iterate(self->vss, ROAR_VS_NOWAIT, NULL) == 2 ); avail = roar_vs_get_avail_write(self->vss, NULL); ROAR_DBG("roar_pcm_pointer(*): avail=%lli", (long long int)avail); buffered = snd_pcm_bytes_to_frames(io->pcm, self->bufsize - avail); ptr = io->appl_ptr - buffered; self->last_ptr = io->appl_ptr; ROAR_DBG("roar_pcm_pointer(*) appl_ptr (frames): %i, buffered (frames): %i", (int)io->appl_ptr, (int)buffered); ROAR_DBG("roar_pcm_pointer(*) = %i", ptr); return ptr; } // TODO: FIXME: add support for reading data! ////////////////////////////////////////////////// // Status: For writing, this should be complete. ////////////////////////////////////////////////// static snd_pcm_sframes_t roar_pcm_transfer(snd_pcm_ioplug_t *io, const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) { struct roar_alsa_pcm * self = io->private_data; char * buf; size_t len = size * self->info.channels * self->info.bits / 8; ssize_t ret; ROAR_DBG("roar_pcm_transfer(*) = ?"); ROAR_DBG("roar_pcm_transfer(*): len=%lu", (long unsigned int) len); // Weird ALSA stuff. buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8; while (len) { ret = roar_vs_write(self->vss, buf, len, NULL); /* * <ph3-der-loewe> is it supposed to be EIO? * <ph3-der-loewe> or can we return the true error code from roar_vs_write()? * <maister> ALSA tends to give -EIO errors * <maister> It shouldn't cause problems to pass roar_vs errnos. * <maister> But the error strings might be a bit confusing perhaps */ if ( ret == -1 ) return -EIO; len -= ret; buf += ret; } while ( roar_vs_iterate(self->vss, ROAR_VS_NOWAIT, NULL) == 2 ); ROAR_DBG("roar_pcm_transfer(*) = %lli", (long long int)size); return size; } /////////////////////////////////////////////////////////////////// // Status: Still missing proper delay measurements from the roar server. // Only uses a blind timer now. In ideal conditions, this will work well. /////////////////////////////////////////////////////////////////// static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) { struct roar_alsa_pcm * self = io->private_data; roar_mus_t lat; ROAR_DBG("roar_pcm_delay(*) = ?"); lat = roar_vs_latency(self->vss, ROAR_VS_BACKEND_DEFAULT, ROAR_VS_NOWAIT, NULL); *delayp = (lat * self->info.rate) / 1000000; return 0; } //////////////////// // Status: Complete //////////////////// static int roar_pcm_prepare(snd_pcm_ioplug_t *io) { ROAR_DBG("roar_pcm_prepare(*) = ?"); return roar_pcm_start(io); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Status: This should be mostly complete. // I'm not sure if hw_params can be called several times during one stream without stop() start() in between. // This will mean a memory leak, and possibly breakage should the buffer size change itself. /////////////////////////////////////////////////////////////////////////////////////////////////////////////// static int roar_pcm_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) { struct roar_alsa_pcm * self = io->private_data; snd_pcm_uframes_t buffersize; int err; ROAR_DBG("roar_pcm_hw_params(*) = ?"); self->info.channels = io->channels; self->info.rate = io->rate; switch (io->format) { case SND_PCM_FORMAT_S8: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 8; break; case SND_PCM_FORMAT_U8: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 8; break; case SND_PCM_FORMAT_A_LAW: self->info.codec = ROAR_CODEC_ALAW; self->info.bits = 8; break; case SND_PCM_FORMAT_MU_LAW: self->info.codec = ROAR_CODEC_MULAW; self->info.bits = 8; break; case SND_PCM_FORMAT_S16_LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 16; break; case SND_PCM_FORMAT_S16_BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 16; break; case SND_PCM_FORMAT_U16_LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 16; break; case SND_PCM_FORMAT_U16_BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 16; break; case SND_PCM_FORMAT_S32_LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 32; break; case SND_PCM_FORMAT_S32_BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 32; break; case SND_PCM_FORMAT_U32_LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 32; break; case SND_PCM_FORMAT_U32_BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 32; break; case SND_PCM_FORMAT_S24_3LE: self->info.codec = ROAR_CODEC_PCM_S_LE; self->info.bits = 24; break; case SND_PCM_FORMAT_S24_3BE: self->info.codec = ROAR_CODEC_PCM_S_BE; self->info.bits = 24; break; case SND_PCM_FORMAT_U24_3LE: self->info.codec = ROAR_CODEC_PCM_U_LE; self->info.bits = 24; break; case SND_PCM_FORMAT_U24_3BE: self->info.codec = ROAR_CODEC_PCM_U_BE; self->info.bits = 24; break; default: return -EINVAL; } if ((err = snd_pcm_hw_params_get_buffer_size(params, &buffersize) < 0)) return err; ROAR_DBG("roar_pcm_hw_params(*) buffersize (frames): %i", (int)buffersize); self->bufsize = self->info.bits * self->info.channels * buffersize / 8; ROAR_DBG("roar_pcm_hw_params(*) Setting buffersize (bytes): %i", (int)self->bufsize); ROAR_DBG("roar_pcm_hw_params(*) = 0"); return 0; } /////////////////////////////////// // Status: This should be complete. // This is the last cleanup function to be called by ALSA. /////////////////////////////////// static int roar_pcm_close (snd_pcm_ioplug_t * io) { struct roar_alsa_pcm * self = io->private_data; ROAR_DBG("roar_pcm_close(*) = ?"); roar_plugin_reset(self); roar_disconnect(&(self->roar.con)); free(self); return 0; } static snd_pcm_ioplug_callback_t roar_pcm_callback = { .start = roar_pcm_start, .stop = roar_pcm_stop, .pointer = roar_pcm_pointer, .transfer = roar_pcm_transfer, .delay = roar_pcm_delay, .prepare = roar_pcm_prepare, .hw_params = roar_pcm_hw_params, .close = roar_pcm_close, }; SND_PCM_PLUGIN_DEFINE_FUNC(roar) { struct roar_alsa_pcm * self; snd_config_iterator_t i, next; snd_config_t * n; const char * para; const char * server = NULL; const char * tmp; int role = ROAR_ROLE_UNKNOWN; int ret; (void)root; ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = ?"); snd_config_for_each(i, next, conf) { n = snd_config_iterator_entry(i); if ( snd_config_get_id(n, ¶) < 0 ) continue; if ( !strcmp(para, "type") || !strcmp(para, "comment") || !strcmp(para, "hint") ) continue; if ( !strcmp(para, "server") ) { if (snd_config_get_string(n, &server) < 0) { return -EINVAL; } } else if ( !strcmp(para, "role") ) { if (snd_config_get_string(n, &tmp) < 0) { return -EINVAL; } if ( (role = roar_str2role(tmp)) == -1 ) { return -EINVAL; } } else { return -EINVAL; } } errno = ENOSYS; if ( (self = malloc(sizeof(struct roar_alsa_pcm))) == NULL ) return -errno; memset(self, 0, sizeof(struct roar_alsa_pcm)); self->stream_role = role; errno = ENOSYS; if ( roar_simple_connect(&(self->roar.con), server, "ALSA Plugin") == -1 ) { free(self); return -errno; } self->io.version = SND_PCM_IOPLUG_VERSION; self->io.name = "RoarAudio Plugin"; self->io.poll_fd = -1; self->io.poll_events = POLLOUT; self->io.mmap_rw = 0; self->io.callback = &roar_pcm_callback; self->io.private_data = self; if ( (ret = snd_pcm_ioplug_create(&(self->io), name, stream, mode)) < 0 ) { roar_disconnect(&(self->roar.con)); free(self); return ret; } if ( (ret = roar_hw_constraint(self)) < 0 ) { snd_pcm_ioplug_delete(&(self->io)); roar_disconnect(&(self->roar.con)); free(self); return ret; } *pcmp = self->io.pcm; ROAR_DBG("SND_PCM_PLUGIN_DEFINE_FUNC(roar) = 0"); return 0; } SND_PCM_PLUGIN_SYMBOL(roar); //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsavs/roar.c�����������������������������������������������������������0000644�0001750�0001750�00000002263�12264733622�016552� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * */ #include "roar.h" struct snd_dlsym_link *snd_dlsym_start; //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/alsavs/roar.h�����������������������������������������������������������0000644�0001750�0001750�00000005140�12264733622�016554� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roar.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010-2011 * * This file is part of libroar a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * * NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc * or libpulse*: * The libs libroaresd, libroararts and libroarpulse link this lib * and are therefore GPL. Because of this it may be illigal to use * them with any software that uses libesd, libartsc or libpulse*. */ #ifndef _ROARAUDIO_PLUGINS_ALSA_ROAR_H_ #define _ROARAUDIO_PLUGINS_ALSA_ROAR_H_ #include <roaraudio.h> #include <errno.h> #include <alsa/asoundlib.h> #include <alsa/global.h> #include <alsa/pcm_external.h> #include <alsa/control_external.h> #include <pthread.h> #include <time.h> #define _as(x) (sizeof((x))/sizeof(*(x))) struct roar_alsa { struct roar_connection con; }; struct roar_alsa_pcm { snd_pcm_ioplug_t io; struct roar_alsa roar; struct roar_audio_info info; roar_vs_t * vss; int stream_role; int stream_opened; size_t bufsize; size_t last_ptr; }; struct roar_mixerstream { int id; char name[32]; unsigned int channels; }; #define MAX_STREAMS 16 struct roar_alsa_ctl { snd_ctl_ext_t ext; struct roar_alsa roar; struct roar_mixerstream streams[MAX_STREAMS]; }; void roar_plugin_reset(struct roar_alsa_pcm * self); void* roar_plugin_thread (void * thread_data); size_t roar_plugin_write(struct roar_alsa_pcm * self, const char * buf, size_t size); void roar_plugin_drain(struct roar_alsa_pcm * self); #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/bash/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553177�015074� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/bash/roaraudio����������������������������������������������������������0000644�0001750�0001750�00000051122�12100236105�016754� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # /etc/bash_completion.d/roaraudio # # Bash completion function for the RoarAudio. # http://roaraudio.keep-cool.org/ # # Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org> # -- # # Tools supported completly: #roard #roar-config # Tools supported partly: #roarctl (volume not implemented correctly) # Tools not supported at all: # Tools not supported at all and unimportent: # Unsupported devel tools: #roartypes # The rest: #roarcat #roarcatplay #roarcatvio #roarbidir #roarmon #roarmonhttp #roarradio #roarlight #roarinterconnect #roarclientpass #roarfilt #roarvumeter #roarsockconnect #roarphone #roarshout #roarvorbis #roarsin #roardtmf #roarvio _roar_no_opts() { COMPREPLY=() } complete -F _roar_no_opts roarsocktypes roartypes _roar_server() { COMPREPLY=( $(_roar_server_exec "$1") ) } _roar_server_exec() { local cur link words nodes stdsocks x11sock file_based file_based_ok local addr cur="$1" link=$(readlink /etc/roarserver 2> /dev/null) nodes=$(grep '^\(node\|executor\)' /etc/decnet.conf 2> /dev/null | sed 's/^.*\tname\t\t*//; s/\t.*$//; s/$/::/') file_based="/tmp/roar $HOME/.roar /tmp/muroard" stdsocks="localhost ::roar"; x11sock=$(xprop -root 2>/dev/null | grep '^ROAR_SERVER(STRING) = ' | sed 's/^[^"]*"//; s/"$//') file_based_ok="" for addr in $file_based do if [ -S "$addr" ] then file_based_ok="$file_based_ok $addr" fi done words="$ROAR_SERVER $link $nodes $file_based_ok $stdsocks $x11sock +slp +fork +abstract" compgen -A hostname $cur compgen -W "$words" $cur } _roar_jumbo_mtu() { COMPREPLY=($(compgen -W "750 1000 1100 1200 1300" -- "${COMP_WORDS[COMP_CWORD]}")) } _roar_rate() { local cur cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=($(compgen -W "8000 16000 32000 11025 22050 44100 48000 96000" -- ${cur})) } _roar_bits() { local cur cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=($(compgen -W "8 16 24 32" -- ${cur})) } _roar_channels() { local cur cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=($(compgen -W "1 2 3 4 5 6 7 8 9" -- ${cur})) } _roar_codec() { local cur cur="${COMP_WORDS[COMP_CWORD]}" words=$(roard --list-cf | tail -n +4 | sed 's/^ *//; s/ .*$//') COMPREPLY=($(compgen -W "${words} default pcm" -- ${cur})) } _roar_flag() { local cur cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=($(compgen -W "meta primary sync cleanmeta hwmixer pause mute mmap antiecho recsource passmixer virtual prethru immutable enhance singlesink" -- ${cur})) } _roar_dir() { local cur cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=($(compgen -W "play record monitor filter output mixing meta bidir thru bridge midi_in midi_out light_in light_out raw_in raw_out complex_in complex_out rdtcs_in rdtcs_out" -- ${cur})) } _roar_metatype() { local cur cur="${COMP_WORDS[COMP_CWORD]}" #phi@ph7:roaraudio $ echo $(grep '^#define ROAR_META_TYPE_' include/roaraudio/meta.h | cut -d_ -f4,5,6,7,8,9 | cut -d' ' -f1 | tr A-Z a-z) COMPREPLY=($(compgen -W "none title album author autor artist version date license tracknumber organization description genre location contact streamurl homepage thumbnail length comment other filename fileurl server duration www woaf encoder encodedby year discid rpg_track_peak rpg_track_gain rpg_album_peak rpg_album_gain hash signalinfo audioinfo offset performer copyright likeness composer rights isrc language gtin isbn ean publisher discnumber sourcemedia label labelno" -- ${cur})) } _roar_role() { local cur cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=($(compgen -W "unknown none music video game event beep phone background_music voice instrument rhythm click mixed" -- ${cur})) } _roar_baseopts() { case "$1" in '--rate') _roar_rate return 0 ;; '--bits') _roar_bits return 0 ;; '--chans') _roar_channels return 0 ;; '--server') _roar_server "${COMP_WORDS[COMP_CWORD]}" return 0 ;; *) ;; esac return 77 } _roar_basecodec() { case "$1" in '--codec') _roar_codec return 0 ;; *) ;; esac return 77 } _roar_baseclients() { local cur prev opts dirs COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" dirs="--wave --midi --light --raw --complex --rdtcs" opts="$dirs --server --rate -R --bits -B --chans -C --codec --rel-id --help" [ "${COMP_WORDS[0]}" = "roarmon" ] && opts="$opts --prethru" _roar_baseopts "$prev" && return 0; _roar_basecodec "$prev" && return 0; case "${prev}" in '-R') _roar_rate return 0 ;; '-B') _roar_bits return 0 ;; '-C') _roar_channels return 0 ;; *) ;; esac _filedir COMPREPLY=(${COMPREPLY[*]} $(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roar_baseclients roarcat roarmon _roarcatplay() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" opts="--server --simple --passive --background --verbose --help" case "${COMP_WORDS[COMP_CWORD-1]}" in '--server') _roar_server "$cur" return 0 ;; *) ;; esac _filedir COMPREPLY=(${COMPREPLY[*]} $(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarcatplay roarcatplay _roarvumeter() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--server --rate --bits --chans --samples --pc --db --beat --lowpass --help" _roar_baseopts "$prev" && return 0; case "${prev}" in '--samples') COMPREPLY=($(compgen -W "5000 50000" -- ${cur})) return 0 ;; '--lowpass') COMPREPLY=($(compgen -W "100 200 300 400 500" -- ${cur})) return 0 ;; *) ;; esac COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarvumeter roarvumeter _roarradio() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--server --rate --bits --chans --codec --help" _roar_baseopts "$prev" && return 0; _roar_basecodec "$prev" && return 0; COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarradio roarradio _roarvorbis() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--server --vclt-out --help" case "${prev}" in '--vclt-out') _filedir return 0 ;; '--server') _roar_server "$cur" return 0 ;; *) ;; esac COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarvorbis roarvorbis _roarinterconnect() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--server --remote --type --rate --bits --chans --codec --help" _roar_baseopts "$prev" && return 0; _roar_basecodec "$prev" && return 0; case "${prev}" in '--remote') _roar_server "$cur" return 0 ;; '--type') COMPREPLY=($(compgen -W "roar esd bidir filter transmit receive" -- ${cur})) return 0 ;; *) ;; esac COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarinterconnect roarinterconnect _roarbidir() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--server --rate --bits --chans --codec --help" _roar_baseopts "$prev" && return 0; _roar_basecodec "$prev" && return 0; _filedir COMPREPLY=(${COMPREPLY[*]} $(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarbidir roarbidir roarcatvio roarcatpassfh roarcatsendfile _roarcatad() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--server --rate --bits --chans --help" _roar_baseopts "$prev" && return 0; _filedir COMPREPLY=(${COMPREPLY[*]} $(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarcatad roarcatad roarcat2sock _roarphone() { local cur prev opts mopts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" mopts="--m-rn --m-nick --m-email --m-hp --m-thumbn --m-loc --m-org" opts="--server --jumbo-mtu --io-flush --rate --bits --chans --afi-downmix --afi-lowpass --afi-speex-prep --afi-speex-denoise --afi-speex-agc --afi-speex-vad --codec --transcode --driver --device --antiecho --threshold --help $mopts" _roar_baseopts "$prev" && return 0; _roar_basecodec "$prev" && return 0; case "${prev}" in '--jumbo-mtu') _roar_jumbo_mtu return 0 ;; '--io-flush') return 0 ;; '--afi-lowpass') return 0 ;; '--driver') return 0 ;; '--device') _filedir return 0 ;; '--antiecho') COMPREPLY=($(compgen -W "none simple speex roard" -- ${cur})) return 0 ;; '--threshold') return 0 ;; '--m-rn') return 0 ;; '--m-nick') COMPREPLY=($(compgen -W "$USER" -- ${cur})) return 0 ;; '--m-email') COMPREPLY=($(compgen -W "$USER@$HOSTNAME" -- ${cur})) return 0 ;; '--m-hp') return 0 ;; '--m-thumbn') return 0 ;; '--m-loc') return 0 ;; '--m-org') return 0 ;; *) ;; esac COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roarphone roarphone _roarctl() { local cur prev pprev opts cmds COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" pprev="--NX-COMMAND--" if [ "$COMP_CWORD" -ge 2 ] then pprev="${COMP_WORDS[COMP_CWORD-2]}" fi if [ "$COMP_CWORD" -ge 3 ] then if [ "${COMP_WORDS[COMP_CWORD-3]}" = 'newvirtual' ] then _roar_codec return 0 fi if [ "$COMP_CWORD" -ge 4 ] then if [ "${COMP_WORDS[COMP_CWORD-4]}" = 'newvirtual' ] then _roar_rate return 0 fi if [ "$COMP_CWORD" -ge 5 ] then if [ "${COMP_WORDS[COMP_CWORD-5]}" = 'newvirtual' ] then _roar_bits return 0 fi if [ "$COMP_CWORD" -ge 6 ] then if [ "${COMP_WORDS[COMP_CWORD-6]}" = 'newvirtual' ] then _roar_channels return 0 fi fi fi fi fi opts="--server --help --verbose -v --list-aiprofiles --list-libstandards --enum-servers --hash-password" cmds="help sleep ping whoami listaiprofiles aiprofileget standby off resume on standbymode exit terminate volume flag unflag kick newvirtual metaget metasave metaload serveroinfo listclients liststreams allinfo toogleflag protectflag role serverinfo servertime serveroinfo2 serverstandards libstandards clientinfo streaminfo" case "${pprev}" in 'volume') COMPREPLY=($(compgen -W "mono stereo 1 2 3 4 5 6 7 8 9" -- ${cur})) return 0 ;; 'flag'|'unflag'|'toogleflag'|'protectflag') _roar_flag return 0 ;; 'kick') return 0 ;; 'newvirtual') _roar_dir return 0 ;; 'metaget') _roar_metatype return 0 ;; 'metasave') _filedir return 0 ;; 'metaload') _filedir return 0 ;; 'role') _roar_role return 0 ;; *) ;; esac case "${prev}" in '--server') _roar_server "$cur" return 0 ;; 'sleep') return 0 ;; 'ping') return 0 ;; 'aiprofileget') COMPREPLY=($(compgen -W "$(roarctl --list-aiprofiles | grep '^Profile Name *: *' | sed 's/^.*: *//')" -- ${cur})) return 0 ;; 'volume') return 0 ;; 'flag'|'unflag'|'toogleflag'|'protectflag') return 0 ;; 'kick') COMPREPLY=($(compgen -W "client stream sample source" -- ${cur})) return 0 ;; 'newvirtual') return 0 ;; 'metaget') return 0 ;; 'metasave') return 0 ;; 'metaload') return 0 ;; 'serveroinfo2') _roar_dir return 0 ;; 'clientinfo'|'streaminfo'|'role') COMPREPLY=($(compgen -W "0 1 2 3 4 5 6 7 8 9" -- ${cur})) return 0 ;; *) ;; esac COMPREPLY=($(compgen -W "${opts} ${cmds}" -- ${cur})) return 0 } complete -F _roarctl roarctl # TODO: add support to this so interactions between parameters are represented. _roar_config() { local cur prev opts libs COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--help --version --libs --cflags --output-pc --output-normal --render-path --universal --provider --product --list-path --path --compare-versions" libs="roar roardsp roarmidi roarlight roareio roaresd esd roarartsc artsc roarpulse pulse roarpulse-simple pulse-simple roarsndio sndio roaryiff Y2" liblibs=lib`echo "$libs" | sed 's/ / lib/g'` COMPREPLY=($(compgen -W "${opts} ${libs} ${liblibs}" -- ${cur})) return 0 } complete -F _roar_config roar-config _roard() { local cur prev opts local opts_misc opts_auth opts_plugins opts_audio opts_stream opts_rolestack opts_output opts_source opts_cf opts_midi opts_light opts_rdtcs opts_x11 opts_server COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" # # The basic options we'll complete. # opts_misc="--daemon --verbose --terminate --start --restart --stop --shutdown --realtime --memlock --chroot --setgid --setuid --sysclocksync --location --description --pidfile --log-syslog --script-postdown --watchdog --watchdog-time" opts_auth="--guest-acclev --trust-acclev --trust-root --no-trust-root --authfile-gen --authfile-load --authfile-type --authfile-acclev --new-authfile" opts_plugins="--plugin-load" opts_audio="--rate --bits --chans -R -B -C --aiprofile" opts_stream="--stream-flags" opts_rolestack="--list-rolestack --rolestack-push" opts_output="--odriver --odevice -o -O -oO -oP -oN --list-driver" opts_source="--source -s -S -sO -sP -sN --list-sources" opts_mixer="-m --mixer -M -mO -mN -mP --list-mixers" opts_cf="--list-cf" opts_midi="--midi-no-console --midi-console-enable --midi-console --ssynth-enable --ssynth-disable" opts_light="--light-channels" opts_rdtcs="--rds-pi --rds-ps --rds-pty --rds-tp --rds-ct" opts_x11="--x11-display --display" opts_server="--tcp --unix --decnet -t -u -n -4 -6 -64 --port -p --bind -b --sock --proto --proto-dir --proto-rate --proto-bits --proto-codec --proto-chans --list-proto --list-profiles --proto-profile --proto-aiprofile --list-aiprofiles --new-sock --slp --x11 --jumbo-mtu -G -U --no-listen --client-fh --close-fh --standby --auto-standby" opts="$opts_misc $opts_auth $opts_plugins $opts_audio $opts_stream $opts_rolestack $opts_output $opts_source $opts_mixer $opts_cf $opts_midi $opts_light $opts_rdtcs $opts_x11 $opts_server --help" # # Complete the arguments to some of the basic commands. # case "${prev}" in # DIR/FILE: '--chroot') _filedir -d return 0 ;; '--pidfile') _filedir return 0 ;; '--script-postdown') _filedir return 0 ;; '--plugin-load') _filedir return 0 ;; '--authfile-gen'|'--authfile-load') _filedir return 0 ;; # MemLock: '--memlock') COMPREPLY=($(compgen -W "none low medium high nearlyall nearlyallsys allcur all default" -- ${cur})) return 0 ;; # Acclev '--guest-acclev'|'--trust-acclev'|'--authfile-acclev') COMPREPLY=($(compgen -W "none idented conctl guest user pwruser all" -- ${cur})) return 0 ;; '--authfile-type') COMPREPLY=($(compgen -W "roar esd pulse htpasswd xauth" -- ${cur})) return 0 ;; # String: '--location'|'--description') return 0 ;; # Int: '--rate'|'-R'|'--proto-rate') _roar_rate return 0 ;; '--bits'|'-B'|'--proto-bits') _roar_bits return 0 ;; '--chans'|'-C'|'--proto-chans') _roar_channels return 0 ;; '--light-channels') COMPREPLY=($(compgen -W "512 1024 1536 2048 4096 8192" -- ${cur})) return 0 ;; '--jumbo-mtu') _roar_jumbo_mtu return 0 ;; # C=F: '--stream-flags') return 0 ;; # R:A '--rolestack-push') return 0 ;; # driver: '--odriver'|'-o') words=$(roard --list-driver | tail -n +3 | sed 's/^ *//; s/ .*$//') COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; # Source: '--source'|'-s') words=$(roard --list-sources | tail -n +3 | sed 's/^ *//; s/ .*$//') COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; # Device: # FIXME: add support for non file devices '--odevice'|'-O') _filedir return 0 ;; '-S') _filedir return 0 ;; '--midi-console') _filedir return 0 ;; # Options: '-dO') return 0 ;; '-oO') return 0 ;; '-sO') return 0 ;; # RDS: '--rds-pi') return 0 ;; '--rds-ps') return 0 ;; '--rds-pty') return 0 ;; # Mixer: # opts_mixer="-m --mixer -M -mO -mN -mP --list-mixers" '--mixer'|'-m') words=$(roard --list-mixers | tail -n +3 | sed 's/^ *//; s/ .*$//') COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; '-M') _filedir return 0 ;; '-mO') return 0 ;; '-mN') return 0 ;; '-mP') return 0 ;; '--list-mixers') return 0 ;; # X11: '--x11-display'|'--display') return 0 ;; # Port: '--port'|'-p') COMPREPLY=( $( compgen -s $cur ) ) return 0 ;; # Host/Node/File: '--bind'|'-b') COMPREPLY=( $( compgen -A hostname $cur ) "0.0.0.0" ) return 0 ;; '--sock') _filedir return 0 ;; # Proto: '--proto') words=$(roard --list-proto | tail -n +3 | sed 's/^ *//; s/ .*$//') COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; '--proto-profile') words=$(roard --list-profiles | tail -n +3 | sed 's/^ *//; s/ .*$//') COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; '--proto-aiprofile'|'--aiprofile') words=$(roarctl --list-aiprofiles | grep '^Profile Name' | sed 's/^.*: *//') COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; # FH: '--client-fh') words=$(command ls /proc/self/fd 2> /dev/null) COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; '--close-fh') words=$(command ls /proc/self/fd 2> /dev/null) COMPREPLY=($(compgen -W "${words}" -- ${cur})) return 0 ;; # Dir: '--proto-dir') _roar_dir return 0; ;; # Codec: '--proto-codec') _roar_codec return 0; ;; # Time: '--watchdog-time') COMPREPLY=($(compgen -W "1000 2000 3000 5000 10000 20000 25000 640000" -- ${cur})) return 0; ;; *) ;; esac COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 } complete -F _roard roard complete -F _command roarify # vim:ft=sh: #ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/gstreamer0.10/����������������������������������������������������������0000755�0001750�0001750�00000000000�12267553243�016441� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/gstreamer0.10/Makefile��������������������������������������������������0000644�0001750�0001750�00000001200�12072575524�020072� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../Makefile.conf include ../../Makefile.inc include Makefile.conf SLIB=libgstroar.so TARGETS=$(SLIB) OBJS=gstroar.o roarsink.o roarmixer.o #DEFINES = -DDEBUG INCLUDE = -I. -I../include -I../include/libroar CFLAGS += $(DEBUG_g) $(Wall) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) $(GST_CFLAGS) LDFLAGS+= $(DEBUG_g) $(Wall) -L../lib/ $(SHARED) $(LDPATH) $(LIBROAR) $(GST_LIBS) -lgstaudio-0.10 all: $(TARGETS) rm -f ../../lib/${SLIB} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../../lib/ clean: rm -f $(TARGETS) *.o new: clean all libgstroar.so: $(OBJS) $(CC) $(LDFLAGS) -o libgstroar.so $(OBJS) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/gstreamer0.10/gstroar.c�������������������������������������������������0000644�0001750�0001750�00000003277�12264733624�020277� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//gstroar.c: /* GStreamer * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> * Copyright (C) <2003> David A. Schleef <ds@schleef.org> * Copyright (C) <2008-2014> Philipp 'ph3-der-loewe' Schafft * <lion@lion.leolix.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "roarsink.h" #include "roarmixer.h" //#include "gst/gst-i18n-plugin.h" static gboolean plugin_init (GstPlugin * plugin) { if (!gst_roarsink_factory_init (plugin)) return FALSE; if (!gst_roarmixer_factory_init (plugin)) return FALSE; // GST_DEBUG_CATEGORY_INIT (roar_debug, "roar", 0, "RoarAudio elements"); #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); #endif /* ENABLE_NLS */ return TRUE; } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "roaraudio", "RoarAudio Element Plugins", plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/gstreamer0.10/roarmixer.c�����������������������������������������������0000644�0001750�0001750�00000033402�12264733624�020617� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarmixer.c: /* GStreamer * Copyright (C) <2005> Arwed v. Merkatz <v.merkatz@gmx.net> * Copyright (C) <2008-2014> Philipp 'ph3-der-loewe' Schafft * <lion@lion.leolix.org> * * roarmixer.h: an RoarAudio audio mixer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02111-1307, USA. */ #include "roarmixer.h" GST_DEBUG_CATEGORY_EXTERN (roar_debug); #define GST_CAT_DEFAULT roar_debug enum { PROP_DEVICE_NAME = 1 }; static const GstElementDetails gst_roar_mixer_element_details = GST_ELEMENT_DETAILS ("RoarAudio Mixer", "Generic/Audio", "Control sound input and output levels with RoarAudio", "Philipp 'ph3-der-loewe' Schafft <lion@lion.leolix.org>"); GST_BOILERPLATE_WITH_INTERFACE (GstRoarMixerElement, gst_roar_mixer_element, GstElement, GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER, gst_roar_mixer_element); GST_IMPLEMENT_ROAR_MIXER_METHODS (GstRoarMixerElement, gst_roar_mixer_element); static GstStateChangeReturn gst_roar_mixer_element_change_state (GstElement * element, GstStateChange transition); static void gst_roar_mixer_element_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_roar_mixer_element_base_init (gpointer klass) { gst_element_class_set_details (GST_ELEMENT_CLASS (klass), &gst_roar_mixer_element_details); } static void gst_roar_mixer_element_class_init (GstRoarMixerElementClass * klass) { GstElementClass *element_class; GObjectClass *gobject_class; element_class = (GstElementClass *) klass; gobject_class = (GObjectClass *) klass; gobject_class->get_property = gst_roar_mixer_element_get_property; g_object_class_install_property (gobject_class, PROP_DEVICE_NAME, g_param_spec_string ("device-name", "Device name", "Human-readable name of the sound device", "", G_PARAM_READABLE)); element_class->change_state = GST_DEBUG_FUNCPTR (gst_roar_mixer_element_change_state); } static void gst_roar_mixer_element_init (GstRoarMixerElement * this, GstRoarMixerElementClass * g_class) { this->mixer = NULL; } static void gst_roar_mixer_element_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstRoarMixerElement *this = GST_ROAR_MIXER_ELEMENT (object); switch (prop_id) { case PROP_DEVICE_NAME: if (this->mixer) { g_value_set_string (value, this->mixer->cardname); } else { g_value_set_string (value, NULL); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static GstStateChangeReturn gst_roar_mixer_element_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; GstRoarMixerElement *this = GST_ROAR_MIXER_ELEMENT (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!this->mixer) { this->mixer = gst_roarmixer_new(NULL, GST_ROAR_MIXER_ALL); } break; default: break; } ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; switch (transition) { case GST_STATE_CHANGE_READY_TO_NULL: if (this->mixer) { gst_roarmixer_free(this->mixer); this->mixer = NULL; } break; default: break; } return ret; } gboolean gst_roarmixer_factory_init (GstPlugin * plugin) { if (!gst_element_register(plugin, "roarmixer", GST_RANK_MARGINAL, GST_TYPE_ROAR_MIXER_ELEMENT)) return FALSE; return TRUE; } G_DEFINE_TYPE (GstRoarMixerTrack, gst_roarmixer_track, GST_TYPE_MIXER_TRACK); GstRoarMixer* gst_roarmixer_new (const gchar *device, GstRoarMixerDirection dir) { GstRoarMixer *ret = NULL; ROAR_WARN("gst_roarmixer_new(device='%s', dir=0x%.4x) = ?", device, dir); ret = g_new0(GstRoarMixer, 1); ret->device = g_strdup(device); ret->dir = dir; ret->cardname = g_strdup("RoarAudio Default Device"); /* if (!gst_ossmixer_open (ret)) goto error; */ if ( roar_simple_connect(&(ret->con), (char*)device, "gstroarmixer") == -1 ) goto error; ROAR_WARN("gst_roarmixer_new(device='%s', dir=0x%.4x) = %p", device, dir, ret); return ret; error: if (ret) gst_roarmixer_free (ret); ROAR_WARN("gst_roarmixer_new(device='%s', dir=0x%.4x) = NULL // Error?", device, dir); return NULL; } void gst_roarmixer_free (GstRoarMixer *mixer) { g_return_if_fail(mixer != NULL); ROAR_WARN("gst_roarmixer_free(mixer=%p) = ?", mixer); if (mixer->device) { g_free(mixer->device); mixer->device = NULL; } if (mixer->cardname) { g_free(mixer->cardname); mixer->cardname = NULL; } if (mixer->tracklist) { g_list_foreach(mixer->tracklist, (GFunc) g_object_unref, NULL); g_list_free(mixer->tracklist); mixer->tracklist = NULL; } roar_disconnect(&(mixer->con)); g_free (mixer); ROAR_WARN("gst_roarmixer_free(mixer=%p) = (void)", mixer); } /* unused with G_DISABLE_* */ static G_GNUC_UNUSED gboolean gst_roarmixer_contains_track (GstRoarMixer * mixer, GstRoarMixerTrack * roartrack) { const GList *item; if ( mixer == NULL || mixer->tracklist == NULL ) return FALSE; for (item = mixer->tracklist; item != NULL; item = item->next) if (item->data == roartrack) return TRUE; return FALSE; } void gst_roarmixer_updatestreamlist (GstRoarMixer *mixer) { gint i = 0; gint num; gint id[ROAR_STREAMS_MAX]; GstMixerTrack *track; ROAR_WARN("gst_roarmixer_updatestreamlist(mixer=%p) = ? // ########################", mixer); ROAR_WARN("gst_roarmixer_updatestreamlist(mixer=%p): tracklist=%p", mixer, mixer->tracklist); if (mixer->tracklist) { ROAR_WARN("gst_roarmixer_updatestreamlist(mixer=%p) = (void)", mixer); return; } /* if (mixer->tracklist) { g_list_foreach(mixer->tracklist, (GFunc) g_object_unref, NULL); g_list_free(mixer->tracklist); mixer->tracklist = NULL; } */ ROAR_WARN("gst_roarmixer_updatestreamlist(mixer=%p): tracklist=%p", mixer, mixer->tracklist); if ( (num = roar_list_streams(&(mixer->con), id, ROAR_STREAMS_MAX)) == -1 ) { return; } for (i = 0; i < num; i++) { track = gst_roarmixer_track_new(mixer, id[i]); ROAR_WARN("gst_roarmixer_updatestreamlist(mixer=%p): track=%p", mixer, track); if ( track == NULL ) continue; mixer->tracklist = g_list_append(mixer->tracklist, track); } ROAR_WARN("gst_roarmixer_updatestreamlist(mixer=%p): tracklist=%p", mixer, mixer->tracklist); ROAR_WARN("gst_roarmixer_updatestreamlist(mixer=%p) = (void) // ###################", mixer); } const GList* gst_roarmixer_list_tracks (GstRoarMixer * mixer) { ROAR_WARN("gst_roarmixer_list_tracks(mixer=%p) = ?", mixer); gst_roarmixer_updatestreamlist(mixer); ROAR_WARN("gst_roarmixer_list_tracks(mixer=%p) = %p", mixer, mixer->tracklist); return (const GList *) mixer->tracklist; } void gst_roarmixer_set_volume (GstRoarMixer * mixer, GstMixerTrack * track, gint * volumes) { GstRoarMixerTrack *roartrack = GST_ROARMIXER_TRACK(track); int channels; struct roar_mixer_settings m; int mode = ROAR_SET_VOL_ALL; gint i; g_return_if_fail(gst_roarmixer_contains_track(mixer, roartrack)); if ( roar_get_vol(&(mixer->con), roartrack->stream_id, &m, &channels) == -1 ) { ROAR_WARN("gst_roarmixer_get_volume(*): can not get mixer infos for stream %i", roartrack->stream_id); return; } if ( channels != track->num_channels ) { ROAR_WARN("gst_roarmixer_get_volume(*): numer of channels for stream %i mismatch (local: %i, server: %i)", roartrack->stream_id, (int)track->num_channels, channels); if ( track->num_channels < channels ) channels = track->num_channels; mode = ROAR_SET_VOL_UNMAPPED; } for (i = 0; i < channels; i++) { m.mixer[i] = volumes[i]; } m.scale = 65535; _LIBROAR_IGNORE_RET(roar_set_vol(&(mixer->con), roartrack->stream_id, &m, channels, mode)); } void gst_roarmixer_get_volume (GstRoarMixer * mixer, GstMixerTrack * track, gint * volumes) { GstRoarMixerTrack *roartrack = GST_ROARMIXER_TRACK(track); int channels; struct roar_mixer_settings m; gint i; g_return_if_fail(gst_roarmixer_contains_track(mixer, roartrack)); if ( roar_get_vol(&(mixer->con), roartrack->stream_id, &m, &channels) == -1 ) { ROAR_WARN("gst_roarmixer_get_volume(*): can not get mixer infos for stream %i", roartrack->stream_id); return; } if ( channels != track->num_channels ) { ROAR_WARN("gst_roarmixer_get_volume(*): numer of channels for stream %i mismatch", roartrack->stream_id); if ( track->num_channels < channels ) channels = track->num_channels; } for (i = 0; i < channels; i++) { if ( m.scale == 65535 ) { volumes[i] = m.mixer[i]; } else { volumes[i] = m.mixer[i] * 65535. / (float) m.scale; // we do not hanle precides scaling here // as it does not matter: // we never write those values back to roard. } } } void gst_roarmixer_set_record (GstRoarMixer * mixer, GstMixerTrack * track, gboolean record) { } void gst_roarmixer_set_mute (GstRoarMixer * mixer, GstMixerTrack * track, gboolean mute) { GstRoarMixerTrack *roartrack = GST_ROARMIXER_TRACK(track); struct roar_stream s; g_return_if_fail(gst_roarmixer_contains_track(mixer, roartrack)); roar_stream_new_by_id(&s, roartrack->stream_id); if (mute) { _LIBROAR_IGNORE_RET(roar_stream_set_flags(&(mixer->con), &s, ROAR_FLAG_MUTE, ROAR_SET_FLAG)); } else { _LIBROAR_IGNORE_RET(roar_stream_set_flags(&(mixer->con), &s, ROAR_FLAG_MUTE, ROAR_RESET_FLAG)); } } // tracks: #define MASK_BIT_IS_SET(mask, bit) \ (mask & (1 << bit)) static void gst_roarmixer_track_class_init (GstRoarMixerTrackClass * klass) { /* nop */ } static void gst_roarmixer_track_init (GstRoarMixerTrack * track) { //memset(track, 0, sizeof(*track)); track->stream_id = -1; ROAR_WARN("gst_roarmixer_track_init(track=%p) = (void)", track); } GstMixerTrack * gst_roarmixer_track_new (GstRoarMixer * mixer, gint stream_id) { GstRoarMixerTrack *roartrack; GstMixerTrack *track; struct roar_stream s; struct roar_client c; struct roar_meta m; gint flags = 0; gchar buf[1024]; int num; int id[ROAR_CLIENTS_MAX]; char * clientname = NULL; char * metaname = NULL; char streamname[1024] = {0}; gint i, h; ROAR_WARN("gst_roarmixer_track_new(mixer=%p, stream_id=%i) = ?", mixer, stream_id); if ( roar_get_stream(&(mixer->con), &s, stream_id) == -1 ) { return NULL; } // TODO: find something more efficent: if ( (num = roar_list_clients(&(mixer->con), id, ROAR_CLIENTS_MAX)) != -1 ) { for (i = 0; i < num; i++) { ROAR_DBG("gst_roarmixer_track_new(*): stream %i -->> client %i?", stream_id, id[i]); if ( roar_get_client(&(mixer->con), &c, id[i]) != -1 ) { for (h = 0; h < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; h++) { ROAR_DBG("gst_roarmixer_track_new(*): stream %i <-> %i -->> client %i?", stream_id, c.streams[h], id[i]); if ( c.streams[h] == stream_id ) { clientname = c.name; h = ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i = num; } } } } } m.type = ROAR_META_TYPE_TITLE; if ( roar_stream_meta_get(&(mixer->con), &s, &m) != -1 ) { metaname = m.value; } if ( roar_stream_get_name(&(mixer->con), &s, streamname, 1024) != 0 ) *streamname = 0; switch (s.dir) { case ROAR_DIR_PLAY: flags |= GST_MIXER_TRACK_OUTPUT; break; case ROAR_DIR_MIXING: flags |= GST_MIXER_TRACK_OUTPUT; break; case ROAR_DIR_OUTPUT: flags |= GST_MIXER_TRACK_MASTER; case ROAR_DIR_MONITOR: flags |= GST_MIXER_TRACK_OUTPUT; break; default: return NULL; } #if 0 if ( !*streamname && metaname == NULL ) sprintf(streamname, "[Stream %i]", stream_id); sprintf(buf, "%s\n%s", clientname ? clientname : "[Unknown]", *streamname ? streamname : metaname ); #else if ( *streamname ) { strcpy(buf, streamname); } else { sprintf(buf, "Stream %i/%s", stream_id, clientname); } #endif roartrack = g_object_new(GST_TYPE_ROARMIXER_TRACK, NULL); ROAR_WARN("gst_roarmixer_track_new(*): roartrack=%p", roartrack); track = GST_MIXER_TRACK(roartrack); track->label = g_strdup(buf); track->num_channels = s.info.channels; track->flags = flags; track->min_volume = 0; track->max_volume = 65535; roartrack->stream_id = stream_id; /* volume */ ROAR_WARN("gst_roarmixer_track_new(mixer=%p, stream_id=%i) = %p", mixer, stream_id, track); return track; } //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/gstreamer0.10/roarmixer.h�����������������������������������������������0000644�0001750�0001750�00000026647�12264733624�020641� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarmixer.h: /* GStreamer * Copyright (C) <2005> Arwed v. Merkatz <v.merkatz@gmx.net> * Copyright (C) <2008-2014> Philipp 'ph3-der-loewe' Schafft * <lion@lion.leolix.org> * * roarmixer.h: an RoarAudio audio mixer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02111-1307, USA. */ #ifndef __GST_ROARMIXER_H__ #define __GST_ROARMIXER_H__ #include <gst/gst.h> #include <gst/interfaces/mixer.h> #include <roaraudio.h> #define VERSION "0.0.1" #define PACKAGE "gst-plugins" #define GST_PACKAGE_ORIGIN "Unknown package origin" #define GST_PACKAGE_NAME "GStreamer Plug-ins source release" G_BEGIN_DECLS #define GST_ROAR_MIXER_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ROAR_MIXER_ELEMENT,GstRoarMixerElement)) #define GST_ROAR_MIXER_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ROAR_MIXER_ELEMENT,GstRoarMixerElementClass)) #define GST_IS_ROAR_MIXER_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ROAR_MIXER_ELEMENT)) #define GST_IS_ROAR_MIXER_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ROAR_MIXER_ELEMENT)) #define GST_TYPE_ROAR_MIXER_ELEMENT (gst_roar_mixer_element_get_type()) #define GST_TYPE_ROARMIXER_TRACK \ (gst_roarmixer_track_get_type ()) #define GST_ROARMIXER_TRACK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ROARMIXER_TRACK, \ GstRoarMixerTrack)) #define GST_ROARMIXER_TRACK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_ROARMIXER_TRACK, \ GstRoarMixerTrackClass)) #define GST_IS_ROARMIXER_TRACK(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_ROARMIXER_TRACK)) #define GST_IS_ROARMIXER_TRACK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_ROARMIXER_TRACK)) typedef struct _GstRoarMixerElement GstRoarMixerElement; typedef struct _GstRoarMixerElementClass GstRoarMixerElementClass; typedef struct _GstRoarMixer GstRoarMixer; struct _GstRoarMixerElement { GstElement parent; GstRoarMixer *mixer; }; struct _GstRoarMixerElementClass { GstElementClass parent; }; GType gst_roar_mixer_element_get_type (void); typedef enum { GST_ROAR_MIXER_CAPTURE = 1<<0, GST_ROAR_MIXER_PLAYBACK = 1<<1, GST_ROAR_MIXER_ALL = GST_ROAR_MIXER_CAPTURE | GST_ROAR_MIXER_PLAYBACK } GstRoarMixerDirection; #define GST_ROAR_MIXER(obj) ((GstRoarMixer*)(obj)) struct _GstRoarMixer { GList * tracklist; /* list of available tracks */ struct roar_connection con; int fd; gchar *host; gchar * device; gchar * cardname; GstRoarMixerDirection dir; }; typedef struct _GstRoarMixerTrack { GstMixerTrack parent; struct roar_mixer_settings mixer; gint channels; gchar * name; gint stream_id; } GstRoarMixerTrack; typedef struct _GstRoarMixerTrackClass { GstMixerTrackClass parent; } GstRoarMixerTrackClass; GType gst_roarmixer_get_type(void); gboolean gst_roarmixer_factory_init (GstPlugin *plugin); GstRoarMixer* gst_roarmixer_new (const gchar *device, GstRoarMixerDirection dir); void gst_roarmixer_free (GstRoarMixer *mixer); void gst_roarmixer_updatestreamlist (GstRoarMixer *mixer); const GList* gst_roarmixer_list_tracks (GstRoarMixer * mixer); void gst_roarmixer_set_volume (GstRoarMixer * mixer, GstMixerTrack * track, gint * volumes); void gst_roarmixer_get_volume (GstRoarMixer * mixer, GstMixerTrack * track, gint * volumes); void gst_roarmixer_set_record (GstRoarMixer * mixer, GstMixerTrack * track, gboolean record); void gst_roarmixer_set_mute (GstRoarMixer * mixer, GstMixerTrack * track, gboolean mute); GType gst_roarmixer_track_get_type (void); GstMixerTrack * gst_roarmixer_track_new (GstRoarMixer * mixer, gint stream_id); #define GST_IMPLEMENT_ROAR_MIXER_METHODS(Type, interface_as_function) \ static gboolean \ interface_as_function ## _supported (Type *this, GType iface_type) \ { \ g_assert (iface_type == GST_TYPE_MIXER); \ \ return (this->mixer != NULL); \ } \ \ static const GList* \ interface_as_function ## _list_tracks (GstMixer * mixer) \ { \ Type *this = (Type*) mixer; \ \ g_return_val_if_fail (this != NULL, NULL); \ g_return_val_if_fail (this->mixer != NULL, NULL); \ \ return gst_roarmixer_list_tracks (this->mixer); \ } \ \ static void \ interface_as_function ## _set_volume (GstMixer * mixer, GstMixerTrack * track, \ gint * volumes) \ { \ Type *this = (Type*) mixer; \ \ g_return_if_fail (this != NULL); \ g_return_if_fail (this->mixer != NULL); \ \ gst_roarmixer_set_volume (this->mixer, track, volumes); \ } \ \ static void \ interface_as_function ## _get_volume (GstMixer * mixer, GstMixerTrack * track, \ gint * volumes) \ { \ Type *this = (Type*) mixer; \ \ g_return_if_fail (this != NULL); \ g_return_if_fail (this->mixer != NULL); \ \ gst_roarmixer_get_volume (this->mixer, track, volumes); \ } \ \ static void \ interface_as_function ## _set_record (GstMixer * mixer, GstMixerTrack * track, \ gboolean record) \ { \ Type *this = (Type*) mixer; \ \ g_return_if_fail (this != NULL); \ g_return_if_fail (this->mixer != NULL); \ \ gst_roarmixer_set_record (this->mixer, track, record); \ } \ \ static void \ interface_as_function ## _set_mute (GstMixer * mixer, GstMixerTrack * track, \ gboolean mute) \ { \ Type *this = (Type*) mixer; \ \ g_return_if_fail (this != NULL); \ g_return_if_fail (this->mixer != NULL); \ \ gst_roarmixer_set_mute (this->mixer, track, mute); \ } \ \ static void \ interface_as_function ## _interface_init (GstMixerClass * klass) \ { \ GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE; \ \ /* set up the interface hooks */ \ klass->list_tracks = interface_as_function ## _list_tracks; \ klass->set_volume = interface_as_function ## _set_volume; \ klass->get_volume = interface_as_function ## _get_volume; \ klass->set_mute = interface_as_function ## _set_mute; \ klass->set_record = interface_as_function ## _set_record; \ } G_END_DECLS #endif /* __GST_ROARMIXER_H__ */ �����������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/gstreamer0.10/roarsink.c������������������������������������������������0000644�0001750�0001750�00000037036�12264733625�020447� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarsink.c: /* GStreamer * Copyright (C) <2005> Arwed v. Merkatz <v.merkatz@gmx.net> * Copyright (C) <2008-2014> Philipp 'ph3-der-loewe' Schafft * <lion@lion.leolix.org> * * Roughly based on the gstreamer 0.8 esdsink plugin: * Copyright (C) <2001> Richard Boulton <richard-gst@tartarus.org> * * roarsink.c: an RoarAudio audio sink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "roarsink.h" #include <unistd.h> #include <errno.h> #define _(x) (x) //#include <gst/gst-i18n-plugin.h> #ifndef ROAR_MAX_WRITE_SIZE #define ROAR_MAX_WRITE_SIZE (21 * 4096) #endif #define ROAR_BUF_SIZE 1764 /* this is dynamic for RoarAudio, use the most common value here for the moment */ //GST_DEBUG_CATEGORY_EXTERN (roar_debug); //#define GST_CAT_DEFAULT roar_debug /* elementfactory information */ static const GstElementDetails roarsink_details = GST_ELEMENT_DETAILS("RoarAudio audio sink", "Sink/Audio", "Plays audio to an RoarAudio server", "Philipp 'ph3-der-loewe' Schafft <lion@lion.leolix.org>"); enum { PROP_0, PROP_HOST, PROP_ROLE, PROP_VOLUME, PROP_MUTE }; #define _QM(x) #x #define QM(x) _QM(x) static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS( "audio/x-alaw, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, " QM(ROAR_MAX_CHANNELS) " ]; " "audio/x-mulaw, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, " QM(ROAR_MAX_CHANNELS) " ]; " // "audio/x-flac; " "audio/x-gsm; " // "application/ogg; " // "audio/x-wav; " /* "audio/x-raw-int, " "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, " "signed = (boolean) { true, false }, " "width = (int) 32, " "depth = (int) 32, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, " QM(ROAR_MAX_CHANNELS) " ]; " */ /* "audio/x-raw-int, " "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, " "signed = (boolean) { true, false }, " "width = (int) 24, " "depth = (int) 24, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, " QM(ROAR_MAX_CHANNELS) " ]; " */ "audio/x-raw-int, " "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, " "signed = (boolean) { true, false }, " "width = (int) 16, " "depth = (int) 16, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, " QM(ROAR_MAX_CHANNELS) " ]; " "audio/x-raw-int, " "signed = (boolean) { true, false }, " "width = (int) 8, " "depth = (int) 8, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, " QM(ROAR_MAX_CHANNELS) " ]" ) ); #undef _QM #undef QM static void gst_roarsink_finalize (GObject * object); static GstCaps *gst_roarsink_getcaps (GstBaseSink * bsink); static gboolean gst_roarsink_open (GstAudioSink * asink); static gboolean gst_roarsink_close (GstAudioSink * asink); static gboolean gst_roarsink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec); static gboolean gst_roarsink_unprepare (GstAudioSink * asink); static guint gst_roarsink_write (GstAudioSink * asink, gpointer data, guint length); static guint gst_roarsink_delay (GstAudioSink * asink); static void gst_roarsink_reset (GstAudioSink * asink); static void gst_roarsink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_roarsink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); GST_BOILERPLATE (GstRoarSink, gst_roarsink, GstAudioSink, GST_TYPE_AUDIO_SINK); static void gst_roarsink_base_init (gpointer g_class) { GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&sink_factory)); gst_element_class_set_details(element_class, &roarsink_details); } static void gst_roarsink_class_init (GstRoarSinkClass * klass) { GObjectClass *gobject_class; GstBaseSinkClass *gstbasesink_class; GstBaseAudioSinkClass *gstbaseaudiosink_class; GstAudioSinkClass *gstaudiosink_class; gobject_class = (GObjectClass *) klass; gstbasesink_class = (GstBaseSinkClass *) klass; gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass; gstaudiosink_class = (GstAudioSinkClass *) klass; parent_class = g_type_class_peek_parent(klass); gobject_class->finalize = gst_roarsink_finalize; gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR(gst_roarsink_getcaps); gstaudiosink_class->open = GST_DEBUG_FUNCPTR(gst_roarsink_open); gstaudiosink_class->close = GST_DEBUG_FUNCPTR(gst_roarsink_close); gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR(gst_roarsink_prepare); gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR(gst_roarsink_unprepare); gstaudiosink_class->write = GST_DEBUG_FUNCPTR(gst_roarsink_write); gstaudiosink_class->delay = GST_DEBUG_FUNCPTR(gst_roarsink_delay); gstaudiosink_class->reset = GST_DEBUG_FUNCPTR(gst_roarsink_reset); gobject_class->set_property = gst_roarsink_set_property; gobject_class->get_property = gst_roarsink_get_property; /* default value is filled in the _init method */ g_object_class_install_property(gobject_class, PROP_HOST, g_param_spec_string("host", "Host", "The server/host running the RoarAudio daemon", NULL, G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_HOST, g_param_spec_string("server", "Server", "The server/host running the RoarAudio daemon", NULL, G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_ROLE, g_param_spec_string("role", "Role", "The stream role", NULL, G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_VOLUME, g_param_spec_float("volume", "Volume", "The stream volume (0.0 to 1.0)", 0.0, 1.0, 1.0, G_PARAM_READWRITE)); g_object_class_install_property(gobject_class, PROP_MUTE, g_param_spec_boolean("mute", "Mute", "The mute state of the stream", FALSE, G_PARAM_READWRITE)); } static void gst_roarsink_init (GstRoarSink * roarsink, GstRoarSinkClass * klass) { roarsink->vss = NULL; roarsink->host = NULL; roarsink->role = NULL; roarsink->volume = -1; roarsink->mute = ROAR_VS_ASK; } static void gst_roarsink_finalize (GObject * object) { GstRoarSink *roarsink = GST_ROARSINK(object); gst_caps_replace(&roarsink->cur_caps, NULL); if ( roarsink->host != NULL ) g_free(roarsink->host); if ( roarsink->role != NULL ) g_free(roarsink->role); G_OBJECT_CLASS(parent_class)->finalize(object); } static GstCaps * gst_roarsink_getcaps (GstBaseSink * bsink) { GstRoarSink *roarsink; roarsink = GST_ROARSINK(bsink); /* no fd, we're done with the template caps */ if (roarsink->vss == NULL || roarsink->cur_caps == NULL) { GST_LOG_OBJECT(roarsink, "getcaps called, returning template caps"); return NULL; } GST_LOG_OBJECT(roarsink, "returning %" GST_PTR_FORMAT, roarsink->cur_caps); return gst_caps_ref(roarsink->cur_caps); } static gboolean gst_roarsink_open(GstAudioSink * asink) { GstPadTemplate *pad_template; GstRoarSink *roarsink; gint i; struct roar_stream oinfo; roarsink = GST_ROARSINK(asink); GST_DEBUG_OBJECT(roarsink, "open"); /* now try to connect to any existing/running sound daemons */ if ( (roarsink->vss = roar_vs_new(roarsink->host, "gstreamer client", NULL)) == NULL ) goto couldnt_connect; if ( roar_server_oinfo(roar_vs_connection_obj(roarsink->vss, NULL), &oinfo, ROAR_DIR_PLAY) == -1 ) goto no_server_info; GST_INFO_OBJECT(roarsink, "got server info rate: %i", oinfo.info.rate); pad_template = gst_static_pad_template_get(&sink_factory); roarsink->cur_caps = gst_caps_copy(gst_pad_template_get_caps(pad_template)); for (i = 0; i < roarsink->cur_caps->structs->len; i++) { GstStructure *s; s = gst_caps_get_structure(roarsink->cur_caps, i); gst_structure_set(s, "rate", G_TYPE_INT, oinfo.info.rate, NULL); } GST_INFO_OBJECT(roarsink, "server caps: %" GST_PTR_FORMAT, roarsink->cur_caps); return TRUE; /* ERRORS */ couldnt_connect: { GST_ELEMENT_ERROR(roarsink, RESOURCE, OPEN_WRITE, (_("Could not establish connection to sound server")), ("can't open connection to RoarAudio server")); return FALSE; } no_server_info: { GST_ELEMENT_ERROR(roarsink, RESOURCE, OPEN_WRITE, (_("Failed to query sound server capabilities")), ("couldn't get server info!")); return FALSE; } } static gboolean gst_roarsink_close (GstAudioSink * asink) { GstRoarSink *roarsink = GST_ROARSINK(asink); GST_DEBUG_OBJECT(roarsink, "close"); gst_caps_replace(&roarsink->cur_caps, NULL); roar_vs_close(roarsink->vss, ROAR_VS_FALSE, NULL); roarsink->vss = NULL; return TRUE; } static gboolean gst_roarsink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) { GstRoarSink *roarsink = GST_ROARSINK(asink); struct roar_audio_info info; info.codec = ROAR_CODEC_DEFAULT; info.bits = spec->depth; info.rate = spec->rate; info.channels = spec->channels; GST_DEBUG_OBJECT(roarsink, "prepare"); GST_INFO_OBJECT(roarsink, "attempting to open data connection to RoarAudio server"); switch (spec->type) { case GST_BUFTYPE_LINEAR: switch (spec->sign) { case TRUE: switch (spec->bigend) { case TRUE: info.codec = ROAR_CODEC_PCM_S_BE; break; case FALSE: info.codec = ROAR_CODEC_PCM_S_LE; break; default: return FALSE; break; } break; case FALSE: switch (spec->bigend) { case TRUE: info.codec = ROAR_CODEC_PCM_U_BE; break; case FALSE: info.codec = ROAR_CODEC_PCM_U_LE; break; default: return FALSE; break; } break; default: return FALSE; break; } break; case GST_BUFTYPE_A_LAW: info.codec = ROAR_CODEC_ALAW; info.bits = 8; break; case GST_BUFTYPE_MU_LAW: info.codec = ROAR_CODEC_MULAW; info.bits = 8; break; case GST_BUFTYPE_GSM: info.codec = ROAR_CODEC_GSM; info.bits = 0; break; default: return FALSE; } if ( roar_vs_stream(roarsink->vss, &info, ROAR_DIR_PLAY, NULL) == -1 ) goto cannot_open; // apply parameters: if ( roarsink->mute != ROAR_VS_ASK && roar_vs_mute(roarsink->vss, roarsink->mute, NULL) == -1 ) { goto cannot_open; } if ( roarsink->volume >= 0.0 && roar_vs_volume_mono(roarsink->vss, roarsink->volume, NULL) == -1 ) { goto cannot_open; } /* get server info */ spec->segsize = ROAR_BUF_SIZE; spec->segtotal = (ROAR_MAX_WRITE_SIZE / spec->segsize); /* FIXME: this is wrong for signed ints (and the * audioringbuffers should do it for us anyway) */ spec->bytes_per_sample = roar_info2framesize(&info) / 8; memset(&(spec->silence_sample), 0, sizeof(spec->silence_sample)); GST_INFO_OBJECT(roarsink, "successfully opened connection to RoarAudio server"); return TRUE; /* ERRORS */ cannot_open: { GST_ELEMENT_ERROR(roarsink, RESOURCE, OPEN_WRITE, (_("Could not establish connection to sound server")), ("can't open connection to RoarAudio server")); return FALSE; } } static gboolean gst_roarsink_unprepare (GstAudioSink * asink) { GstRoarSink *roarsink = GST_ROARSINK(asink); if (roarsink->vss == NULL) return TRUE; roar_vs_close(roarsink->vss, ROAR_VS_FALSE, NULL); roarsink->vss = NULL; GST_INFO_OBJECT(roarsink, "closed sound device"); return TRUE; } static guint gst_roarsink_write (GstAudioSink * asink, gpointer data, guint length) { GstRoarSink *roarsink = GST_ROARSINK(asink); gint to_write = 0; to_write = length; while (to_write > 0) { ssize_t done; done = roar_vs_write(roarsink->vss, data, to_write, NULL); if (done < 0) goto write_error; to_write -= done; data += done; } return length; /* ERRORS */ write_error: { GST_ELEMENT_ERROR(roarsink, RESOURCE, WRITE, ("Failed to write data to the RoarAudio daemon"), GST_ERROR_SYSTEM); return 0; } } static guint gst_roarsink_delay (GstAudioSink * asink) { // GstRoarSink *roarsink = GST_ROARSINK (asink); guint latency; latency = 441; // compile type depending and link level deppendent, // use default value for local operations here for the moment GST_DEBUG_OBJECT(asink, "got latency: %u", latency); return latency; } static void gst_roarsink_reset (GstAudioSink * asink) { GST_DEBUG_OBJECT(asink, "reset called"); } static void gst_roarsink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstRoarSink *roarsink = GST_ROARSINK(object); switch (prop_id) { case PROP_HOST: if ( roarsink->host != NULL ) g_free(roarsink->host); roarsink->host = g_value_dup_string(value); break; case PROP_ROLE: if ( roarsink->role != NULL ) g_free(roarsink->role); roarsink->role = g_value_dup_string(value); break; case PROP_VOLUME: roarsink->volume = (float)g_value_get_float(value); if ( roarsink->vss == NULL ) return; roar_vs_volume_mono(roarsink->vss, roarsink->volume, NULL); break; case PROP_MUTE: if ( g_value_get_boolean(value) ) { roarsink->mute = ROAR_VS_TRUE; } else { roarsink->mute = ROAR_VS_FALSE; } if ( roarsink->vss == NULL ) return; roar_vs_mute(roarsink->vss, roarsink->mute, NULL); break; default: break; } } static void gst_roarsink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstRoarSink *roarsink = GST_ROARSINK(object); float l, r; int ret; switch (prop_id) { case PROP_HOST: g_value_set_string(value, roarsink->host); break; case PROP_ROLE: g_value_set_string(value, roarsink->role); break; case PROP_VOLUME: if ( roarsink->vss == NULL || roar_vs_volume_get(roarsink->vss, &l, &r, NULL) == -1 ) { l = roarsink->volume >= 0.0 ? roarsink->volume : 1.0; } else { l = (l + r)/2; roarsink->volume = l; } g_value_set_float(value, l); break; case PROP_MUTE: if ( roarsink->vss == NULL || (ret = roar_vs_mute(roarsink->vss, ROAR_VS_ASK, NULL)) == -1 ) { ret = roarsink->mute != ROAR_VS_ASK ? roarsink->mute : ROAR_VS_FALSE; } else { roarsink->mute = ret; } g_value_set_boolean(value, ret == ROAR_VS_TRUE ? TRUE : FALSE); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } gboolean gst_roarsink_factory_init (GstPlugin * plugin) { if (!gst_element_register(plugin, "roarsink", GST_RANK_MARGINAL, GST_TYPE_ROARSINK)) return FALSE; return TRUE; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/gstreamer0.10/roarsink.h������������������������������������������������0000644�0001750�0001750�00000004266�12264733625�020453� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//roarsink.h: /* GStreamer * Copyright (C) <2005> Arwed v. Merkatz <v.merkatz@gmx.net> * Copyright (C) <2008-2014> Philipp 'ph3-der-loewe' Schafft * <lion@lion.leolix.org> * * roarsink.h: an RoarAudio audio sink * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02111-1307, USA. */ #ifndef __GST_ROARSINK_H__ #define __GST_ROARSINK_H__ #include <gst/gst.h> #include <gst/audio/gstaudiosink.h> #include <roaraudio.h> #define VERSION "0.0.1" #define PACKAGE "gst-plugins" #define GST_PACKAGE_ORIGIN "Unknown package origin" #define GST_PACKAGE_NAME "GStreamer Plug-ins source release" G_BEGIN_DECLS #define GST_TYPE_ROARSINK \ (gst_roarsink_get_type()) #define GST_ROARSINK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ROARSINK,GstRoarSink)) #define GST_ROARSINK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ROARSINK,GstRoarSinkClass)) #define GST_IS_ROARSINK(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ROARSINK)) #define GST_IS_ROARSINK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ROARSINK)) typedef struct _GstRoarSink GstRoarSink; typedef struct _GstRoarSinkClass GstRoarSinkClass; struct _GstRoarSink { GstAudioSink sink; roar_vs_t * vss; gchar *host; gchar *role; float volume; int mute; GstCaps *cur_caps; }; struct _GstRoarSinkClass { GstAudioSinkClass parent_class; }; GType gst_roarsink_get_type(void); gboolean gst_roarsink_factory_init (GstPlugin *plugin); G_END_DECLS #endif /* __GST_ROARSINK_H__ */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/mplayer/����������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553177�015630� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/mplayer/ao_roar.c�������������������������������������������������������0000644�0001750�0001750�00000010543�12264733626�017415� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//ao_roar.c: /* * ao_roar - RoarAudio audio output driver for MPlayer * * copyright (c) 2002 Juergen Keil <jk@tools.de> * copyright (c) 2008-2014 Philipp 'ph3-der-loewe' Schafft * * This file is part of RoarAudio, based on a file from MPlayer. * * MPlayer is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MPlayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with MPlayer; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <time.h> #ifdef __svr4__ #include <stropts.h> #endif #include <roaraudio.h> #include "config.h" #include "audio_out.h" #include "audio_out_internal.h" #include "libaf/af_format.h" #include "mp_msg.h" #include "help_mp.h" #undef ESD_DEBUG #if ESD_DEBUG #define dprintf(...) printf(__VA_ARGS__) #else #define dprintf(...) /**/ #endif #define ROAR_CLIENT_NAME "MPlayer" static struct roar_connection roar_con; static struct roar_stream roar_stream; static struct roar_stream_info roar_info; static int roar_fh; static ao_info_t info = { "RoarAudio audio output", "roar", "Philipp 'ph3-der-loewe' Schafft <lion@lion.leolix.org>", "" }; LIBAO_EXTERN(roar) /* * to set/get/query special features/parameters */ static int control(int cmd, void *arg) { switch (cmd) { case AOCONTROL_GET_VOLUME: case AOCONTROL_SET_VOLUME: return CONTROL_OK; default: return CONTROL_UNKNOWN; } } /* * open & setup audio device * return: 1=success 0=fail */ static int init(int rate_hz, int channels, int format, int flags) { int codec = ROAR_CODEC_DEFAULT; int bits = 16; if ( roar_simple_connect(&roar_con, NULL, ROAR_CLIENT_NAME) == -1 ) return 0; switch (format) { case AF_FORMAT_S8: bits = 8; break; case AF_FORMAT_U8: bits = 8; codec = ROAR_CODEC_PCM_U_LE; break; } if ( (roar_fh = roar_simple_new_stream_obj(&roar_con, &roar_stream, rate_hz, channels, bits, codec, ROAR_DIR_PLAY)) == -1 ) return 0; if ( roar_stream_get_info(&roar_con, &roar_stream, &roar_info) == -1 ) { close(roar_fh); return 0; } roar_socket_nonblock(roar_fh, ROAR_SOCKET_NONBLOCK); return 1; } /* * close audio device */ static void uninit(int immed) { if ( roar_fh != -1 ) close(roar_fh); roar_fh = -1; roar_disconnect(&roar_con); } /* * plays 'len' bytes of 'data' * it should round it down to outburst*n * return: number of bytes played */ static int play(void* data, int len, int flags) { int pkg = 441*2*2; int ret = 0; int r; while (len > 0) { if ( (r = write(roar_fh, data, pkg < len ? pkg : len)) > 0 ) { len -= r; data += r; ret += r; } else { break; } } // ROAR_WARN("play(*) = %i", ret); return ret; } /* * stop playing, keep buffers (for pause) */ static void audio_pause(void) { /* * not possible with esd. the esd daemom will continue playing * buffered data (not more than ESD_MAX_DELAY seconds of samples) */ } /* * resume playing, after audio_pause() */ static void audio_resume(void) { /* * not possible with esd. * * Let's hope the pause was long enough that the esd ran out of * buffered data; we restart our time based delay computation * for an audio resume. */ } /* * stop playing and empty buffers (for seeking/pause) */ static void reset(void) { } /* * return: how many bytes can be played without blocking */ static int get_space(void) { fd_set sl; struct timeval tv; int r; FD_ZERO(&sl); FD_SET(roar_fh, &sl); tv.tv_sec = 0; tv.tv_usec = 1; if ((r = select(roar_fh + 1, NULL, &sl, NULL, &tv)) > 0) { return roar_info.block_size; } return 0; } /* * return: delay in seconds between first and last sample in buffer */ static float get_delay(void) { return 0.02; } �������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/������������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553177�015266� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/Makefile����������������������������������������������������������0000644�0001750�0001750�00000002226�12214226015�016704� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../Makefile.conf include ../../Makefile.inc TARGETS_PROTO=protocol-irc$(SHARED_SUFFIX) protocol-esound$(SHARED_SUFFIX) protocol-rplay$(SHARED_SUFFIX) protocol-gopher$(SHARED_SUFFIX) TARGETS_DMX=dmx-random$(SHARED_SUFFIX) dmx-waveform$(SHARED_SUFFIX) dmx-strobe$(SHARED_SUFFIX) TARGETS_SERVICE=service-client$(SHARED_SUFFIX) TARGETS_MISC=listenpty$(SHARED_SUFFIX) TARGETS=$(TARGETS_PROTO) $(TARGETS_SERVICE) $(TARGETS_DMX) $(TARGETS_MISC) #DEFINES = -DDEBUG INCLUDE = -I../../include -I../.. CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(SHARED) -L../../lib $(LDPATH) LIBS = $(LIBROAR) all: ${TARGETS} clean: rm -f ${TARGETS} *.o new: clean all install: all cp $(cp_v) ${TARGETS} '$(DESTDIR)$(PREFIX_PLUGINS)/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/roard/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/' semi-install: all sh -c 'set -e; for file in *$(SHARED_SUFFIX); do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_PLUGINS)/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/roard/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/'; done' %$(SHARED_SUFFIX): %.o $(CC) $(LDFLAGS) -o $@ $+ $(LIBS) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/dmx-i2c.c���������������������������������������������������������0000644�0001750�0001750�00000010600�12264733626�016666� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//dmx-i2c.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> #include <sys/ioctl.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #define DEFAULT_DEVICE "/dev/i2c-1" #define DEFAULT_SLAVE 0x58 #define ADDR_COMMAND 2 #define ADDR_BANK 4 #define ADDR_DATA 5 #define COMMAND_DMX 0x3f struct state { size_t startaddr; size_t len; uint8_t slave; struct roar_vio_calls * vio; }; static struct state * g_state; static struct state g_state_init = { .startaddr = 0, .len = 16, .slave = DEFAULT_SLAVE, .vio = NULL }; static inline int __i2c_set_slave(void) { struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SLAVE, .argp = (void*)(int)g_state->slave}; return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); } static inline int __i2c_write(size_t off, const uint8_t value) { union i2c_smbus_data data = {.byte = value}; struct i2c_smbus_ioctl_data args = {.read_write = I2C_SMBUS_WRITE, .command = off, .size = I2C_SMBUS_BYTE_DATA, .data = &data}; struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SMBUS, .argp = &args}; return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); } static inline int __i2c_command(uint8_t command) { return __i2c_write(ADDR_COMMAND, command); } static inline int __i2c_start_dmx(void) { return __i2c_command(COMMAND_DMX); } static inline int __i2c_set_channel(size_t channel, uint8_t value) { size_t bank, offset; bank = channel/32; offset = bank*32; if ( __i2c_write(ADDR_BANK, bank) == -1 ) return -1; return __i2c_write(ADDR_DATA+channel-offset, value); } static int _init (struct roar_dl_librarypara * para) { struct roar_keyval * p; const char * dev = DEFAULT_DEVICE; p = roar_keyval_lookup(para->argv, "startaddr", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->startaddr = atoi(p->value); p = roar_keyval_lookup(para->argv, "len", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->len = atoi(p->value); p = roar_keyval_lookup(para->argv, "slave", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->slave = atoi(p->value); p = roar_keyval_lookup(para->argv, "device", para->argc, 1); if ( p != NULL && p->value != NULL ) dev = p->value; g_state->vio = roar_vio_open_dstr_simple_new(dev, ROAR_VIOF_READWRITE); if ( g_state->vio == NULL ) { ROAR_ERR("_init(para=%p): Can not open device: %s: %s", para, dev, roar_errorstring); return -1; } __i2c_set_slave(); return 0; } static int _free (struct roar_dl_librarypara * para) { (void)para; roar_vio_close(g_state->vio); g_state->vio = NULL; return 0; } static int _update (struct roar_dl_librarypara * para) { size_t i; int val; (void)para; __i2c_start_dmx(); for (i = 0; i < g_state->len; i++) { val = light_dmxchannel_get(g_state->startaddr + i); if ( val < 0 ) continue; __i2c_set_channel(i, val); } return 0; } static struct roar_dl_appsched sched = { .init = _init, .free = _free, .update = _update, .tick = NULL, .wait = NULL }; ROAR_DL_PLUGIN_START(dmx_waveform) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-i2c", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This plugin sends DMX data to RoarAudio DMX Transmitters using I²C"); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); } ROAR_DL_PLUGIN_END //ll ��������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/dmx-random.c������������������������������������������������������0000644�0001750�0001750�00000010035�12264733626�017473� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//dmx-random.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> struct channel { int32_t endsamp; int32_t cursamp; unsigned char startval, endval; }; struct state { size_t startaddr; size_t len; int32_t samples_per_tick; struct channel * channels; }; static struct state * g_state; static struct state g_state_init = { .startaddr = 0, .len = 4, .samples_per_tick = 2, /* default: 2, good for fireflies, for moodlight 8 seems to be a better value */ .channels = NULL }; static void calc_end(size_t index) { if ( g_state->channels[index].cursamp <= g_state->channels[index].endsamp ) return; g_state->channels[index].cursamp = 0; g_state->channels[index].endsamp = (int32_t)1 + (int32_t)roar_random_uint16() * g_state->samples_per_tick; g_state->channels[index].startval = g_state->channels[index].endval; if ( roar_random_uint16() < 32768 ) return; g_state->channels[index].endval = roar_random_uint16() & 0xE0; } static void calc_channel(size_t index) { // trel = cursamp/endsamp double trel = (double)g_state->channels[index].cursamp/(double)g_state->channels[index].endsamp; double valdiff = (double)(g_state->channels[index].endval - g_state->channels[index].startval)*trel; valdiff += (double)g_state->channels[index].startval; light_dmxchannel_set(g_state->startaddr + index, (unsigned char)(unsigned int)(int)valdiff); } static int _init (struct roar_dl_librarypara * para) { struct roar_keyval * p; p = roar_keyval_lookup(para->argv, "startaddr", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->startaddr = atoi(p->value); p = roar_keyval_lookup(para->argv, "len", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->len = atoi(p->value); p = roar_keyval_lookup(para->argv, "samples-per-tick", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->samples_per_tick = atoi(p->value); g_state->channels = roar_mm_malloc(g_state->len*sizeof(struct channel)); if ( g_state->channels == NULL ) return -1; memset(g_state->channels, 0, g_state->len*sizeof(struct channel)); return 0; } static int _free (struct roar_dl_librarypara * para) { (void)para; if ( g_state->channels != NULL ) roar_mm_free(g_state->channels); g_state->channels = NULL; return 0; } static int _update (struct roar_dl_librarypara * para) { size_t i; (void)para; for (i = 0; i < g_state->len; i++) { calc_end(i); calc_channel(i); g_state->channels[i].cursamp += ROAR_OUTPUT_BUFFER_SAMPLES; } return 0; } static struct roar_dl_appsched sched = { .init = _init, .free = _free, .update = _update, .tick = NULL, .wait = NULL }; ROAR_DL_PLUGIN_START(dmx_random) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-random", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This generates random light effects using roard's DMX interface."); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); } ROAR_DL_PLUGIN_END //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/dmx-strobe.c������������������������������������������������������0000644�0001750�0001750�00000011230�12264733627�017510� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//dmx-strobe.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> struct state { // config: ssize_t channel_brightness; ssize_t channel_frequency; ssize_t channel_trigger; uint8_t brightness; uint8_t frequency; // runtime: uint8_t tigger_value; struct roar_subscriber * subscription_event; }; static struct state * g_state; static struct state g_state_init = { .channel_brightness = -1, .channel_frequency = -1, .channel_trigger = -1, .brightness = 255, .frequency = 64, .tigger_value = 0 }; #define __set_XXX(type) \ static void __set_##type (uint8_t val) { \ ROAR_DBG("__set_%s(val=%i): channel=%li", #type, val, (long int)g_state->channel_##type); \ if ( g_state->channel_##type != -1 ) \ light_dmxchannel_set(g_state->channel_##type, val); \ } __set_XXX(brightness) __set_XXX(frequency) __set_XXX(trigger) static void __handle_event(uint8_t event) { switch (event) { case ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_BEAT: g_state->tigger_value += 7; // prime value > 3 for maximum 'random' effect. __set_trigger(g_state->tigger_value); break; case ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_OFF: __set_frequency(0); break; case ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_ON: case ROAR_ROARDMX_EVENT_STROBE|ROAR_ROARDMX_ETYPE_HOLD: __set_brightness(g_state->brightness); __set_frequency(g_state->frequency); break; } } static int _init (struct roar_dl_librarypara * para) { struct roar_keyval * p; p = roar_keyval_lookup(para->argv, "channel-brightness", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->channel_brightness = atoi(p->value); p = roar_keyval_lookup(para->argv, "channel-frequency", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->channel_frequency = atoi(p->value); p = roar_keyval_lookup(para->argv, "channel-trigger", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->channel_trigger = atoi(p->value); p = roar_keyval_lookup(para->argv, "brightness", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->brightness = atoi(p->value); p = roar_keyval_lookup(para->argv, "frequency", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->frequency = atoi(p->value); return 0; } static struct roar_dl_appsched sched = { .init = _init, .free = NULL, .update = NULL, .tick = NULL, .wait = NULL }; static void cb_event(struct roar_notify_core * core, struct roar_event * event, void * userdata) { struct state * old = g_state; (void)core, (void)userdata; g_state = userdata; __handle_event(event->arg0); g_state = old; } static int init(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { struct roar_event event; (void)para, (void)lib; memset(&event, 0, sizeof(event)); event.event = ROAR_DATA_DMX512_EVENT; event.emitter = -1; event.target = -1; event.target_type = ROAR_OT_STREAM; g_state->subscription_event = roar_notify_core_subscribe(NULL, &event, cb_event, g_state); return 0; } static int unload(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; roar_notify_core_unsubscribe(NULL, g_state->subscription_event); return 0; } ROAR_DL_PLUGIN_START(dmx_strobe) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-strobe", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Controls strobes using roard's DMX interface."); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_INIT, init); ROAR_DL_PLUGIN_REG_UNLOAD(unload); } ROAR_DL_PLUGIN_END //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/dmx-waveform.c����������������������������������������������������0000644�0001750�0001750�00000012727�12264733630�020046� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//dmx-waveform.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> #define SAMPLES_PER_TICK 2 struct state { size_t startaddr; size_t len; int stream; struct roar_stream_server * ss; }; static struct state * g_state; static struct state g_state_init = { .startaddr = 0, .len = 4, .stream = -1, .ss = NULL }; static int16_t __get_chanval(struct state * self, size_t c, int pos) { int16_t ret = 0; if ( pos ) { ret = light_dmxchannel_get(self->startaddr + c); } else { if ( self->len & 1 ) { ret = light_dmxchannel_get(self->startaddr + self->len - 1); } else { ret = light_dmxchannel_get(self->startaddr + self->len/2 + c); } } if ( !pos ) ret *= -1; ret *= 127; ROAR_DBG("__get_chanval(self=%p, c=%lu, pos=%i) = %i", self, (long unsigned int)c, pos, (int)ret); return ret; } static ssize_t _vio_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct state * self = vio->inst; ssize_t samplesize = roar_info2samplesize(&(ROAR_STREAM(self->ss)->info)) / 8; ssize_t framesize = roar_info2framesize(&(ROAR_STREAM(self->ss)->info)) / 8; size_t i, c; int16_t * samp = buf; size_t zeros = 0; ROAR_DBG("_vio_read(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (long unsigned int)count); if ( count % framesize ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } framesize *= 2; if ( count % framesize ) { zeros = count % framesize; count -= zeros; memset(buf+count, 0, zeros); } ROAR_DBG("_vio_read(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (long unsigned int)count); for (i = 0; i < count/samplesize;) { for (c = 0; c < ROAR_STREAM(self->ss)->info.channels; c++, i++) samp[i] = __get_chanval(self, c, 1); for (c = 0; c < ROAR_STREAM(self->ss)->info.channels; c++, i++) samp[i] = __get_chanval(self, c, 0); } ROAR_DBG("_vio_read(vio=%p, buf=%p, count=%lu) = %lu", vio, buf, (long unsigned int)count, (long unsigned int)count); return count + zeros; } static int _vio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { (void)vio, (void)data; if ( cmd == ROAR_VIO_CTL_NONBLOCK ) return 0; roar_err_set(ROAR_ERROR_BADRQC); return -1; } static int _vio_close (struct roar_vio_calls * vio) { struct state * self = vio->inst; self->stream = -1; self->ss = NULL; return 0; } static int _init (struct roar_dl_librarypara * para) { struct roar_keyval * p; p = roar_keyval_lookup(para->argv, "startaddr", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->startaddr = atoi(p->value); p = roar_keyval_lookup(para->argv, "len", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->len = atoi(p->value); if ((g_state->stream = streams_new()) == -1 ) return -1; if ( streams_get(g_state->stream, &(g_state->ss)) == -1 ) { streams_delete(g_state->stream); return -1; } if ( streams_set_dir(g_state->stream, ROAR_DIR_PLAY, 1) == -1 ) { streams_delete(g_state->stream); return -1; } if ( streams_set_name(g_state->stream, "DMX to Waveform bridge") == -1 ) { streams_delete(g_state->stream); return -1; } ROAR_STREAM(g_state->ss)->info = *g_sa; if ( g_state->len & 1 ) { ROAR_STREAM(g_state->ss)->info.channels = g_state->len - 1; } else { ROAR_STREAM(g_state->ss)->info.channels = g_state->len / 2; } ROAR_STREAM(g_state->ss)->info.bits = 16; roar_vio_clear_calls(&(g_state->ss->vio)); g_state->ss->vio.inst = g_state; g_state->ss->vio.read = _vio_read; g_state->ss->vio.ctl = _vio_ctl; g_state->ss->vio.close = _vio_close; streams_set_fh(g_state->stream, -2); client_stream_add(g_self_client, g_state->stream); return 0; } static int _free (struct roar_dl_librarypara * para) { (void)para; if ( g_state->stream == -1 ) return 0; if ( streams_reset_flag(g_state->stream, ROAR_FLAG_IMMUTABLE) == -1 ) return -1; if ( streams_delete(g_state->stream) == -1 ) return -1; g_state->stream = -1; return 0; } static struct roar_dl_appsched sched = { .init = _init, .free = _free, .update = NULL, .tick = NULL, .wait = NULL }; ROAR_DL_PLUGIN_START(dmx_waveform) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-waveform", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This renders DMX channels as waveform signals. This is helpful to drive LEDs with cheap PWM based sound devices."); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); } ROAR_DL_PLUGIN_END //ll �����������������������������������������roaraudio-1.0beta11/plugins/roard/listenpty.c�������������������������������������������������������0000644�0001750�0001750�00000004756�12264733630�017470� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//listenpty.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> #if defined(ROAR_HAVE_POSIX_OPENPT) && defined(ROAR_HAVE_GRANTPT) && defined(ROAR_HAVE_UNLOCKPT) && defined(ROAR_HAVE_TCGETATTR) && defined(ROAR_HAVE_TCSETATTR) && defined(ROAR_HAVE_CFMAKERAW) #define __HAVE_SUPPORT #endif #ifdef __HAVE_SUPPORT #include <termios.h> #endif static int init (struct roar_dl_librarypara * para) { #ifdef __HAVE_SUPPORT int serverfh = posix_openpt(O_RDWR|O_NOCTTY); struct termios termios; (void)para; if ( serverfh == -1 ) { ROAR_WARN("Can not open PTY Master: %s", strerror(errno)); return 0; } tcgetattr(serverfh, &termios); cfmakeraw(&termios); tcsetattr(serverfh, TCSANOW, &termios); grantpt(serverfh); unlockpt(serverfh); if ( clients_new_from_fh(serverfh, ROAR_PROTO_ROARAUDIO, ROAR_BYTEORDER_NETWORK, 0) == -1 ) { close(serverfh); return 0; } ROAR_WARN("PTY Slave: %s", ptsname(serverfh)); return 0; #else ROAR_ERR("No PTY Support found so can not load listenpty plugin."); return -1; #endif } static struct roar_dl_appsched sched = { .init = init, .free = NULL, .update = NULL, .tick = NULL, .wait = NULL }; ROAR_DL_PLUGIN_START(listenpty) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("listenpty", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This implements a listen socket using a PTY"); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); } ROAR_DL_PLUGIN_END //ll ������������������roaraudio-1.0beta11/plugins/roard/protocol-esound.c�������������������������������������������������0000644�0001750�0001750�00000043411�12264733630�020560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//emul_esd.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> #ifndef ROAR_WITHOUT_DCOMP_EMUL_ESD #ifdef ROAR_HAVE_H_ESD #include <esd.h> struct emul_esd_command { int cmd; size_t datalen; #if !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_MINIMAL) char name[COMMAND_MAX_NAMELEN]; #else char * name; #endif int (*handler)(int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); }; static int emul_esd_exec_command (int client, int cmd, struct roar_vio_calls * vio); static int emul_esd_check_client (int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara); static int emul_esd_int_read_buf (int client, int * data, void * buf); static int emul_esd_int_write (int client, int data, struct roar_vio_calls * vio); static int emul_esd_test_auth (int client, void * data, struct roar_vio_calls * vio); static int emul_esd_test_byteorder(int client, void * data); static int emul_esd_on_connect (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); static int emul_esd_on_stream (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); static int emul_esd_on_latency (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); static int emul_esd_on_standby (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); static int emul_esd_on_standbymode(int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); static int emul_esd_on_stream_pan (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); static int emul_esd_on_server_info(int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); static int emul_esd_on_all_info (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio); #if !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_MINIMAL) #define _NAME(x) (x) #else #define _NAME(x) ((char*)NULL) #endif #define _cmd_t int #define _INTSIZE sizeof(_cmd_t) #define _NOT_TO_IMPLEMENT NULL #define _UNIMPLEMNTED_IN_ESD NULL #define _NEED_SAMPLE_SUPPORT NULL #define _ROAR2ESD(x) ((x)+1) #define _ESD2ROAR(x) ((x)-1) static struct emul_esd_command g_emul_esd_commands[] = { {ESD_PROTO_CONNECT, ESD_KEY_LEN + _INTSIZE, _NAME("CONNECT"), emul_esd_on_connect}, {ESD_PROTO_LOCK, ESD_KEY_LEN + _INTSIZE, _NAME("LOCK"), NULL}, {ESD_PROTO_UNLOCK, ESD_KEY_LEN + _INTSIZE, _NAME("UNLOCK"), NULL}, {ESD_PROTO_STREAM_PLAY, ESD_NAME_MAX + 2 * _INTSIZE, _NAME("STREAM_PLAY"), emul_esd_on_stream}, {ESD_PROTO_STREAM_REC, ESD_NAME_MAX + 2 * _INTSIZE, _NAME("STREAM_REC"), emul_esd_on_stream}, {ESD_PROTO_STREAM_MON, ESD_NAME_MAX + 2 * _INTSIZE, _NAME("STREAM_MON"), emul_esd_on_stream}, {ESD_PROTO_SAMPLE_CACHE, ESD_NAME_MAX + 3 * _INTSIZE, _NAME("SAMPLE_CACHE"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_SAMPLE_FREE, _INTSIZE, _NAME("SAMPLE_FREE"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_SAMPLE_PLAY, _INTSIZE, _NAME("SAMPLE_PLAY"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_SAMPLE_LOOP, _INTSIZE, _NAME("SAMPLE_LOOP"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_SAMPLE_STOP, _INTSIZE, _NAME("SAMPLE_STOP"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_SAMPLE_KILL, 0 , _NAME("SAMPLE_KILL"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_STANDBY, ESD_KEY_LEN + _INTSIZE, _NAME("STANDBY"), emul_esd_on_standby}, {ESD_PROTO_RESUME, ESD_KEY_LEN + _INTSIZE, _NAME("RESUME"), emul_esd_on_standby}, {ESD_PROTO_SAMPLE_GETID, ESD_NAME_MAX , _NAME("SAMPLE_GETID"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_STREAM_FILT, ESD_NAME_MAX + 2 * _INTSIZE, _NAME("STREAM_FILT"), emul_esd_on_stream}, {ESD_PROTO_SERVER_INFO, _INTSIZE, _NAME("SERVER_INFO"), emul_esd_on_server_info}, {ESD_PROTO_ALL_INFO, _INTSIZE, _NAME("ALL_INFO"), emul_esd_on_all_info}, {ESD_PROTO_SUBSCRIBE, 0 , _NAME("SUBSCRIBE"), _UNIMPLEMNTED_IN_ESD}, {ESD_PROTO_UNSUBSCRIBE, 0 , _NAME("UNSUBSCRIBE"), _UNIMPLEMNTED_IN_ESD}, {ESD_PROTO_STREAM_PAN, 3 * _INTSIZE, _NAME("STREAM_PAN"), emul_esd_on_stream_pan}, {ESD_PROTO_SAMPLE_PAN, 3 * _INTSIZE, _NAME("SAMPLE_PAN"), _NEED_SAMPLE_SUPPORT}, {ESD_PROTO_STANDBY_MODE, _INTSIZE, _NAME("STANDBY_MODE"), emul_esd_on_standbymode}, {ESD_PROTO_LATENCY, 0 , _NAME("LATENCY"), emul_esd_on_latency}, {ESD_PROTO_MAX, 0 , _NAME("MAX"), _NOT_TO_IMPLEMENT}, {-1, 0, _NAME("END OF LIST"), _NOT_TO_IMPLEMENT} }; // command handling: static int emul_esd_exec_command(int client, int cmd, struct roar_vio_calls * vio) { struct emul_esd_command * cur; void * data = NULL; ssize_t ret; size_t done = 0; int r; int i; ROAR_DBG("emul_esd_exec_command(*) = ?"); if ( client == -1 || cmd < ESD_PROTO_CONNECT || cmd > ESD_PROTO_MAX || vio == NULL ) return -1; ROAR_DBG("emul_esd_exec_command(*) = ?"); for (i = 0; (cur = &(g_emul_esd_commands[i]))->cmd != -1; i++) { if ( cur->cmd == cmd ) { if ( cur->datalen > 0 ) { if ( (data = roar_mm_malloc(cur->datalen)) == NULL ) { // we will do a protocol error in case we do not drop the client return -1; } while ( done < cur->datalen ) { ret = roar_vio_read(vio, data+done, cur->datalen-done); if ( ret < 1 ) { roar_mm_free(data); return -1; } else { done += ret; } } } if ( cur->handler == NULL ) { ROAR_WARN("emul_esd_exec_command(client=%i, cmd=%s(%i), vio=%p): client uses unimplemted command", client, cur->name, cmd, vio ); r = -1; } else { r = cur->handler(client, cur, data, vio); } if ( data != NULL ) roar_mm_free(data); return r; } } return -1; } static int emul_esd_set_proto(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; if ( emul_esd_exec_command(client, ESD_PROTO_CONNECT, vio) == -1 ) return -1; return 0; } static int emul_esd_check_client(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { _cmd_t cmd; (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; if ( client == -1 ) return -1; if ( roar_vio_read(vio, &cmd, _INTSIZE) != _INTSIZE ) { // really bad protocol error return -1; } return emul_esd_exec_command(client, cmd, vio); } // porto lib: int emul_esd_int_read_buf (int client, int * data, void * buf) { _cmd_t d; (void)client; if ( data == NULL || buf == NULL ) return -1; d = *(_cmd_t*)buf; *data = d; return 0; } static int emul_esd_int_write (int client, int data, struct roar_vio_calls * vio) { _cmd_t d = data; (void)client; return roar_vio_write(vio, &d, _INTSIZE) == _INTSIZE ? 0 : -1; } static int emul_esd_test_auth (int client, void * data, struct roar_vio_calls * vio) { // accept all clients for the moment. (void)data; return emul_esd_int_write(client, 1, vio); } static int emul_esd_test_byteorder(int client, void * data) { struct roar_client * c; if ( clients_get(client, &c) == -1 ) return -1; // "NDNE"; if ( !memcmp(data, "NDNE", 4) ) { c->byteorder = ROAR_BYTEORDER_LE; } else if ( !memcmp(data, "ENDE", 4) ) { c->byteorder = ROAR_BYTEORDER_BE; } else if ( !memcmp(data, "NEED", 4) ) { c->byteorder = ROAR_BYTEORDER_PDP; } else { return -1; } return 0; } // handler: static int emul_esd_on_connect (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { (void)cmd; ROAR_DBG("emul_esd_on_connect(client=%i, cmd=%p, data=%p, vio=%p) = ?", client, cmd, data, vio); if ( client == -1 || data == NULL || vio == NULL ) return -1; ROAR_DBG("emul_esd_on_connect(client=%i, cmd=%p, data=%p, vio=%p) = ?", client, cmd, data, vio); if ( emul_esd_test_auth(client, data, vio) == -1 ) return -1; ROAR_DBG("emul_esd_on_connect(client=%i, cmd=%p, data=%p, vio=%p) = ?", client, cmd, data, vio); if ( emul_esd_test_byteorder(client, data+ESD_KEY_LEN) == -1 ) return -1; ROAR_DBG("emul_esd_on_connect(client=%i, cmd=%p, data=%p, vio=%p) = ?", client, cmd, data, vio); return 0; } static int emul_esd_on_stream (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { struct roar_stream_server * ss; struct roar_stream * s; struct roar_client * c; int stream; int dir = -1; int esdformat; int rate = 0; if ( client == -1 || cmd == NULL || data == NULL || vio == NULL ) return -1; switch (cmd->cmd) { case ESD_PROTO_STREAM_PLAY: dir = ROAR_DIR_PLAY; break; case ESD_PROTO_STREAM_REC: dir = ROAR_DIR_RECORD; break; case ESD_PROTO_STREAM_MON: dir = ROAR_DIR_MONITOR; break; case ESD_PROTO_STREAM_FILT: dir = ROAR_DIR_FILTER; break; default: return -1; } if ( clients_get(client, &c) == -1 ) { return -1; } ROAR_DBG("emul_esd_on_stream(client=%i, ...): creating stream...", client); if ((stream = streams_new()) == -1 ) { return -1; } ROAR_DBG("emul_esd_on_stream(client=%i, ...): getting stream...", client); if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); return -1; } s = ROAR_STREAM(ss); ROAR_DBG("emul_esd_on_stream(client=%i, ...): set client of stream...", client); if ( client_stream_add(client, stream) == -1 ) { streams_delete(stream); return -1; } emul_esd_int_read_buf(client, &esdformat, data); emul_esd_int_read_buf(client, &rate, data+_INTSIZE); strncpy(c->name, data + 2*_INTSIZE, ROAR_BUFFER_NAME > ESD_NAME_MAX ? ESD_NAME_MAX : ROAR_BUFFER_NAME); c->name[ROAR_BUFFER_NAME-1] = 0; ROAR_DBG("emul_esd_on_stream(*): esdformat=0x%.8X, rate=%i", esdformat, rate); s->info.rate = rate; switch (esdformat & ESD_MASK_BITS) { case ESD_BITS8: s->info.bits = 8; s->info.codec = ROAR_CODEC_PCM_U_LE; break; case ESD_BITS16: s->info.bits = 16; s->info.codec = ROAR_CODEC_DEFAULT; break; default: streams_delete(stream); return -1; } switch (esdformat & ESD_MASK_CHAN) { case ESD_MONO: s->info.channels = 1; break; case ESD_STEREO: s->info.channels = 2; break; default: streams_delete(stream); return -1; } ss->codec_orgi = s->info.codec; ROAR_DBG("emul_esd_on_stream(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec); if ( streams_set_dir(stream, dir, 1) == -1 ) { return -1; } if ( client_stream_exec(client, stream) == -1 ) { return -1; } return 0; } static int emul_esd_on_latency (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { int lag = ROAR_OUTPUT_CFREQ; (void)cmd, (void)data; lag *= 2.0 * 44100.0 / (float)g_sa->rate; return emul_esd_int_write(client, lag, vio); } static int emul_esd_on_standby (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { int ok = 0; if ( emul_esd_test_auth(client, data, vio) == -1 ) { return emul_esd_int_write(client, ok, vio); } ok = 1; if (cmd->cmd == ESD_PROTO_STANDBY) { g_standby = 1; } else { g_standby = 0; } return emul_esd_int_write(client, ok, vio); } static int emul_esd_on_standbymode(int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { int mode = ESM_ERROR; (void)cmd, (void)data; if ( g_standby ) { if ( g_autostandby ) { mode = ESM_ON_AUTOSTANDBY; } else { mode = ESM_ON_STANDBY; } } else { mode = ESM_RUNNING; } return emul_esd_int_write(client, mode, vio); } static int emul_esd_on_stream_pan (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { struct roar_stream_server * ss; int stream = -1; int left = 256, right = 256; int ok = 0; (void)cmd; emul_esd_int_read_buf(client, &stream, data + 0*_INTSIZE); emul_esd_int_read_buf(client, &left, data + 1*_INTSIZE); emul_esd_int_read_buf(client, &right, data + 2*_INTSIZE); stream = _ESD2ROAR(stream); if ( streams_get(stream, &ss) != -1 ) { ss->mixer.scale = 256; ss->mixer.mixer[0] = left; ss->mixer.mixer[1] = right; if ( streams_set_mixer(stream) != -1 ) ok = 1; } return emul_esd_int_write(client, ok, vio); } static int emul_esd_on_server_info(int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { int version = 0; int rate = g_sa->rate; int format = 0; (void)cmd, (void)data; switch (g_sa->bits) { case 8: format |= ESD_BITS8; break; case 16: format |= ESD_BITS16; break; } switch (g_sa->channels) { case 1: format |= ESD_MONO; break; case 2: format |= ESD_STEREO; break; } if ( emul_esd_int_write(client, version, vio) == -1 ) return -1; if ( emul_esd_int_write(client, rate, vio) == -1 ) return -1; if ( emul_esd_int_write(client, format, vio) == -1 ) return -1; return 0; } static int emul_esd_on_all_info (int client, struct emul_esd_command * cmd, void * data, struct roar_vio_calls * vio) { struct roar_stream_server * ss; struct roar_audio_info * info; struct roar_client * c; char name[ESD_NAME_MAX]; char * sname; int id, rate, left, right, format; int i; if ( emul_esd_on_server_info(client, cmd, data, vio) == -1 ) return -1; for (i = 0; i < (ROAR_STREAMS_MAX+2); i++) { memset(name, 0, sizeof(name)); id = rate = format = 0; left = right = 0; if ( i >= ROAR_STREAMS_MAX ) { id = -1; } else { if ( streams_get(i, &ss) == -1 ) continue; switch (streams_get_dir(i)) { case ROAR_DIR_PLAY: format |= ESD_PLAY; break; case ROAR_DIR_MONITOR: format |= ESD_MONITOR; break; case ROAR_DIR_RECORD: format |= ESD_RECORD; break; default: continue; break; } info = &(ROAR_STREAM(ss)->info); id = i; rate = info->rate; switch (info->bits) { case 8: format |= ESD_BITS8; break; case 16: format |= ESD_BITS16; break; } switch (info->channels) { case 1: if ( ss->mixer.mixer[0] == ss->mixer.scale ) { left = right = 256; } else { left = right = ss->mixer.mixer[0] * 256 / ss->mixer.scale; } format |= ESD_MONO; break; case 2: if ( ss->mixer.mixer[0] == ss->mixer.scale ) { left = 256; } else { left = ss->mixer.mixer[0] * 256 / ss->mixer.scale; } if ( ss->mixer.mixer[1] == ss->mixer.scale ) { right = 256; } else { right = ss->mixer.mixer[1] * 256 / ss->mixer.scale; } format |= ESD_STEREO; break; default: left = right = 0; } sname = streams_get_name(id); if ( sname == NULL || sname[0] == 0 ) { if ( clients_get(streams_get_client(id), &c) != -1 ) { sname = c->name; } } if ( sname == NULL || sname[0] == 0 ) sname = "(unknown)"; strncpy(name, sname, sizeof(name) > ROAR_BUFFER_NAME ? ROAR_BUFFER_NAME : sizeof(name)); name[sizeof(name)-1] = 0; } id = _ROAR2ESD(id); if ( emul_esd_int_write(client, id, vio) == -1 ) return -1; if ( roar_vio_write(vio, name, sizeof(name)) != sizeof(name) ) return -1; if ( emul_esd_int_write(client, rate, vio) == -1 ) return -1; if ( emul_esd_int_write(client, left, vio) == -1 ) return -1; if ( emul_esd_int_write(client, right, vio) == -1 ) return -1; if ( emul_esd_int_write(client, format, vio) == -1 ) return -1; if ( i == ROAR_STREAMS_MAX+1) { // write 'length'... if ( emul_esd_int_write(client, id, vio) == -1 ) return -1; } } return 0; } static struct roar_dl_proto __proto_common_esd = { .proto = ROAR_PROTO_ESOUND, .description = "EsounD emulation", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = emul_esd_set_proto, .handle = emul_esd_check_client }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, __proto_common_esd, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_esd) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-esd", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of the Enlightened Sound Daemon's protocol"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END #endif #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/protocol-gopher.c�������������������������������������������������0000644�0001750�0001750�00000060060�12264733631�020547� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//emul_gopher.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> #ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER #include <roaraudio/proto_gopher.h> #define _INFO ROAR_GOPHER_TYPE_INFO #define _DIR ROAR_GOPHER_TYPE_DIR #define _FILE ROAR_GOPHER_TYPE_FILE #define _SOUND ROAR_GOPHER_TYPE_SOUND struct item; static int scb_status_txt (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static int scb_test (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static int scb_clients (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static int scb_streams (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static int scb_client_info(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static int scb_stream_info(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static int scb_listen_menu(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static int scb_listen (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); static struct roar_gopher_menu_item g_gopher_root_menu[] = { {.type = _INFO, .name = "roard Root Menu"}, {.type = _FILE, .name = "Server Info", .selector = "/info.txt", .host = NULL, .port = 0}, {.type = _FILE, .name = "Server Status", .selector = "/status.txt", .host = NULL, .port = 0}, {.type = _DIR, .name = "Clients", .selector = "/clients/", .host = NULL, .port = 0}, {.type = _DIR, .name = "Streams", .selector = "/streams/", .host = NULL, .port = 0}, {.type = _DIR, .name = "Listen!", .selector = "/listen/", .host = NULL, .port = 0}, }; // need a true constant string. #define info_text \ "This server is RoarAudio server (roard) with a small status gopher server\n" \ "integrated. (For version and stuff see /status.txt.)\n" \ "RoarAudio is a modern, multi OS, networed sound system.\n" \ "For more information see http://roaraudio.keep-cool.org/\n" static struct item { const char * selector; char type; struct roar_gopher_menu menu; struct roar_audio_info info; int dir; const char * text; int (*cb)(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara); } g_gopher_items[] = { {.selector = "", .type = _DIR, .menu = {.items = g_gopher_root_menu, .items_len = sizeof(g_gopher_root_menu)/sizeof(*g_gopher_root_menu)}, .cb = NULL }, // and again as selector '/' as some clients seems to require it: {.selector = "/", .type = _DIR, .menu = {.items = g_gopher_root_menu, .items_len = sizeof(g_gopher_root_menu)/sizeof(*g_gopher_root_menu)}, .cb = NULL }, {.selector = "/info.txt", .type = _FILE, .text = info_text, .cb = NULL}, {.selector = "/status.txt", .type = _FILE, .cb = scb_status_txt}, {.selector = "/test/*", .type = _FILE, .cb = scb_test}, {.selector = "/clients/", .type = _DIR, .cb = scb_clients}, {.selector = "/streams/", .type = _DIR, .cb = scb_streams}, {.selector = "/clients/*/", .type = _DIR, .cb = scb_client_info}, {.selector = "/streams/*/", .type = _DIR, .cb = scb_stream_info}, {.selector = "/listen/", .type = _DIR, .cb = scb_listen_menu}, {.selector = "/listen/*/*/*/*/*", .type = _FILE, .cb = scb_listen} }; static char * _aprintf(size_t sizehint, const char * format, ...); static int send_menu (int client, struct roar_gopher_menu * menu, struct roar_vio_calls * vio, struct roar_buffer ** obuffer); static int send_text (const char * text, struct roar_buffer ** obuffer); // SCBs: static int scb_status_txt (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { const size_t len = 1024; (void)client, (void)vio, (void)selector, (void)text, (void)sitem, (void)obuffer; *text = roar_mm_malloc(len); if ( *text == NULL ) return -1; **text = 0; snprintf(*text, len, "Host application: %s\r\n" "Host ABI: %s\r\n" "Server location: %s\r\n" "Server description: %s\r\n" "\r\n" "Counters current: %" LIBROAR__ll "u clients, %" LIBROAR__ll "u streams\r\n" "Counters sum: %" LIBROAR__ll "u clients, %" LIBROAR__ll "u streams\r\n", pluginpara->appname == NULL ? "***unknown***" : pluginpara->appname, pluginpara->abiversion == NULL ? "***unknown***" : pluginpara->abiversion, g_config->location, g_config->description, (LIBROAR__longlong unsigned int)g_counters.cur.clients, (LIBROAR__longlong unsigned int)g_counters.cur.streams, (LIBROAR__longlong unsigned int)g_counters.sum.clients, (LIBROAR__longlong unsigned int)g_counters.sum.streams ); (*text)[len-1] = 0; return 0; } static int scb_test(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { ssize_t toks; char * tok; size_t len; (void)client, (void)vio, (void)obuffer, (void)pluginpara; toks = roar_mm_strseltok(sitem->selector, selector, &tok, 1); if ( toks == -1 ) return -1; len = strlen(tok); len += 64; *text = roar_mm_malloc(len); if ( *text == NULL ) return -1; **text = 0; snprintf(*text, len, "Your text was: %s", tok); (*text)[len-1] = 0; return 0; } static int scb_clients (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { struct roar_gopher_menu_item items[ROAR_CLIENTS_MAX]; struct roar_gopher_menu menu = {.flags = 0, .items = items, .items_len = 0}; struct roar_gopher_menu_item * item; struct roar_client_server * cs; struct roar_client * c; const size_t len = 80; char * d; size_t i; int ret; (void)selector, (void)text, (void)sitem, (void)pluginpara; memset(items, 0, sizeof(items)); for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( (c = ROAR_CLIENT((cs = g_clients[i]))) != NULL ) { item = &(items[menu.items_len++]); item->type = _DIR; d = roar_mm_malloc(len); if ( d == NULL ) { menu.items_len--; continue; } if ( c->name != NULL && c->name[0] != 0 ) { snprintf(d, len, "Client %i: %s", (int)i, c->name); } else { snprintf(d, len, "Client %i", (int)i); } item->name = d; d = roar_mm_malloc(len); if ( d == NULL ) { if ( item->name != NULL ) roar_mm_free((void*)item->name); menu.items_len--; continue; } snprintf(d, len, "/clients/%i/", (int)i); item->selector = d; } } ret = send_menu(client, &menu, vio, obuffer); for (i = 0; i < menu.items_len; i++) { if ( items[i].name != NULL ) roar_mm_free((void*)items[i].name); if ( items[i].selector != NULL ) roar_mm_free((void*)items[i].selector); } return ret; } static int scb_streams (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { struct roar_gopher_menu_item items[ROAR_STREAMS_MAX]; struct roar_gopher_menu menu = {.flags = 0, .items = items, .items_len = 0}; struct roar_gopher_menu_item * item; struct roar_stream_server * ss; struct roar_stream * s; const size_t len = 80; char * d; size_t i; int ret; (void)selector, (void)text, (void)sitem, (void)pluginpara; memset(items, 0, sizeof(items)); for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (s = ROAR_STREAM((ss = g_streams[i]))) != NULL ) { item = &(items[menu.items_len++]); item->type = _DIR; d = roar_mm_malloc(len); if ( d == NULL ) { menu.items_len--; continue; } if ( ss->name != NULL && ss->name[0] != 0 ) { snprintf(d, len, "Stream %i: %s", (int)i, ss->name); } else { snprintf(d, len, "Stream %i", (int)i); } item->name = d; d = roar_mm_malloc(len); if ( d == NULL ) { if ( item->name != NULL ) roar_mm_free((void*)item->name); menu.items_len--; continue; } snprintf(d, len, "/streams/%i/", (int)i); item->selector = d; } } ret = send_menu(client, &menu, vio, obuffer); for (i = 0; i < menu.items_len; i++) { if ( items[i].name != NULL ) roar_mm_free((void*)items[i].name); if ( items[i].selector != NULL ) roar_mm_free((void*)items[i].selector); } return ret; } static int scb_client_info(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { #define _MAX_ITEMS (16 + ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT) struct roar_gopher_menu_item items[_MAX_ITEMS]; struct roar_gopher_menu menu = {.flags = 0, .items = items, .items_len = 0}; struct roar_gopher_menu_item * item; struct roar_client_server * cs; struct roar_client * c; size_t i; int ret; ssize_t toks; char * tok; int id; char tmp[80]; (void)text, (void)pluginpara; memset(items, 0, sizeof(items)); toks = roar_mm_strseltok(sitem->selector, selector, &tok, 1); if ( toks == -1 ) return -1; id = atoi(tok); if ( clients_get_server(id, &cs) == -1 ) return -1; c = ROAR_CLIENT(cs); item = &(items[menu.items_len++]); item->type = _INFO; if ( c->name != NULL && c->name[0] != 0 ) { item->name = _aprintf(64, "Client %i: %s", id, c->name); } else { item->name = _aprintf(64, "Client %i", id); } if ( roar_nnode_get_socktype(&(c->nnode)) != ROAR_SOCKET_TYPE_UNKNOWN ) { if ( roar_nnode_to_str(&(c->nnode), tmp, sizeof(tmp)) == 0 ) { item = &(items[menu.items_len++]); item->type = _INFO; item->name = _aprintf(64, "Network node: %s", tmp); } } item = &(items[menu.items_len++]); item->type = _INFO; item->name = _aprintf(64, "Protocol: %s", roar_proto2str(c->proto)); if ( c->execed != -1 ) { item = &(items[menu.items_len++]); item->type = _DIR; item->name = _aprintf(64, "Exected Stream: %i", c->execed); item->selector = _aprintf(64, "/streams/%i/", c->execed); } for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) { if ( c->streams[i] != -1 ) { item = &(items[menu.items_len++]); item->type = _DIR; item->name = _aprintf(64, "Stream: %i", c->streams[i]); item->selector = _aprintf(64, "/streams/%i/", c->streams[i]); } } ret = send_menu(client, &menu, vio, obuffer); for (i = 0; i < menu.items_len; i++) { if ( items[i].name != NULL ) roar_mm_free((void*)items[i].name); if ( items[i].selector != NULL ) roar_mm_free((void*)items[i].selector); } #undef _MAX_ITEMS return ret; } static int scb_stream_info(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { #define _MAX_ITEMS 12 struct roar_gopher_menu_item items[_MAX_ITEMS]; struct roar_gopher_menu menu = {.flags = 0, .items = items, .items_len = 0}; struct roar_gopher_menu_item * item; struct roar_stream_server * ss; struct roar_stream * s; size_t i; int ret; ssize_t toks; char * tok; int id; (void)text, (void)pluginpara; memset(items, 0, sizeof(items)); toks = roar_mm_strseltok(sitem->selector, selector, &tok, 1); if ( toks == -1 ) return -1; id = atoi(tok); if ( streams_get(id, &ss) == -1 ) return -1; s = ROAR_STREAM(ss); item = &(items[menu.items_len++]); item->type = _INFO; if ( ss->name != NULL && ss->name[0] != 0 ) { item->name = _aprintf(64, "Stream %i: %s", id, ss->name); } else { item->name = _aprintf(64, "Stream %i", id); } item = &(items[menu.items_len++]); item->type = _INFO; item->name = _aprintf(64, "Stream state: %s", roar_streamstate2str(ss->state)); item = &(items[menu.items_len++]); item->type = _INFO; item->name = _aprintf(64, "Stream direction: %s", roar_dir2str(s->dir)); item = &(items[menu.items_len++]); item->type = _INFO; item->name = _aprintf(128, "Signal info: rate:%iHz bits:%i channels:%i codec:%s", s->info.rate, s->info.bits, s->info.channels, roar_codec2str(s->info.codec)); if ( ss->codec_orgi != ROAR_AUDIO_INFO_INVALID && ss->codec_orgi != s->info.codec ) { item = &(items[menu.items_len++]); item->type = _INFO; item->name = _aprintf(64, "Streamed codec: %s", roar_codec2str(ss->codec_orgi)); } if ( ss->role != -1 ) { item = &(items[menu.items_len++]); item->type = _INFO; item->name = _aprintf(64, "Stream role: %s", roar_role2str(ss->role)); } item = &(items[menu.items_len++]); item->type = _DIR; item->name = _aprintf(64, "Client: %i", ss->client); item->selector = _aprintf(64, "/clients/%i/", ss->client); ret = send_menu(client, &menu, vio, obuffer); for (i = 0; i < menu.items_len; i++) { if ( items[i].name != NULL ) roar_mm_free((void*)items[i].name); if ( items[i].selector != NULL ) roar_mm_free((void*)items[i].selector); } #undef _MAX_ITEMS return ret; } static int scb_listen_menu(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { #define _MAX_ITEMS 12 struct roar_gopher_menu_item items[_MAX_ITEMS]; struct roar_gopher_menu menu = {.flags = 0, .items = items, .items_len = 0}; struct roar_gopher_menu_item * item; const char * codec; int ret; int codecs[] = {ROAR_CODEC_DEFAULT, ROAR_CODEC_RIFF_WAVE, ROAR_CODEC_AU, ROAR_CODEC_OGG_VORBIS}; size_t i; (void)selector, (void)text, (void)sitem, (void)pluginpara; memset(items, 0, sizeof(items)); item = &(items[menu.items_len++]); item->type = _INFO; item->name = roar_mm_strdup("Select a format you want to listen in:"); item = &(items[menu.items_len++]); item->type = _INFO; item->name = NULL; // empty lion for (i = 0; i < (sizeof(codecs)/sizeof(*codecs)); i++) { item = &(items[menu.items_len++]); item->type = _SOUND; codec = roar_codec2str(codecs[i]); item->name = _aprintf(64, "%u channels with %u bits at %uHz, %s", g_sa->channels, g_sa->bits, g_sa->rate, codec); item->selector = _aprintf(64, "/listen/monitor/%u/%u/%u/%s", g_sa->rate, g_sa->bits, g_sa->channels, codec); } ret = send_menu(client, &menu, vio, obuffer); for (i = 0; i < menu.items_len; i++) { if ( items[i].name != NULL ) roar_mm_free((void*)items[i].name); if ( items[i].selector != NULL ) roar_mm_free((void*)items[i].selector); } #undef _MAX_ITEMS return ret; } static int scb_listen (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { struct roar_stream_server * ss; struct roar_stream * s; struct roar_audio_info info; int dir = -1; ssize_t toks; char * tok[5]; int stream = -1; (void)vio, (void)text, (void)obuffer, (void)pluginpara; toks = roar_mm_strseltok(sitem->selector, selector, tok, 5); if ( toks != 5 ) return -1; memset(&info, 0, sizeof(info)); if ( (dir = roar_str2dir(tok[0])) == -1 ) return -1; // test for unsupported dirs: switch (dir) { case ROAR_DIR_THRU: case ROAR_DIR_RAW_IN: case ROAR_DIR_FILTER: return -1; break; } info.rate = atoi(tok[1]); info.bits = atoi(tok[2]); info.channels = atoi(tok[3]); info.codec = roar_str2codec(tok[4]); if ( info.codec == ROAR_AUDIO_INFO_INVALID ) return -1; if ((stream = streams_new()) == -1 ) return -1; if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); return -1; } s = ROAR_STREAM(ss); if ( client_stream_add(client, stream) == -1 ) { streams_delete(stream); return -1; } memcpy(&(s->info), &info, sizeof(info)); ss->codec_orgi = info.codec; if ( streams_set_dir(stream, dir, 1) == -1 ) { streams_delete(stream); return -1; } if ( client_stream_exec(client, stream) == -1 ) { streams_delete(stream); return -1; } return 0; } // other code: static int strip_nl (char * str) { register char c; for (; (c = *str) != 0; str++) { if ( c == '\r' || c == '\n' ) { *str = 0; return 1; } } return 0; } static char * _aprintf(size_t sizehint, const char * format, ...) { va_list ap; char * buf; int ret; sizehint += 128; if ( (buf = roar_mm_malloc(sizehint)) == NULL ) return NULL; va_start(ap, format); ret = vsnprintf(buf, sizehint, format, ap); va_end(ap); buf[sizehint-1] = 0; return buf; } static int send_menu (int client, struct roar_gopher_menu * menu, struct roar_vio_calls * vio, struct roar_buffer ** obuffer) { struct roar_buffer * buf; struct roar_gopher_menu_item * item; const size_t len = 256; size_t i; void * data; char * chardata; const char * host; unsigned int port; struct roar_sockname sockaddr; (void)client; if ( roar_vio_ctl(vio, ROAR_VIO_CTL_GET_SOCKNAME, &sockaddr) == -1 ) { memset(&sockaddr, 0, sizeof(sockaddr)); } for (i = 0; i < menu->items_len; i++) { item = &(menu->items[i]); if ( roar_buffer_new_data(&buf, len, &data) == -1 ) { if ( sockaddr.addr != NULL ) roar_mm_free(sockaddr.addr); return -1; } chardata = data; switch (item->type) { case _INFO: snprintf(data, len-1, "i%s\tfake\t(NULL)\t0\r\n", item->name == NULL ? "" : item->name); break; default: host = item->host == NULL ? sockaddr.addr : item->host; port = item->port == 0 ? (unsigned int)sockaddr.port : item->port; snprintf(data, len-1, "%c%s\t%s\t%s\t%u\r\n", item->type, item->name, item->selector, host, port); break; } chardata[len-1] = 0; if ( roar_buffer_set_len(buf, strlen(data)) == -1 ) { roar_buffer_free(buf); if ( sockaddr.addr != NULL ) roar_mm_free(sockaddr.addr); return -1; } if ( roar_buffer_moveintoqueue(obuffer, &buf) == -1 ) { roar_buffer_free(buf); if ( sockaddr.addr != NULL ) roar_mm_free(sockaddr.addr); return -1; } } if ( sockaddr.addr != NULL ) roar_mm_free(sockaddr.addr); return 0; } static int send_text (const char * text, struct roar_buffer ** obuffer) { struct roar_buffer * buf; void * data; size_t len = strlen(text); if ( roar_buffer_new_data(&buf, len+6, &data) == -1 ) return -1; memcpy(data, text, len); //memcpy(data+len, "\r\n.\r\n\0", 6); memcpy(data+len, "\0", 1); if ( roar_buffer_moveintoqueue(obuffer, &buf) == -1 ) return -1; return 0; } static int emul_gopher_check_client(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct roar_client_server * cs; struct item * c = NULL; char inbuf[1024]; ssize_t ret; size_t i; int funcret = -1; size_t len = 0; void * data; char * text; (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); if ( clients_get_server(client, &cs) == -1 ) { return -1; } ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); if ( cs->inbuf != NULL ) { len = sizeof(inbuf)-1; if ( roar_buffer_shift_out(&(cs->inbuf), inbuf, &len) == -1 ) { return -1; } if ( cs->inbuf != NULL ) { roar_buffer_free(cs->inbuf); return -1; } // test if we have still buffer space left. if ( len == (sizeof(inbuf)-1) ) { return -1; } } ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); ret = roar_vio_read(vio, inbuf+len, sizeof(inbuf)-len-1); if ( ret < 1 ) { ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = -1", client, vio); return -1; } ret += len; inbuf[ret] = 0; ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); if ( !strip_nl(inbuf) ) { if ( roar_buffer_new_data(&(cs->inbuf), ret, &data) == -1 ) { ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = -1", client, vio); return -1; } memcpy(data, inbuf, ret); ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = 0", client, vio); return 0; } ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); for (i = 0; i < sizeof(g_gopher_items)/sizeof(*g_gopher_items); i++) { // if ( !roar_mm_strselcmp(g_gopher_items[i].selector, inbuf) ) { if ( !roar_mm_strselcmp(g_gopher_items[i].selector, inbuf) ) { c = &(g_gopher_items[i]); break; } } if ( c == NULL ) { ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = -1", client, vio); return -1; } ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); if ( c->cb != NULL ) { text = NULL; funcret = c->cb(client, vio, inbuf, &text, c, obuffer, pluginpara); if ( funcret == 0 && text != NULL ) funcret = send_text(text, obuffer); if ( text != NULL ) roar_mm_free(text); } else { switch (c->type) { case _DIR: funcret = send_menu(client, &(c->menu), vio, obuffer); break; case _FILE: funcret = send_text(c->text, obuffer); break; default: funcret = -1; break; } } ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = ?", client, vio); if ( funcret == -1 ) { ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = -1", client, vio); return -1; } ROAR_DBG("emul_gopher_check_client(client=%i, vio=%p) = 0", client, vio); return 0; } static int emul_gopher_flushed_client(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { (void)client, (void)vio, (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; ROAR_DBG("emul_gopher_flushed_client(client=%i, vio=%p) = ?", client, vio); return -1; } static struct roar_dl_proto __proto_common_gopher = { .proto = ROAR_PROTO_GOPHER, .description = "The Internet Gopher Protocol", .flags = ROAR_DL_PROTO_FLAGS_NONE, .handle = emul_gopher_check_client, .flushed = emul_gopher_flushed_client }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, __proto_common_gopher, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_gopher) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-gopher", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of the Internet Gopher protocol"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END #endif //ll ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/protocol-irc.c����������������������������������������������������0000644�0001750�0001750�00000053741�12264733631�020050� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//irc.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> #include <ctype.h> #define MAX_CHANNELS 8 struct channel { char * name; struct { char * text; char * user; time_t ts; } topic; size_t client_count; int clients[ROAR_CLIENTS_MAX]; }; struct state { const char * server_name; const char * server_fullname; const char * quit_msg; struct roar_subscriber * subscription_client_delete; struct channel g_channels[MAX_CHANNELS]; }; static struct state g_state_init = { .server_name = "irc.roard", .server_fullname = "RoarAudio roard IRC Server plugin", .quit_msg = NULL, .subscription_client_delete = NULL }; static struct state * g_state = &g_state_init; static const struct command { const char * name; int (*func)(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text); } g_commands[]; static int is_valid_name (const char * name) { register char c; for (; (c = *name) != 0; name++) { if ( !(isalnum(c) || c == '-' || c == '_') ) return 0; } return 1; } static void strip_nl(char * str) { register char c; for (; (c = *str) != 0; str++) { if ( c == '\r' || c == '\n' ) { *str = 0; return; } } } static char * get_nick(int client) { struct roar_client * c; clients_get(client, &c); return c->name; } static const char * get_ident(int client) { static char buf[80]; struct roar_client * c; clients_get(client, &c); if ( c->uid == -1 ) { buf[0] = '~'; buf[1] = 0; } else { snprintf(buf, sizeof(buf)-1, "uid%i~", c->uid); buf[sizeof(buf)-1] = 0; } return buf; } static const char * get_node(int client) { struct roar_client * c; static char buf_nnode[80]; char * nnode; clients_get(client, &c); roar_nnode_to_str(&(c->nnode), buf_nnode, sizeof(buf_nnode)); nnode = strstr(buf_nnode, ": "); if ( nnode == NULL ) { nnode = "unknown~"; } else { nnode += 2; } return nnode; } static const char * get_ufull(int client) { struct roar_client * c; static char buf[80]; const char * ident = get_ident(client); const char * nnode = get_node(client); clients_get(client, &c); snprintf(buf, sizeof(buf)-1, "%s!%s@%s", c->name, ident, nnode); buf[sizeof(buf)-1] = 0; return buf; } static const char * get_realname(int client) { (void)client; return "(no realname)"; } static int get_client_by_nick(const char * nick) { struct roar_client * c; int i; for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( clients_get(i, &c) != 0 ) continue; if ( !!strcasecmp(c->name, nick) ) continue; return i; } return -1; } static struct channel * get_channel(const char * name) { struct channel * c; size_t i; for (i = 0; i < MAX_CHANNELS; i++) { c = &(g_state->g_channels[i]); if ( !c->client_count ) continue; if ( !!strcasecmp(c->name, name) ) continue; return c; } return NULL; } static size_t get_listener_list(int client, const char * channel, int ** listener) { struct channel * c; static int clients[ROAR_CLIENTS_MAX]; size_t ret = 0; size_t i, k; int j; int found; for (i = 0; i < MAX_CHANNELS; i++) { c = &(g_state->g_channels[i]); if ( !c->client_count ) continue; if ( c->clients[client] < 1 ) continue; if ( channel != NULL && !!strcasecmp(c->name, channel) ) continue; for (j = 0; j < ROAR_CLIENTS_MAX; j++) { if ( c->clients[j] > 0 ) { found = 0; for (k = 0; k < ret; k++) { if ( clients[k] == j ) { found = 1; } } if ( !found ) { clients[ret] = j; ret++; } } } } *listener = clients; return ret; } static void put_printf(int client, struct roar_buffer ** obuffer, const char *format, ...) { va_list ap; struct roar_buffer * buf; size_t len = 2048; void * data; int ret; if ( roar_buffer_new_data(&buf, len, &data) == -1 ) return; va_start(ap, format); ret = vsnprintf(data, len-1, format, ap); va_end(ap); if ( roar_buffer_set_len(buf, strlen(data)) == -1 ) { roar_buffer_free(buf); return; } if ( obuffer == NULL ) { // TODO: FIXME: find a better way to to this. clients_add_output(client, &buf); } else { if ( roar_buffer_moveintoqueue(obuffer, &buf) == -1 ) roar_buffer_free(buf); } } static int do_join(int client, const char * channel) { struct channel * c = NULL; size_t i; if ( channel[0] != '#' ) return -1; if ( !is_valid_name(channel+1) ) return -1; for (i = 0; i < MAX_CHANNELS; i++) { if ( !g_state->g_channels[i].client_count ) continue; if ( !!strcasecmp(g_state->g_channels[i].name, channel) ) continue; c = &(g_state->g_channels[i]); break; } if ( c == NULL ) { for (i = 0; i < MAX_CHANNELS; i++) { if ( g_state->g_channels[i].client_count ) continue; c = &(g_state->g_channels[i]); break; } if ( c == NULL ) return -1; memset(c, 0, sizeof(*c)); c->name = roar_mm_strdup(channel); } if ( c->clients[client] ) return -1; c->clients[client] = 1; c->client_count++; return 0; } static int do_part(int client, const char * channel) { struct channel * c = NULL; size_t i; for (i = 0; i < MAX_CHANNELS; i++) { if ( !g_state->g_channels[i].client_count ) continue; if ( !!strcasecmp(g_state->g_channels[i].name, channel) ) continue; if ( !g_state->g_channels[i].clients[client] ) return -1; c = &(g_state->g_channels[i]); break; } c->clients[client] = 0; c->client_count--; if ( !c->client_count ) { roar_mm_free(c->name); if ( c->topic.text != NULL ) roar_mm_free(c->topic.text); if ( c->topic.user != NULL ) roar_mm_free(c->topic.user); } return 0; } static int do_names(int client, struct roar_buffer ** obuffer, const char * channel) { const char * nick = get_nick(client); size_t i; char buf[256]; size_t len, offset; char * c_nick; int j; for (i = 0; i < MAX_CHANNELS; i++) { if ( !g_state->g_channels[i].client_count ) continue; if ( !!strcasecmp(g_state->g_channels[i].name, channel) ) continue; offset = 0; for (j = 0; j < ROAR_CLIENTS_MAX; j++) { if ( g_state->g_channels[i].clients[j] == 0 ) continue; c_nick = get_nick(j); len = strlen(c_nick); if ( (offset + len + 3) > sizeof(buf) ) { buf[offset] = 0; put_printf(client, obuffer, ":%s 353 %s = %s :%s\n", g_state->server_name, nick, channel, buf); offset = 0; } memcpy(buf + offset, c_nick, len); offset += len; buf[offset] = ' '; offset++; buf[offset] = 0; } if ( offset ) { buf[offset] = 0; put_printf(client, obuffer, ":%s 353 %s = %s :%s\n", g_state->server_name, nick, channel, buf); } put_printf(client, obuffer, ":%s 366 %s %s :End of /NAMES list.\n", g_state->server_name, nick, channel); return 0; } return -1; } static int __run_command(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { size_t i; int found = 0; for (i = 0; g_commands[i].name != NULL; i++) { if ( !strcasecmp(g_commands[i].name, cmd) ) { found = 1; g_commands[i].func(client, obuffer, cmd, args, text); } } if ( !found ) { put_printf(client, obuffer, ":%s 421 %s %s :Unknown command\n", g_state->server_name, get_nick(client), cmd); } return 0; } static void cb_client_delete(struct roar_notify_core * core, struct roar_event * event, void * userdata) { int * listener; size_t count; struct channel * c; const char * text = g_state->quit_msg; int client = event->target; const char * ufull = get_ufull(client); size_t i; (void)core, (void)userdata; if ( text == NULL ) text = "Client deleted. Died, kicked or internal error."; if ( g_state->quit_msg != NULL ) put_printf(client, NULL, "ERROR :Closing Link: %s (Quit: %s)\n", ufull, text); count = get_listener_list(client, NULL, &listener); for (; count; count--, listener++) put_printf(*listener, NULL, ":%s QUIT :Quit: %s\n", ufull, text); for (i = 0; i < MAX_CHANNELS; i++) { c = &(g_state->g_channels[i]); if ( !c->client_count ) continue; if ( !c->clients[client] ) continue; c->clients[client] = 0; c->client_count--; if ( !c->client_count ) { roar_mm_free(c->name); if ( c->topic.text != NULL ) roar_mm_free(c->topic.text); if ( c->topic.user != NULL ) roar_mm_free(c->topic.user); } } clients_flush(client); } static int set_proto(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct roar_client_server * cs; char * name; (void)client, (void)vio, (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; clients_get_server(client, &cs); name = ROAR_CLIENT(cs)->name; snprintf(name, sizeof(ROAR_CLIENT(cs)->name), "Client%i~", client); /* :ph7.ph.sft NOTICE AUTH :*** Looking up your hostname... :ph7.ph.sft NOTICE AUTH :*** Couldn't resolve your hostname; using your IP address instead NICK nick USER A B C D :ph7.ph.sft NOTICE AUTH :*** Couldn't resolve your hostname; using your IP address instead :ph7.ph.sft 002 nick :Your host is ph7.ph.sft, running version Unreal3.2.7 :ph7.ph.sft 003 nick :This server was created Tue Aug 28 2007 at 10:02:00 CEST :ph7.ph.sft 004 nick ph7.ph.sft Unreal3.2.7 iowghraAsORTVSxNCWqBzvdHtGp lvhopsmntikrRcaqOALQbSeIKVfMCuzNTGj :ph7.ph.sft 005 nick NAMESX SAFELIST HCN MAXCHANNELS=10 CHANLIMIT=#:10 MAXLIST=b:60,e:60,I:60 NICKLEN=30 CHANNELLEN=32 TOPICLEN=307 KICKLEN=307 AWAYLEN=307 MAXTARGETS=20 WALLCHOPS :are supported by this server :ph7.ph.sft 005 nick WATCH=128 SILENCE=15 MODES=12 CHANTYPES=# PREFIX=(ohv)@%+ CHANMODES=beIqa,kfL,lj,psmntirRcOAQKVCuzNSMTG NETWORK=PH2 CASEMAPPING=ascii EXTBAN=~,cqnr ELIST=MNUCT STATUSMSG=@%+ EXCEPTS INVEX :are supported by this server :ph7.ph.sft 005 nick CMDS=KNOCK,MAP,DCCALLOW,USERIP :are supported by this server */ put_printf(client, obuffer, ":%s 001 %s :Welcome to the roard based IRC server.\n" ":%s 375 %s :- %s Message of the Day -\n" ":%s 372 %s :- MotD goes here...\n" ":%s 376 %s :End of /MOTD command.\n", g_state->server_name, name, g_state->server_name, name, g_state->server_name, g_state->server_name, name, g_state->server_name, name ); __run_command(client, obuffer, "LUSERS", NULL, NULL); return 0; } static int check_client(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { char cmd[1024*2]; char * args; char * text; ssize_t len; (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; len = roar_vio_read(vio, cmd, sizeof(cmd)-1); if ( len < 1 ) { clients_delete(client); return -1; } cmd[len] = 0; strip_nl(cmd); ROAR_DBG("check_client(client=%i, vio=?): cmd=\"%s\"", client, cmd); if ( cmd[0] == 0 ) return 0; args = strstr(cmd, " "); if ( args != NULL ) { *args = 0; args++; if ( *args == ':' ) { text = args + 1; args = NULL; } else { text = strstr(args, " :"); if ( text != NULL ) { *text = 0; text += 2; } } } else { text = NULL; } __run_command(client, obuffer, cmd, args, text); return 0; } // commands: static int on_nick(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { char * nick = get_nick(client); int * listener; size_t count; const char * ufull; (void)cmd, (void)text; if ( args != NULL && args[0] != 0 && is_valid_name(args) && strlen(args) < ROAR_BUFFER_NAME ) { if ( get_client_by_nick(args) != -1 ) { put_printf(client, obuffer, ":%s 433 %s %s :Nickname is already in use.\n", g_state->server_name, nick, args); } else { ufull = get_ufull(client); put_printf(client, obuffer, ":%s NICK :%s\n", ufull, args); count = get_listener_list(client, NULL, &listener); for (; count; count--, listener++) if ( *listener != client ) put_printf(*listener, NULL, ":%s NICK :%s\n", ufull, args); strcpy(nick, args); } } else { put_printf(client, obuffer, ":%s 432 %s %s :Erroneous Nickname: Illegal characters\n", g_state->server_name, nick, args); } return 0; } static int on_user(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { (void)client, (void)obuffer, (void)cmd, (void)args, (void)text; return 0; } static int on_quit(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { int ret; (void)obuffer, (void)cmd, (void)args; if ( text == NULL ) text = "... have a cuddle ..."; g_state->quit_msg = text; ret = clients_delete(client); g_state->quit_msg = NULL; return ret; } static int on_ping(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { (void)cmd, (void)args; put_printf(client, obuffer, "PONG :%s\n", text); return 0; } static int on_lusers(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { const char * clientnick = get_nick(client); size_t i; size_t numchans = 0; (void)cmd, (void)args, (void)text; /* :v0.fellig.org 251 nick :There are 9 users and 11 invisible on 1 servers :v0.fellig.org 252 nick 1 :operator(s) online :v0.fellig.org 254 nick 16 :channels formed :v0.fellig.org 255 nick :I have 20 clients and 0 servers :v0.fellig.org 265 nick :Current Local Users: 20 Max: 52 :v0.fellig.org 266 nick :Current Global Users: 20 Max: 22 */ for (i = 0; i < MAX_CHANNELS; i++) { if ( !g_state->g_channels[i].client_count ) continue; numchans++; } put_printf(client, obuffer, ":%s 251 %s :There are %zu users and 0 invisible on 1 servers\n", g_state->server_name, clientnick, counters_get(cur, clients)); put_printf(client, obuffer, ":%s 254 %s %zu :channels formed\n", g_state->server_name, clientnick, numchans); put_printf(client, obuffer, ":%s 255 %s :I have %zu clients and 0 servers\n", g_state->server_name, clientnick, counters_get(cur, clients)); put_printf(client, obuffer, ":%s 265 %s :Current Local Users: %zu Max: <unknown>\n", g_state->server_name, clientnick, counters_get(cur, clients)); put_printf(client, obuffer, ":%s 266 %s :Current Global Users: %zu Max: <unknown>\n", g_state->server_name, clientnick, counters_get(cur, clients)); return 0; } static int on_whois(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { const char * clientnick = get_nick(client); const char * tnick = args; int tclient; (void)cmd, (void)text; /* :ph7.ph.sft 317 nick phi 131 1322456381 :seconds idle, signon time */ if ( (tclient = get_client_by_nick(tnick)) == -1 ) { put_printf(client, obuffer, ":%s 401 %s %s :No such nick/channel\n", g_state->server_name, clientnick, tnick); } else { put_printf(client, obuffer, ":%s 311 %s %s %s %s * :%s\n", g_state->server_name, clientnick, tnick, get_ident(tclient), get_node(tclient), get_realname(tclient)); put_printf(client, obuffer, ":%s 312 %s %s %s :%s\n", g_state->server_name, clientnick, tnick, g_state->server_name, g_state->server_fullname); } put_printf(client, obuffer, ":%s 318 %s %s :End of /WHOIS list.\n", g_state->server_name, clientnick, tnick); return 0; } static int on_privmsg(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { const char * ufull = get_ufull(client); int * listener; size_t count; char * next; int tmp; if ( args == NULL || text == NULL ) return -1; if ( text[0] == 0 ) return 0; while (args != NULL) { next = strstr(args, ","); if ( next != NULL ) { *next = 0; next++; } if ( args[0] == '#' ) { count = get_listener_list(client, args, &listener); for (; count; count--, listener++) if ( *listener != client ) put_printf(*listener, NULL, ":%s %s %s :%s\n", ufull, cmd, args, text); } else { if ( (tmp = get_client_by_nick(args)) == -1 ) { put_printf(client, obuffer, ":%s 401 %s %s :No such nick/channel\n", g_state->server_name, get_nick(client), args); } else { put_printf(tmp, NULL, ":%s %s %s :%s\n", ufull, cmd, args, text); } } args = next; } return 0; } static int on_list(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { const char * clientnick = get_nick(client); struct channel * c; size_t i; (void)cmd, (void)args, (void)text; put_printf(client, obuffer, ":%s 321 %s Channel :Users Name\n", g_state->server_name, clientnick); for (i = 0; i < MAX_CHANNELS; i++) { c = &(g_state->g_channels[i]); if ( !c->client_count ) continue; put_printf(client, obuffer, ":%s 322 %s %s %zu :[+] %s\n", g_state->server_name, clientnick, c->name, c->client_count, c->topic.text == NULL ? "" : c->topic.text); } put_printf(client, obuffer, ":%s 323 %s :End of /LIST\n", g_state->server_name, clientnick); return 0; } static int on_join(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { struct channel * c; const char * ufull = get_ufull(client); int * listener; size_t count; const char * nick; (void)cmd, (void)text; if ( args == NULL ) return -1; if ( do_join(client, args) != 0 ) { return -1; } count = get_listener_list(client, args, &listener); for (; count; count--, listener++) put_printf(*listener, NULL, ":%s JOIN :%s\n", ufull, args); c = get_channel(args); if ( c->topic.text != NULL ) { nick = get_nick(client); put_printf(client, obuffer, ":%s 332 %s %s :%s\n" ":%s 333 %s %s %s %li\n", g_state->server_name, nick, c->name, c->topic.text, g_state->server_name, nick, c->name, c->topic.user, (long int)c->topic.ts ); } do_names(client, obuffer, args); return 0; } static int on_part(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { const char * ufull = get_ufull(client); int * listener; size_t count; (void)obuffer, (void)cmd; if ( args == NULL ) return -1; if ( text == NULL ) text = "Dejoined."; count = get_listener_list(client, args, &listener); for (; count; count--, listener++) put_printf(*listener, NULL, ":%s PART %s :%s\n", ufull, args, text); do_part(client, args); return 0; } static int on_names(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { (void)cmd, (void)text; if ( args == NULL ) return -1; return do_names(client, obuffer, args); } static int on_topic(int client, struct roar_buffer ** obuffer, const char * cmd, char * args, char * text) { struct channel * c; const char * ufull = get_ufull(client); int * listener; size_t count; char * nick = get_nick(client); (void)obuffer, (void)cmd; if ( args == NULL ) return -1; c = get_channel(args); if ( c == NULL ) return -1; if ( !c->clients[client] ) { return -1; } if ( c->topic.text != NULL ) roar_mm_free(c->topic.text); if ( c->topic.user != NULL ) roar_mm_free(c->topic.user); c->topic.text = NULL; c->topic.user = roar_mm_strdup(nick); c->topic.ts = time(NULL); if ( text != NULL ) c->topic.text = roar_mm_strdup(text); if ( text == NULL ) text = ""; count = get_listener_list(client, c->name, &listener); for (; count; count--, listener++) put_printf(*listener, NULL, ":%s TOPIC %s :%s\n", ufull, c->name, text); return 0; } static const struct command g_commands[] = { {"NICK", on_nick}, {"USER", on_user}, {"QUIT", on_quit}, {"PING", on_ping}, {"LUSERS", on_lusers}, {"WHOIS", on_whois}, {"PRIVMSG", on_privmsg}, {"NOTICE", on_privmsg}, {"LIST", on_list}, {"JOIN", on_join}, {"PART", on_part}, {"NAMES", on_names}, {"TOPIC", on_topic}, {NULL, NULL} }; // plugin handling suff: static int init(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { struct roar_event event; (void)para, (void)lib; memset(&event, 0, sizeof(event)); event.event = ROAR_OE_BASICS_DELETE; event.emitter = -1; event.target = -1; event.target_type = ROAR_OT_CLIENT; memset(g_state->g_channels, 0, sizeof(g_state->g_channels)); g_state->subscription_client_delete = roar_notify_core_subscribe(NULL, &event, cb_client_delete, NULL); return 0; } static int unload(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; roar_notify_core_unsubscribe(NULL, g_state->subscription_client_delete); return 0; } static const struct roar_dl_proto proto = { .proto = ROAR_PROTO_IRC, .description = "Internet Relay Chat", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = set_proto, .unset_proto = NULL, .handle = check_client, .flush = NULL, .flushed = NULL, .status = NULL }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, proto, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_irc) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-irc", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of the Internet Relay Chat (IRC)"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_INIT, init); ROAR_DL_PLUGIN_REG_UNLOAD(unload); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init); } ROAR_DL_PLUGIN_END //ll �������������������������������roaraudio-1.0beta11/plugins/roard/protocol-rplay.c��������������������������������������������������0000644�0001750�0001750�00000042413�12264733631�020414� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//emul_rplay.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> #ifndef ROAR_WITHOUT_DCOMP_EMUL_RPLAY struct emul_rplay_command { const char * name; const char * usage; ssize_t min_args; ssize_t max_args; int (*handler)(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); }; static int emul_rplay_exec_command (int client, struct roar_vio_calls * vio, char * command); static int emul_rplay_send_error (int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen, const char * msg); static int emul_rplay_on_status(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static int emul_rplay_on_quit(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static int emul_rplay_on_help(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); // things we need to implent soon: static int emul_rplay_on_play(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static int emul_rplay_on_put(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); //static int emul_rplay_on_set(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); //static int emul_rplay_on_modify(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static int emul_rplay_on_pause(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static int emul_rplay_on_continue(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); //static int emul_rplay_on_stop(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static struct emul_rplay_command emul_rplay_commands[] = { {"access", NULL, -1, -1, NULL}, {"application", NULL, 1, -1, NULL}, {"continue", NULL, 1, -1, emul_rplay_on_continue}, {"die", NULL, 1, -1, NULL}, {"done", NULL, 1, -1, NULL}, // #ifdef DEBUG {"find", NULL, 1, 1, NULL}, {"get", NULL, 1, 1, NULL}, {"help", NULL, -1, -1, emul_rplay_on_help}, {"info", NULL, 1, 1, NULL}, {"list", NULL, 0, 1, NULL}, {"modify", NULL, 2, -1, NULL}, {"monitor", NULL, 1, -1, NULL}, {"pause", NULL, 1, -1, emul_rplay_on_pause}, {"play", NULL, 1, -1, emul_rplay_on_play}, {"put", NULL, 2, -1, emul_rplay_on_put}, {"quit", NULL, 0, 0, emul_rplay_on_quit}, {"reset", NULL, 0, 0, NULL}, {"set", NULL, 1, -1, NULL}, {"skip", NULL, 1, 1, NULL}, {"status", NULL, 0, 0, emul_rplay_on_status}, {"stop", NULL, 1, -1, NULL}, {"version", NULL, 0, 0, NULL}, {"volume", NULL, 0, 1, NULL}, {"wait", NULL, -1, -1, NULL}, {NULL, NULL, -1, -1, NULL} }; static inline int is_true(const char * str) { const char * ts[] = {"true", "t", "1", "yes", "y", "on"}; size_t i; for (i = 0; i < (sizeof(ts)/sizeof(*ts)); i++) if ( !strcasecmp(str, ts[i]) ) return 1; return 0; } static inline int is_false(const char * str) { return !is_true(str); } static int format_to_codec(const char * str, const int bo) { if ( !strcasecmp(str, "ulaw") || !strcasecmp(str, "u_law") || !strcasecmp(str, "u-law") ) return ROAR_CODEC_MULAW; if ( !strncasecmp(str, "ulinear", 7) ) { switch (bo) { case ROAR_BYTEORDER_LE: return ROAR_CODEC_PCM_U_LE; break; case ROAR_BYTEORDER_BE: return ROAR_CODEC_PCM_U_BE; break; case ROAR_BYTEORDER_PDP: return ROAR_CODEC_PCM_U_PDP; break; default: return -1; break; } } else if ( !strncasecmp(str, "linear", 6) ) { switch (bo) { case ROAR_BYTEORDER_LE: return ROAR_CODEC_PCM_S_LE; break; case ROAR_BYTEORDER_BE: return ROAR_CODEC_PCM_S_BE; break; case ROAR_BYTEORDER_PDP: return ROAR_CODEC_PCM_S_PDP; break; default: return -1; break; } } return -1; } static int emul_rplay_set_proto (int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; if ( emul_rplay_on_status(client, NULL, vio, NULL, 0) == -1 ) return -1; return 0; } static int emul_rplay_check_client (int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { char buf[1024]; ssize_t len; (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; if ( client == -1 ) return -1; if ( (len = roar_vio_read(vio, buf, sizeof(buf)-1)) <= 0 ) { // really bad protocol error return -1; } for (; buf[len-1] == '\r' || buf[len-1] == '\n'; len--); buf[len] = 0; return emul_rplay_exec_command(client, vio, buf); } int emul_rplay_exec_command (int client, struct roar_vio_calls * vio, char * command) { struct emul_rplay_command * cmd; struct roar_keyval * kv; ssize_t kvlen; char * para = NULL; char * c; int last_was_space = 0; for (c = command; *c != 0; c++) { if ( *c == ' ' || *c == '\t' ) { last_was_space = 1; *c = 0; } else { if ( last_was_space ) { para = c; break; } } } if ( para == NULL ) { kv = NULL; kvlen = 0; } else { kvlen = roar_keyval_split(&kv, para, " \t", "=", 0); if ( kvlen == -1 ) return emul_rplay_send_error(client, NULL, vio, NULL, 0, "Can not parse parameter list"); } for (cmd = emul_rplay_commands; cmd->name != NULL; cmd++) { if ( !strcasecmp(cmd->name, command) ) break; } if ( cmd->name == NULL ) return emul_rplay_send_error(client, NULL, vio, kv, kvlen, "unknown command"); if ( cmd->handler == NULL ) return emul_rplay_send_error(client, cmd, vio, kv, kvlen, "unsupported command"); return cmd->handler(client, cmd, vio, kv, kvlen); } int emul_rplay_send_error (int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen, const char * msg) { struct roar_keyval * kvr; const char * command; const char * cd = NULL; (void)client; if ( cmd != NULL ) { command = cmd->name; } else { command = "(unknown)"; } if ( kv != NULL ) { kvr = roar_keyval_lookup(kv, "client-data", kvlen, 0); if ( kvr != NULL ) cd = kvr->value; } if ( cd == NULL ) cd = ""; return roar_vio_printf(vio, "-error=\"%s\" command=\"%s\" client-data=\"%s\"\n", msg, command, cd) <= 0 ? -1 : 0; } int emul_rplay_on_status(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen) { const char * hostname = "localhost"; const char * version = "RoarAudio"; char uptime[16]; const char * byteorder = "native"; int fragsize = ROAR_OUTPUT_CALC_OUTBUFSIZE(g_sa); int h, m, s; (void)client, (void)cmd, (void)kv, (void)kvlen; s = g_pos / g_sa->rate / g_sa->channels; h = s / 3600; s -= h * 3600; m = s / 60; s -= m * 60; snprintf(uptime, sizeof(uptime)-1, "%.2i:%.2i:%.2i", h, m, s); uptime[sizeof(uptime)-1] = 0; switch (ROAR_CODEC_BYTE_ORDER(g_sa->codec)) { case ROAR_CODEC_LE: byteorder = "little-endian"; break; case ROAR_CODEC_BE: byteorder = "big-endian"; break; case ROAR_CODEC_PDP: byteorder = "pdp-endian"; break; } roar_vio_printf(vio, "+host=%s version=%s uptime=%s " "audio-bits=%i audio-byte-order=%s audio-channels=%i " "audio-device=internal-mixer " "audio-format=linear-%i " "audio-fragsize=%i " "audio-port=speaker,headphone,lineout audio-rate=10 " "audio-sample-rate=%i " "volume=254 " "curr-rate=10 priority-threshold=0 audio-close=0 audio-device-status=open" "\n", hostname, version, uptime, g_sa->bits, byteorder, g_sa->channels, g_sa->bits, fragsize, g_sa->rate ); return 0; } static int emul_rplay_on_quit(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen) { (void)client, (void)cmd, (void)vio, (void)kv, (void)kvlen; return -1; } static int emul_rplay_on_help(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen) { struct emul_rplay_command * c; (void)client, (void)cmd, (void)kv, (void)kvlen; roar_vio_printf(vio, "+message=\"command summary\" command=help\n"); for (c = emul_rplay_commands; c->name != NULL; c++) { roar_vio_printf(vio, "%-8s %s\n", c->name, c->usage == NULL ? "" : c->usage); } roar_vio_printf(vio, ".\n"); return -1; } static int emul_rplay_on_play(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen) { struct roar_keyval * kvr, * rate, * bits, * channels, * format, * byteorder; struct roar_audio_info info; struct roar_stream_server * ss; struct roar_stream * s; int stream; int bo = -1; char * cd = NULL; if ( (kvr = roar_keyval_lookup(kv, "input", kvlen, 0)) == NULL ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "no input parameter"); return -1; } if ( !!strcasecmp(kvr->value, "flow") ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "non-flow input not supported"); return -1; } /* "input-format=%s input-sample-rate=%d input-bits=%d " "input-channels=%d input-byte-order=%s", */ rate = roar_keyval_lookup(kv, "input-sample-rate", kvlen, 0); bits = roar_keyval_lookup(kv, "input-bits", kvlen, 0); channels = roar_keyval_lookup(kv, "input-channels", kvlen, 0); format = roar_keyval_lookup(kv, "input-format", kvlen, 0); byteorder = roar_keyval_lookup(kv, "input-byte-order", kvlen, 0); if ( rate == NULL || bits == NULL || channels == NULL || format == NULL || byteorder == NULL ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "missing audio parameter"); return -1; } info.rate = atoi(rate->value); info.bits = atoi(bits->value); info.channels = atoi(channels->value); if ( !strcasecmp(byteorder->value, "big-endian") || !strcasecmp(byteorder->value, "big") ) { bo = ROAR_BYTEORDER_BE; } else if ( !strcasecmp(byteorder->value, "little-endian") || !strcasecmp(byteorder->value, "little") ) { bo = ROAR_BYTEORDER_LE; } else if ( !strcasecmp(byteorder->value, "pdp-endian") || !strcasecmp(byteorder->value, "pdp") ) { bo = ROAR_BYTEORDER_PDP; } else { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "unknown byte order"); return -1; } info.codec = format_to_codec(format->value, bo); if ((stream = streams_new()) == -1 ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "can not create new stream"); return -1; } if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); emul_rplay_send_error(client, cmd, vio, kv, kvlen, "can not get stream object"); return -1; } s = ROAR_STREAM(ss); if ( client_stream_add(client, stream) == -1 ) { streams_delete(stream); emul_rplay_send_error(client, cmd, vio, kv, kvlen, "can not add stream to client"); return -1; } memcpy(&(s->info), &info, sizeof(info)); ss->codec_orgi = s->info.codec; if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) { streams_delete(stream); emul_rplay_send_error(client, cmd, vio, kv, kvlen, "can not set dir on stream"); return -1; } if ( (kvr = roar_keyval_lookup(kv, "client-data", kvlen, 0)) != NULL ) { cd = kvr->value; } if ( cd == NULL ) cd = ""; // connection_reply(c, "%cid=#%d sound=\"%s\" command=%s client-data=\"%s\" list-name=\"%s\"", // roar_vio_printf(vio, "+id=#%i sound=\"%s\" command=%s client-data=\"%s\" list-name=\"%s\""); roar_vio_printf(vio, "+id=#%i command=%s client-data=\"%s\"\n", stream, "play", cd); return 0; } static int emul_rplay_on_put(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen) { struct roar_keyval * kvr; int stream; size_t len; char * cd = NULL; //23:00 < ph3-der-loewe> rptp_putline(flow_fd, "put id=#%d size=0", spool_id); if ( (kvr = roar_keyval_lookup(kv, "id", kvlen, 0)) == NULL ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "no id parameter"); return -1; } stream = atoi(kvr->value+1); if ( (kvr = roar_keyval_lookup(kv, "size", kvlen, 0)) == NULL ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "no size parameter"); return -1; } len = atoi(kvr->value); if ( len != 0 ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "currently only zero size put supported"); return -1; } if ( client_stream_exec(client, stream) == -1 ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "can not exec stream"); return -1; } if ( (kvr = roar_keyval_lookup(kv, "client-data", kvlen, 0)) != NULL ) { cd = kvr->value; } if ( cd == NULL ) cd = ""; /* connection_reply(c, "%cid=#%d size=%d command=put client-data=\"%s\"", RPTP_OK, spool_id, sound_size, client_data); */ roar_vio_printf(vio, "+id=#%i command=%s client-data=\"%s\"\n", stream, "put", cd); return 0; } //static int emul_rplay_on_set(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); //static int emul_rplay_on_modify(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static int emul_rplay_on_pause(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen) { struct roar_keyval * kvr; int stream; char * cd = NULL; if ( kvlen < 1 ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "no id parameter"); return -1; } stream = atoi(kv->key+1); if ( streams_set_flag(stream, ROAR_FLAG_PAUSE) == -1 ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "can not set pause flag"); return -1; } if ( (kvr = roar_keyval_lookup(kv, "client-data", kvlen, 0)) != NULL ) { cd = kvr->value; } if ( cd == NULL ) cd = ""; roar_vio_printf(vio, "+id=#%i command=%s client-data=\"%s\"\n", stream, "pause", cd); return 0; } static int emul_rplay_on_continue(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen) { struct roar_keyval * kvr; int stream; char * cd = NULL; if ( kvlen < 1 ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "no id parameter"); return -1; } stream = atoi(kv->key+1); if ( streams_reset_flag(stream, ROAR_FLAG_PAUSE) == -1 ) { emul_rplay_send_error(client, cmd, vio, kv, kvlen, "can not reset pause flag"); return -1; } if ( (kvr = roar_keyval_lookup(kv, "client-data", kvlen, 0)) != NULL ) { cd = kvr->value; } if ( cd == NULL ) cd = ""; roar_vio_printf(vio, "+id=#%i command=%s client-data=\"%s\"\n", stream, "coninue", cd); return 0; } //static int emul_rplay_on_stop(int client, struct emul_rplay_command * cmd, struct roar_vio_calls * vio, struct roar_keyval * kv, size_t kvlen); static struct roar_dl_proto __proto_common_rplay = { .proto = ROAR_PROTO_RPLAY, .description = "RPlay emulation", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = emul_rplay_set_proto, .handle = emul_rplay_check_client }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, __proto_common_rplay, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_rplay) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-rplay", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of the RPlay protocol"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END #endif //ll �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/roard/service-client.c��������������������������������������������������0000644�0001750�0001750�00000011301�12264733632�020333� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//service-about.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2013-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roard/include/roard.h> static ssize_t __list(int * ids, size_t len) { struct roar_client * c; size_t i, j; if ( g_counters.cur.clients > len ) { roar_err_set(ROAR_ERROR_NOSPC); return -1; } for (j = i = 0; i < ROAR_CLIENTS_MAX && j < len; i++) if ( clients_get(i, &c) == 0 ) ids[j++] = i; return j; } static ssize_t __num(enum roar_service_num what) { switch (what) { case ROAR_SERVICE_NUM_DEFAULT: case ROAR_SERVICE_NUM_CURRENT: return g_counters.cur.clients; break; case ROAR_SERVICE_NUM_BUFFER: if ( ((double)g_counters.cur.clients * 1.5) > ROAR_CLIENTS_MAX ) return ROAR_CLIENTS_MAX; return (double)g_counters.cur.clients * 1.25; break; #ifndef DEBUG default: break; #endif } roar_err_set(ROAR_ERROR_NOTSUP); return -1; } static int __get(int id, struct roar_client * client) { struct roar_client * c; if ( client == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( clients_get(id, &c) == -1 ) return -1; memcpy(client, c, sizeof(struct roar_client)); client->acl = NULL; return 0; } static int __status(int id) { struct roar_dl_librarypara * pluginpara; const struct roard_proto_handle * proto; struct roar_client_server * cs; struct roar_vio_calls vio; int ret, err; if ( clients_get_server(id, &cs) == -1 ) return -1; if ( (proto = clients_get_protohandle(ROAR_CLIENT(cs)->proto)) == NULL ) return -1; if ( proto->lhandle != NULL ) roar_dl_context_restore(proto->lhandle); pluginpara = roar_dl_getpara(proto->lhandle); switch (proto->type) { case ROARD_PROTO_TYPE_COMMON: if ( proto->impl.common->status == NULL ) { ret = -1; err = ROAR_ERROR_NOSYS; } else { roar_vio_open_fh_socket(&vio, clients_get_fh(id)); ret = proto->impl.common->status(id, &vio, &(cs->outbuf), &(cs->protoinst), proto->para, proto->paralen, pluginpara); } break; default: ret = -1; err = ROAR_ERROR_NOSYS; break; } if ( pluginpara != NULL ) roar_dl_para_unref(pluginpara); if ( proto->lhandle != NULL ) roar_dl_context_store(proto->lhandle); roar_err_set(err); return ret; } static int __set_ids(int id, int clear, int pid, int uid, int gid) { struct roar_client * c; // just to check if the client exist. if ( clients_get(id, &c) == -1 ) return -1; // TODO: add proper error handling here. if ( pid != -1 || clear ) clients_set_pid(id, pid); if ( uid != -1 || clear ) clients_set_uid(id, uid); if ( gid != -1 || clear ) clients_set_gid(id, gid); return 0; } static int __set_proto(int id, int proto) { (void)id, (void)proto; roar_err_set(ROAR_ERROR_NOSYS); return -1; } static struct roar_service_client api = { .list = __list, .num = __num, .get = __get, .kick = (int(*)(int id, int error, const char * msg))clients_delete, .status = __status, .set_ids = __set_ids, .set_name = clients_set_name, .set_proto = __set_proto, /* dummy */ .exec = client_stream_exec }; ROAR_DL_PLUGIN_REG_SERVICES_GET_API(get_api, api) static const struct roar_dl_service service[1] = { { .appname = NULL, .appabi = NULL, .servicename = ROAR_SERVICE_CLIENT_NAME, .serviceabi = ROAR_SERVICE_CLIENT_ABI, .description = "Access to client management", .flags = ROAR_DL_SERVICE_FLAGS_NONE, .userdata = NULL, .get_api = get_api } }; ROAR_DL_PLUGIN_REG_SERVICES(service); ROAR_DL_PLUGIN_START(service_client) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("service-client", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This plugin provides an interface to client control features of roard."); ROAR_DL_PLUGIN_REG_FNFUNC(ROAR_DL_FN_SERVICE); } ROAR_DL_PLUGIN_END //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/��������������������������������������������������������������0000755�0001750�0001750�00000000000�12267553177�016167� 5����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/Makefile������������������������������������������������������0000644�0001750�0001750�00000002442�12134610313�017604� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include ../../Makefile.conf include ../../Makefile.inc TARGETS_PROTO=protocol-echo$(SHARED_SUFFIX) protocol-daytime$(SHARED_SUFFIX) protocol-discard$(SHARED_SUFFIX) tic-tac-toe$(SHARED_SUFFIX) protocol-http$(SHARED_SUFFIX) TARGETS_MISC=plugin-info$(SHARED_SUFFIX) helloworld$(SHARED_SUFFIX) debug-notify$(SHARED_SUFFIX) TARGETS_IO=piface$(SHARED_SUFFIX) TARGETS_SERVICE=service-about$(SHARED_SUFFIX) TARGETS=$(TARGETS_MISC) $(TARGETS_PROTO) $(TARGETS_SERVICE) $(TARGETS_IO) #DEFINES = -DDEBUG DEFINES+= -DROAR_DBG_PREFIX=\"'$(shell basename $+ .c)'\" INCLUDE = -I../../include -I../.. CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(SHARED) -L../../lib $(LDPATH) LIBS = $(LIBROAR) all: ${TARGETS} clean: rm -f ${TARGETS} *.o new: clean all install: all cp $(cp_v) ${TARGETS} '$(DESTDIR)$(PREFIX_PLUGINS)/universal/universal/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/' semi-install: all sh -c 'set -e; for file in *$(SHARED_SUFFIX); do ln -fs `pwd`/$$file '$(DESTDIR)$(PREFIX_PLUGINS)/universal/universal/$(DEV_VENDOR)-$(DEV_VENDOR_NAME)/'; done' %$(SHARED_SUFFIX): %.o $(CC) $(LDFLAGS) -o $@ $+ $(LIBS) protocol-http$(SHARED_SUFFIX): protocol-http.o $(CC) $(LDFLAGS) -o $@ $+ $(LIBS) $(lib_uste) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/debug-notify.c������������������������������������������������0000644�0001750�0001750�00000021043�12264733632�020720� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//debug-notify.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> #include <ctype.h> static struct roar_subscriber * subscription_client_delete = NULL; static int command_get_name(int cmd, const char ** name) { static const struct { const int cmd; const char * name; } cmds[] = { {ROAR_CMD_NOOP, "NOOP"}, {ROAR_CMD_IDENTIFY, "IDENTIFY"}, {ROAR_CMD_AUTH, "AUTH"}, {ROAR_CMD_NEW_STREAM, "NEW_STREAM"}, {ROAR_CMD_SET_META, "SET_META"}, {ROAR_CMD_EXEC_STREAM, "EXEC_STREAM"}, {ROAR_CMD_QUIT, "QUIT"}, {ROAR_CMD_GET_STANDBY, "GET_STANDBY"}, {ROAR_CMD_SET_STANDBY, "SET_STANDBY"}, {ROAR_CMD_SERVER_INFO, "SERVER_INFO"}, {ROAR_CMD_SERVER_STATS, "SERVER_STATS"}, {ROAR_CMD_SERVER_OINFO, "SERVER_OINFO"}, {ROAR_CMD_ADD_DATA, "ADD_DATA"}, {ROAR_CMD_EXIT, "EXIT"}, {ROAR_CMD_LIST_STREAMS, "LIST_STREAMS"}, {ROAR_CMD_LIST_CLIENTS, "LIST_CLIENTS"}, {ROAR_CMD_GET_CLIENT, "GET_CLIENT"}, {ROAR_CMD_GET_STREAM, "GET_STREAM"}, {ROAR_CMD_KICK, "KICK"}, {ROAR_CMD_SET_VOL, "SET_VOL"}, {ROAR_CMD_GET_VOL, "GET_VOL"}, {ROAR_CMD_CON_STREAM, "CON_STREAM"}, {ROAR_CMD_GET_META, "GET_META"}, {ROAR_CMD_LIST_META, "LIST_META"}, {ROAR_CMD_BEEP, "BEEP"}, {ROAR_CMD_GET_STREAM_PARA, "GET_STREAM_PARA"}, {ROAR_CMD_SET_STREAM_PARA, "SET_STREAM_PARA"}, {ROAR_CMD_ATTACH, "ATTACH"}, {ROAR_CMD_DETACH, "DETACH"}, {ROAR_CMD_PASSFH, "PASSFH"}, {ROAR_CMD_GETTIMEOFDAY, "GETTIMEOFDAY"}, {ROAR_CMD_WHOAMI, "WHOAMI"}, {ROAR_CMD_DEVCTL, "DEVCTL"}, {ROAR_CMD_CAPS, "CAPS"}, {ROAR_CMD_WAIT, "WAIT"}, {ROAR_CMD_NOTIFY, "NOTIFY"}, {ROAR_CMD_SEEK, "SEEK"}, {ROAR_CMD_CLIENTCTL, "CLIENTCTL"}, {ROAR_CMD_LOOKUP, "LOOKUP"}, {ROAR_CMD_CONCTL, "CONCTL"}, {ROAR_CMD_SHIFT_DATA, "SHIFT_DATA"}, {ROAR_CMD_RAUM_SEEKTABLE, "RAUM_SEEKTABLE"}, {ROAR_CMD_RAUM_PICTURE, "RAUM_PICTURE"}, {ROAR_CMD_RAUM_SYNC, "RAUM_SYNC"}, {ROAR_CMD_EPERM, "EPERM"}, {ROAR_CMD_OK_STOP, "OK_STOP"}, {ROAR_CMD_OK, "OK"}, {ROAR_CMD_ERROR, "ERROR"}, {ROAR_CMD_EOL, "EOL"} }; size_t i; for (i = 0; i < (sizeof(cmds)/sizeof(*cmds)); i++) { if ( cmds[i].cmd == cmd ) { *name = cmds[i].name; return 0; } } roar_err_set(ROAR_ERROR_NOENT); return -1; } static void dbg_notify_cb(struct roar_notify_core * core, struct roar_event * event, void * userdata) { char buf[1024] = ""; char estr[1024] = "/* ROAR_??? */"; char ttstr[1024] = "/* ROAR_OT_??? */"; const char * ttname; uint32_t ev = ROAR_EVENT_GET_TYPE(event); int i; ttname = roar_ot2str(event->target_type); if ( ttname != NULL ) { snprintf(ttstr, sizeof(ttstr)-1, "/* ROAR_OT_%s */", ttname); buf[sizeof(ttstr)-1] = 0; for (i = 0; ttstr[i] != 0; i++) if ( islower(ttstr[i]) ) ttstr[i] = toupper(ttstr[i]); } if ( ev == ROAR_NOTIFY_SPECIAL ) { snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_SPECIAL */"); } else if ( ROAR_NOTIFY_IS_CMD(ev) ) { if ( command_get_name(ROAR_NOTIFY_EVENT2CMD(ev), &ttname) == -1 ) { snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_CMD2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2CMD(ev)); } else { snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_CMD2EVENT(ROAR_CMD_%s) */", ttname); for (i = 0; estr[i] != 0; i++) if ( islower(estr[i]) ) estr[i] = toupper(estr[i]); } } else if ( ROAR_NOTIFY_IS_EGRP(ev) ) { snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_EGRP2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2EGRP(ev)); } else if ( ROAR_NOTIFY_IS_OE(ev) ) { switch (ev) { // OE basics: case ROAR_OE_BASICS_CHANGE_STATE: snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_CHANGE_STATE */"); break; case ROAR_OE_BASICS_CHANGE_FLAGS: snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_CHANGE_FLAGS */"); break; case ROAR_OE_BASICS_NEW: snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_NEW */"); break; case ROAR_OE_BASICS_DELETE: snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_DELETE */"); break; // OE Streams: case ROAR_OE_STREAM_CHANGE_VOLUME: snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_STREAM_CHANGE_VOLUME */"); break; case ROAR_OE_STREAM_XRUN: snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_STREAM_XRUN */"); break; case ROAR_OE_STREAM_META_UPDATE: snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_STREAM_META_UPDATE */"); break; // OE Default: default: snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_OE2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2OE(ev)); break; } } else if ( ROAR_NOTIFY_IS_DATA(ev) ) { switch (ev) { case ROAR_DATA_DMX512_CHANNEL_UPDATE: snprintf(estr, sizeof(estr)-1, "/* ROAR_DATA_DMX512_CHANNEL_UPDATE */"); break; case ROAR_DATA_DMX512_EVENT: snprintf(estr, sizeof(estr)-1, "/* ROAR_DATA_DMX512_EVENT */"); break; // DATA Default: default: snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_EVENT2DATA(ROAR_DATA_GROUP(%s) + %lu) */", roar_dir2str(ROAR_DATA_EVENT2DIR(ROAR_NOTIFY_EVENT2DATA(ev))), (long unsigned int)ROAR_DATA_EVENT2EVENT(ROAR_NOTIFY_EVENT2DATA(ev))); break; } } else if ( ROAR_NOTIFY_IS_USER(ev) ) { snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_USER2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2USER(ev)); } buf[sizeof(estr)-1] = 0; if ( event->flags & ROAR_EVENT_FLAG_PROXYEVENT ) { snprintf(buf, sizeof(buf)-1, ".event_proxy=0x%.8x%s, ", (int)event->event_proxy, estr); buf[sizeof(buf)-1] = 0; } roar_debug_msg(ROAR_DEBUG_TYPE_DEBUG, __LINE__, __FILE__, ROAR_DBG_PREFIX, "dbg_notify_cb(core=%p, event=%p{.flags=0x%.8x, event=0x%.8x%s, %s.emitter=%i, .target=%i, .target_type=%i%s, .arg0=%i, .arg1=%i, .arg2=%p}, userdata=%p) = (void)", core, event, (int)event->flags, (int)event->event, (event->flags & ROAR_EVENT_FLAG_PROXYEVENT ? "" : estr), buf, event->emitter, event->target, event->target_type, ttstr, event->arg0, event->arg1, event->arg2, userdata); } static int init(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { struct roar_event event; (void)para, (void)lib; memset(&event, 0, sizeof(event)); event.event = ROAR_EGRP_ANY_EVENT; event.emitter = -1; event.target = -1; event.target_type = -1; subscription_client_delete = roar_notify_core_subscribe(NULL, &event, dbg_notify_cb, NULL); return 0; } static int unload(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; roar_notify_core_unsubscribe(NULL, subscription_client_delete); return 0; } ROAR_DL_PLUGIN_START(debug_notify) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("debug-notify", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This plugin will print all messages passed via notify bus"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_INIT, init); ROAR_DL_PLUGIN_REG_UNLOAD(unload); } ROAR_DL_PLUGIN_END //ll ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/helloworld.c��������������������������������������������������0000644�0001750�0001750�00000005464�12264733632�020510� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//helloworld.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> // A simple function printing our message. static int hw_init (struct roar_dl_librarypara * para) { const char * text = "Hello world!"; struct roar_keyval * cur; size_t i; if ( para != NULL && para->argv != NULL ) { for (i = 0; i < para->argc; i++) { cur = &(para->argv[i]); if ( cur->key != NULL && !strcmp(cur->key, "text") ) { if ( cur->value != NULL ) { text = cur->value; } else if ( (i+1) < para->argc && para->argv[i+1].key == NULL ) { text = para->argv[i+1].value; i++; } } } } roar_vio_printf(roar_stdout, "%s\n", text); return 0; } // This struct contains the AppSched pointers. static struct roar_dl_appsched sched = { .init = hw_init, .free = NULL, .update = NULL, .tick = NULL, .wait = NULL }; // This is the plugin control block. ROAR_DL_PLUGIN_START(helloworld) { // Here we set the name and vendor of our plugin. // If you have no Vendor ID you need to use ROAR_DL_PLUGIN_META_PRODUCT_NV(). ROAR_DL_PLUGIN_META_PRODUCT_NIV("helloworld", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); // This sets the version of your plugin. ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); // This sets the license of your plugin. // If there is no tag for the license you use you can just // use ROAR_DL_PLUGIN_META_LICENSE(). ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); // This sets the author and contact infos. // There are several other macros to do this with other parameters. // See ROAR_DL_PLUGIN_META_CONTACT*() in the header or documentation. ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); // This sets the description for your plugin. ROAR_DL_PLUGIN_META_DESC("This plugin prints the string \"Hello world!\"."); // Here the AppSched block from above is registered. ROAR_DL_PLUGIN_REG_APPSCHED(&sched); // This is the end of the control block. } ROAR_DL_PLUGIN_END //ll ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/piface.c������������������������������������������������������0000644�0001750�0001750�00000032053�12264733633�017557� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//piface.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2013-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> #ifdef ROAR_HAVE_H_LINUX_SPI_SPIDEV #include <linux/spi/spidev.h> #include <sys/ioctl.h> #define NUM_PORTS (8+8+1) #define TRANSFER_LEN 3 #define TRANSFER_DELAY 5 #define TRANSFER_SPEED 1000000 #define TRANSFER_BPW 8 #define SPI_WRITE_CMD 0x40 #define SPI_READ_CMD 0x41 #define IODIRA 0x00 // I/O direction A #define IODIRB 0x01 // I/O direction B #define IOCON 0x0A // I/O config #define GPIOA 0x12 // port A #define GPIOB 0x13 // port B #define GPPUA 0x0C // port A pullups #define GPPUB 0x0D // port B pullups #define OUTPUT_PORT GPIOA #define INPUT_PORT GPIOB struct state { int inited; int bus; int device; struct roar_vio_calls vio_store; struct roar_vio_calls * vio; unsigned char buffer_output; unsigned char buffer_input; struct roar_service_gpio_port ports[NUM_PORTS]; }; static struct state * state = NULL; static struct state state_init = { .inited = 0, .bus = 0, .device = 0, .vio = NULL, .buffer_output = 0x00, .buffer_input = 0x00, .ports = { // inputs: {.id = 0, .name = "gpin0", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 1, .name = "gpin1", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 2, .name = "gpin2", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 3, .name = "gpin3", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 4, .name = "gpin4", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 5, .name = "gpin5", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 6, .name = "gpin6", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 7, .name = "gpin7", .mode = ROAR_SERVICE_GPIO_FINPUT|ROAR_SERVICE_GPIO_FPULLUP, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, // outputs: {.id = 8, .name = "gpout0", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 9, .name = "gpout1", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 10, .name = "gpout2", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 11, .name = "gpout3", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 12, .name = "gpout4", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 13, .name = "gpout5", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 14, .name = "gpout6", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, {.id = 15, .name = "gpout7", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TBOOL, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 1, .frange_min = 0, .frange_max = 1}, // special: {.id = 16, .name = "bar0", .mode = ROAR_SERVICE_GPIO_FOUTPUT, .unit = NULL, .type = ROAR_SERVICE_GPIO_TINT, .state = ROAR_SERVICE_GPIO_SUNINITED, .irange_min = 0, .irange_max = 8, .frange_min = 0, .frange_max = 8} } }; static int piface__transfer(char cmd, char port, char value) { unsigned char txbuffer[3] = {cmd, port, value}; unsigned char rxbuffer[3]; struct spi_ioc_transfer transfer_buffer = { .tx_buf = (unsigned long) txbuffer, .rx_buf = (unsigned long) rxbuffer, .len = TRANSFER_LEN, .delay_usecs = TRANSFER_DELAY, .speed_hz = TRANSFER_SPEED, .bits_per_word = TRANSFER_BPW, }; struct roar_vio_sysio_ioctl ctl = {.cmd = SPI_IOC_MESSAGE(1), .argp = &transfer_buffer}; if ( roar_vio_ctl(state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) return -1; return (unsigned int)rxbuffer[2]; } static int piface__init(void) { char path[80]; if ( state->inited ) { roar_err_set(ROAR_ERROR_ALREADY); return -1; } snprintf(path, sizeof(path), "file://dev/spidev%i.%i", state->bus, state->device); state->vio = &(state->vio_store); if ( roar_vio_open_dstr_simple(state->vio, path, ROAR_VIOF_READWRITE) == -1 ) return -1; piface__transfer(SPI_WRITE_CMD, IOCON, 8); // enable hardware addressing piface__transfer(SPI_WRITE_CMD, GPIOA, 0x00); // turn on port A piface__transfer(SPI_WRITE_CMD, IODIRA, 0); // set port A as an output piface__transfer(SPI_WRITE_CMD, IODIRB, 0xFF); // set port B as an input piface__transfer(SPI_WRITE_CMD, GPPUB, 0xFF); // turn on port B pullups piface__transfer(SPI_WRITE_CMD, OUTPUT_PORT, 0x00); // turn of all outputs. state->inited = 1; return 0; } static int piface__free(void) { if ( !state->inited ) { roar_err_set(ROAR_ERROR_BADSTATE); return -1; } roar_vio_close(state->vio); state->inited = 0; return 0; } static void piface__write_output(unsigned char val) { piface__transfer(SPI_WRITE_CMD, OUTPUT_PORT, state->buffer_output = val); } static unsigned char piface__read_output(void) { return state->buffer_output = piface__transfer(SPI_READ_CMD, OUTPUT_PORT, 0xFF); } static unsigned char piface__read_input(void) { return state->buffer_input = piface__transfer(SPI_READ_CMD, INPUT_PORT, 0xFF) ^ 0xFF; } static inline int __portval_to_bool(const struct roar_service_gpio_port * port, unsigned int val) { int bit = 1 << (port->id & 0x07); return val & bit ? 1 : 0; } static inline unsigned char __render_bar(int bits) { unsigned char ret = 0; int i; // this is a generic version. As long as this is not called too often it should work fine. for (i = 0; i < bits; i++) { ret <<= 1; ret |= 1; } return ret; } // get list of gpio IDs. // buffer is passed as ids, buffer size (in elements) is passed as len. // returns the number of elements stored in ids or -1 on error. static ssize_t __list(int * ids, size_t len) { size_t i; if ( ids == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; i < len && i < NUM_PORTS; i++) ids[i] = i; return i; } // get the number of gpios. See also comments above on what. static ssize_t __num(enum roar_service_num what) { (void)what; return NUM_PORTS; // 8 inputs, 8 outputs and a a virtual bar } // get a gpio by ID. The object returned is a copy and must not be motified or freed. static int __get(int id, struct roar_service_gpio_port * port) { if ( id < 0 || id >= NUM_PORTS ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } if ( port == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } *port = state->ports[id]; return 0; } // Sets up ports. // the controler should set mode and state of port to given target mode and state. // If id is given as -1 this is about the controler. mode MUST NOT contain any // flags beside ROAR_SERVICE_GPIO_FCACHED. If ROAR_SERVICE_GPIO_FCACHED // is set it is applied all ports. static int __setup(int id, uint_least32_t mode, enum roar_service_gpio_state tstate) { size_t i; if ( id < -1 || id >= NUM_PORTS ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } if ( id == -1 ) { if ( mode != 0 && mode != ROAR_SERVICE_GPIO_FCACHED ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } switch (tstate) { case ROAR_SERVICE_GPIO_SREADY: if ( state->inited ) return 0; if ( piface__init() == -1 ) return -1; for (i = 0; i < NUM_PORTS; i++) { state->ports[i].mode |= ROAR_SERVICE_GPIO_FCACHED; state->ports[i].mode -= ROAR_SERVICE_GPIO_FCACHED; state->ports[i].mode |= mode; } return 0; case ROAR_SERVICE_GPIO_SUNINITED: if ( !state->inited ) return 0; return piface__free(); default: roar_err_set(ROAR_ERROR_INVAL); return -1; break; } } roar_err_set(ROAR_ERROR_NOSYS); return -1; } // get value of port (input or output) as int or float. static int __get_int(int id) { const struct roar_service_gpio_port * port; unsigned char val; if ( !state->inited ) { roar_err_set(ROAR_ERROR_BADSTATE); return -1; } if ( id < 0 || id >= NUM_PORTS ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } port = &(state->ports[id]); if ( port->type != ROAR_SERVICE_GPIO_TBOOL ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( port->mode & ROAR_SERVICE_GPIO_FINPUT ) { val = piface__read_input(); } else { val = piface__read_output(); } return __portval_to_bool(port, val); } static double __get_float(int id) { return __get_int(id); } // set value of output (as int or float). static int __set_int(int id, int val) { const struct roar_service_gpio_port * port; unsigned char buffer; int bit; if ( !state->inited ) { roar_err_set(ROAR_ERROR_BADSTATE); return -1; } if ( id < 0 || id >= NUM_PORTS ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } port = &(state->ports[id]); if ( !(port->mode & ROAR_SERVICE_GPIO_FOUTPUT) ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if ( val < port->irange_min || val > port->irange_max ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } switch (port->type) { case ROAR_SERVICE_GPIO_TBOOL: bit = 1 << (id & 0x07); buffer = state->buffer_output; buffer |= bit; if ( !val ) buffer -= bit; piface__write_output(buffer); return 0; break; case ROAR_SERVICE_GPIO_TINT: piface__write_output(__render_bar(val)); return 0; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } } static int __set_float(int id, double val) { return __set_int(id, val); } static struct roar_service_gpio api = { .list = __list, .num = __num, .get = __get, .setup = __setup, .get_int = __get_int, .get_float = __get_float, .set_int = __set_int, .set_float = __set_float, .convert_int = NULL, .convert_float = NULL }; ROAR_DL_PLUGIN_REG_SERVICES_GET_API(get_api, api) static const struct roar_dl_service service[1] = { { .appname = NULL, .appabi = NULL, .servicename = ROAR_SERVICE_GPIO_NAME, .serviceabi = ROAR_SERVICE_GPIO_ABI, .description = "Interface to PiFace", .flags = ROAR_DL_SERVICE_FLAGS_NONE, .userdata = NULL, .get_api = get_api } }; ROAR_DL_PLUGIN_REG_SERVICES(service); ROAR_DL_PLUGIN_START(piface) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("piface", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This plugin provides a simple interface to the PiFace board."); ROAR_DL_PLUGIN_REG_FNFUNC(ROAR_DL_FN_SERVICE); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(state, state_init); } ROAR_DL_PLUGIN_END #endif //ll �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/plugin-info.c�������������������������������������������������0000644�0001750�0001750�00000012254�12264733633�020560� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//plugin-info.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> static int static_counter = 0; int nonstatic_counter = 0; static int global_data_init = 0; static int * global_data; static void print_counter (void) { static int static_func_counter = 0; printf("static_counter=%i, nonstatic_counter=%i, static_func_counter=%i, *global_data=%i\n", static_counter, nonstatic_counter, static_func_counter, *global_data); static_counter++; nonstatic_counter++; static_func_counter++; (*global_data)++; } static void print_parameter(struct roar_dl_librarypara * para) { size_t i; char c; roar_vio_printf(roar_stdout, "version = %i (%smatching)\n", para->version, para->version == ROAR_DL_LIBPARA_VERSION ? "" : "not "); roar_vio_printf(roar_stdout, "length = %lu (%smatching)\n", (long unsigned int)para->len, para->len == sizeof(*para) ? "" : "not "); if ( para->version != ROAR_DL_LIBPARA_VERSION || para->len != sizeof(*para) ) { roar_vio_printf(roar_stdout, "Warning: Unsupported para block. Version or length missmatch.\n"); return; } roar_vio_printf(roar_stdout, "refc = %lu\n", (long unsigned int)para->refc); if ( para->argv == NULL ) { roar_vio_printf(roar_stdout, "argv[] = <not set>\n"); } else { roar_vio_printf(roar_stdout, "argv[] = <kv array>\n"); for (i = 0; i < para->argc; i++) { c = i == (para->argc - 1) ? '\\' : '|'; if ( para->argv[i].value == NULL ) { roar_vio_printf(roar_stdout, " %c- \"%s\" has no value.\n", c, para->argv[i].key); } else { roar_vio_printf(roar_stdout, " %c- \"%s\" has value \"%s\".\n", c, para->argv[i].key, para->argv[i].value); } } } roar_vio_printf(roar_stdout, para->binargv == NULL ? "binargv = <not set>\n" : "binargv = %p\n", para->binargv); roar_vio_printf(roar_stdout, para->appname == NULL ? "appname = <not set>\n" : "appname = \"%s\"\n", para->appname); roar_vio_printf(roar_stdout, para->abiversion == NULL ? "abiversion = <not set>\n" : "abiversion = \"%s\"\n", para->abiversion); roar_vio_printf(roar_stdout, para->notifycore == NULL ? "notifycore = <not set>\n" : "notifycore = %p\n", para->notifycore); roar_vio_printf(roar_stdout, para->container == NULL ? "container = <not set>\n" : "container = %p\n", para->container); roar_vio_printf(roar_stdout, para->loader == NULL ? "loader = <not set>\n" : "loader = %p\n", para->loader); roar_vio_printf(roar_stdout, para->loader_userdata == NULL ? "loader_userdata = <not set>\n" : "loader_userdata = %p\n", para->loader_userdata); } static void print_notifycore (struct roar_dl_librarypara * para) { struct roar_notify_core * tmp; tmp = roar_notify_core_swap_global(NULL); roar_notify_core_swap_global(tmp); if ( para->notifycore == NULL || para->notifycore == tmp ) { roar_vio_printf(roar_stdout, tmp == NULL ? "global notify core= <not set> (matching)\n" : "global notify core= %p (matching)\n", tmp); } else { roar_vio_printf(roar_stdout, tmp == NULL ? "global notify core= <not set> (not matching)\n" : "global notify core= %p (not matching)\n", tmp); } roar_notify_core_unref(tmp); } static void print_env(void) { const char * server = roar_libroar_get_server(); roar_vio_printf(roar_stdout, "Default server: %s%s%s\n", server == NULL ? "" : "\"", server == NULL ? "<not set>" : server, server == NULL ? "" : "\""); } static int init (struct roar_dl_librarypara * para) { print_parameter(para); print_notifycore(para); print_env(); print_counter(); return 0; } static struct roar_dl_appsched sched = { .init = init, .free = NULL, .update = NULL, .tick = NULL, .wait = NULL }; ROAR_DL_PLUGIN_START(plugin_info) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("plugin-info", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Display information about the plugin context"); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(global_data, global_data_init); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); } ROAR_DL_PLUGIN_END //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/protocol-daytime.c��������������������������������������������0000644�0001750�0001750�00000005615�12264733634�021630� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//protocol-daytime.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> static int _set_proto(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct roar_buffer * buf; void * data; ssize_t len; time_t now = time(NULL); char * date = asctime(gmtime(&now)); (void)client, (void)vio, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; len = roar_mm_strlen(date) + 1; if ( roar_buffer_new_data(&buf, len, &data) == -1 ) return -1; memcpy(data, date, len); if ( roar_buffer_moveintoqueue(obuffer, &buf) == -1 ) return -1; return 0; } static int _flushed(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { (void)client, (void)vio, (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; roar_err_set(ROAR_ERROR_NODATA); return -1; } static const struct roar_dl_proto proto = { .proto = ROAR_PROTO_DAYTIME, .description = "The Internet daytime protocol", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = _set_proto, .unset_proto = NULL, .handle = NULL, .flush = NULL, .flushed = _flushed, .status = NULL }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, proto, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_daytime) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-daytime", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of the Internet daytime protocol"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END //ll �������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/protocol-discard.c��������������������������������������������0000644�0001750�0001750�00000004466�12264733634�021610� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//protocol-discard.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> static int _handle(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { char buf[4096]; (void)client, (void)obuffer, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; if ( roar_vio_read(vio, buf, sizeof(buf)) < 1 ) { return -1; } return 0; } static const struct roar_dl_proto proto = { .proto = ROAR_PROTO_DISCARD, .description = "Discard all data send to the server", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = NULL, .unset_proto = NULL, .handle = _handle, .flush = NULL, .flushed = NULL, .status = NULL }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, proto, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_discard) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-discard", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of a dummy protocol discarding all data"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END //ll ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/protocol-echo.c�����������������������������������������������0000644�0001750�0001750�00000005622�12264733634�021110� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//protocol-echo.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> static int _handle(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct roar_buffer * buf; void * data; ssize_t len; (void)client, (void)userdata, (void)protopara, (void)protoparalen, (void)pluginpara; ROAR_DBG("_handle(client=%i, vio=%p) = ?", client, vio); if ( roar_buffer_new_data(&buf, 1024, &data) == -1 ) return -1; len = roar_vio_read(vio, data, 1024); if ( len < 1 ) { ROAR_DBG("_handle(client=%i, vio=%p) = -1 // error=%s(%i)", client, vio, roar_errorstring, roar_error); return -1; } if ( roar_buffer_set_len(buf, len) == -1 ) { ROAR_DBG("_handle(client=%i, vio=%p) = -1 // error=%s(%i)", client, vio, roar_errorstring, roar_error); roar_buffer_free(buf); return -1; } if ( roar_buffer_moveintoqueue(obuffer, &buf) == -1 ) return -1; ROAR_DBG("_handle(client=%i, vio=%p) = 0", client, vio); return 0; } static const struct roar_dl_proto proto = { .proto = ROAR_PROTO_ECHO, .description = "Send all data send to the server back to the client", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = NULL, .unset_proto = NULL, .handle = _handle, .flush = NULL, .flushed = NULL, .status = NULL }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, proto, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_echo) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-echo", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of a dummy protocol sending all data back to the sender"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END //ll ��������������������������������������������������������������������������������������������������������������roaraudio-1.0beta11/plugins/universal/protocol-http.c�����������������������������������������������0000644�0001750�0001750�00000071045�12264733635�021154� 0����������������������������������������������������������������������������������������������������ustar �phi�����������������������������phi��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//protocol-http.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include <roaraudio.h> #ifdef ROAR_HAVE_LIBUSTE #include <uste.h> #endif struct resource_handle; enum ctl_cmd { CMD_SET_CLIENTNAME }; enum status { STATUS_WAITING_FOR_HEADERS = 0, STATUS_END_OF_HEADER, STATUS_BAD_HEADER, STATUS_RUNNING_DATA, STATUS_DONE }; struct input_source { int userdata_si; void * userdata_vp; ssize_t offset; struct roar_vio_calls * vio; struct roar_vio_calls vio_store; }; struct http_client { enum status status; struct roar_buffer * input_buffer; char * method; char * proto; char * uri; char * path, * query_string; void * headersstore; struct roar_keyval * headers; ssize_t headerslen; const struct resource_handle * resource; struct input_source input; struct roar_dl_librarypara * pluginpara; int clientid; }; struct resource_handle { const char * uri; const char * rawdata; const ssize_t rawlen; const char * content_type; int (*header_send)(struct http_client * self, struct roar_buffer ** obuffer); int (*body_send)(struct http_client * self, struct roar_buffer ** obuffer); }; static struct { enum { HOSTTYPE_GENERIC = 0, HOSTTYPE_ROARD } hosttype; union { struct { int (*clients_set_name)(int id, const char * name); } roard; } hostspec; } __host = {.hosttype = HOSTTYPE_GENERIC}; static int header_send(struct roar_buffer ** obuffer, int status, const char * msg, const char * content_type, ssize_t len); static void send_errorpage(struct http_client * self, struct roar_buffer ** obuffer, int error, const char * msg); static int slow_zero_stream(struct http_client * self, struct roar_buffer ** obuffer) { struct roar_buffer * buffer; void * data; self->status = STATUS_RUNNING_DATA; if ( roar_buffer_new_data(&buffer, 1, &data) == -1 ) return -1; *((char*)data) = 0; if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) { roar_buffer_free(buffer); return -1; } return 0; } static const char * __res_vio_content_type_get(struct http_client * self, const char * indexfile) { const char * point = strrchr(indexfile != NULL ? indexfile : self->path, '.'); if ( point == NULL ) return NULL; point++; #define __type1(mime,ext) \ } else if ( !strcmp(point, (ext)) ) { \ return (mime); #define __type2(mime,ext0,ext1) \ } else if ( !strcmp(point, (ext0)) || !strcmp(point, (ext1)) ) { \ return (mime); #ifdef __FIX_VIM_SYNTAX_HIGHLIGHTING__ } #endif if ( !strcmp(point, "txt") || !strcmp(point, "text") ) { return "text/plain"; __type2("text/html", "html", "htm") __type1("text/css", "css") __type1("image/png", "png") __type2("image/jpeg", "jpeg", "jpg") } return NULL; } #ifdef ROAR_HAVE_LIBUSTE static uste_var_t __res_vio_handle_uste_build_headers(struct http_client * self) { uste_var_t root = uste_var_new_kv(); uste_var_t var; ssize_t i; if ( root == NULL ) return NULL; uste_var_set_key(root, "header"); for (i = 0; i < self->headerslen; i++) { var = uste_var_new_str(self->headers[i].value == NULL ? "" : self->headers[i].value); if ( self->headers[i].key != NULL ) uste_var_set_key(var, self->headers[i].key); uste_var_push(root, var); uste_var_unref(var); } return root; } static inline int __is_hex(char c) { if ( c >= '0' && c <= '9' ) return 1; if ( c >= 'a' && c <= 'f' ) return 1; if ( c >= 'A' && c <= 'F' ) return 1; return 0; } static inline int __hex2num(char c) { if ( c >= '0' && c <= '9' ) return c - '0'; if ( c >= 'a' && c <= 'f' ) return c - 'a' + 10; if ( c >= 'A' && c <= 'F' ) return c - 'A' + 10; return 0; } static void __res_vio_handle_uste_uridecode(char * str) { const char * c = str; for (; *c; c++, str++) { if ( *c == '%' && __is_hex(c[1]) && __is_hex(c[2]) ) { *str = __hex2num(c[1])*16 + __hex2num(c[2]); c += 2; } else if ( *c == '+' ) { *str = ' '; } else { *str = *c; } } *str = *c; } static void __res_vio_handle_uste_keyify(char * str) { if ( *str == '#' ) *str = '_'; for (;*str; str++) if (*str == '.') *str = '_'; } static uste_var_t __res_vio_handle_uste_build_getparams(struct http_client * self) { uste_var_t root = uste_var_new_kv(); uste_var_t subroot; uste_var_t var; char * qs_buffer; char * cur; char * state; char * key, * value; if ( root == NULL ) return NULL; uste_var_set_key(root, "get"); if ( self->query_string == NULL ) return root; qs_buffer = roar_mm_strdup(self->query_string); // do better handling here. if ( qs_buffer == NULL ) return root; cur = roar_mm_strtok_r(qs_buffer, "&", &state); while (cur != NULL) { key = cur; value = strstr(cur, "="); if ( value != NULL ) { *value = 0; value++; __res_vio_handle_uste_uridecode(value); } __res_vio_handle_uste_uridecode(key); __res_vio_handle_uste_keyify(key); if ( value == NULL ) { var = uste_var_new_undef(); } else { var = uste_var_new_str(value); } subroot = uste_var_pull(root, key); if ( subroot == NULL ) { subroot = uste_var_new_array(); if ( subroot != NULL ) { uste_var_set_key(subroot, key); uste_var_push(root, subroot); } } if ( subroot != NULL ) { uste_var_push(subroot, var); uste_var_unref(subroot); } uste_var_unref(var); cur = roar_mm_strtok_r(NULL, "&", &state); } roar_mm_free(qs_buffer); return root; } static uste_var_t __res_vio_handle_uste_build_rootkv(struct http_client * self) { uste_var_t root = uste_var_new_kv(); uste_var_t subroot, subsubroot; uste_var_t var; if ( root == NULL ) return NULL; #define __new_member_prefix(prefix,name) \ if ( prefix->name != NULL ) { \ var = uste_var_new_str(prefix->name); \ uste_var_set_key(var, #name); \ uste_var_push(subsubroot, var); \ uste_var_unref(var); \ } #define __new_member(name) __new_member_prefix(self,name) subroot = uste_var_new_kv(); if ( subroot != NULL ) { uste_var_set_key(subroot, "__client__"); uste_var_push(root, subroot); var = uste_var_new_int(self->clientid); uste_var_set_key(var, "clientid"); uste_var_push(subroot, var); uste_var_unref(var); subsubroot = uste_var_new_kv(); if ( subsubroot != NULL ) { uste_var_set_key(subsubroot, "http"); uste_var_push(subroot, subsubroot); __new_member(method); __new_member(proto); __new_member(uri); __new_member(path); __new_member(query_string); var = __res_vio_handle_uste_build_headers(self); uste_var_push(subsubroot, var); uste_var_unref(var); var = __res_vio_handle_uste_build_getparams(self); uste_var_push(subsubroot, var); uste_var_unref(var); uste_var_unref(subsubroot); } uste_var_unref(subroot); } subroot = uste_var_new_kv(); if ( subroot != NULL ) { uste_var_set_key(subroot, "__host__"); uste_var_push(root, subroot); subsubroot = subroot; __new_member_prefix(self->pluginpara, appname); __new_member_prefix(self->pluginpara, abiversion); uste_var_unref(subroot); } return root; } static void __res_vio_handle_uste(struct http_client * self, struct roar_buffer ** obuffer, const char * content_type, const char * filename) { struct roar_buffer * buffer = NULL; uste_renderer_t renderer; uste_parser_t parser; uste_var_t rootkv; uste_node_t root; int err; parser = uste_parser_new(self->input.vio, filename); err = roar_error; roar_vio_close(self->input.vio); if ( parser == NULL ) { send_errorpage(self, obuffer, err, NULL); return; } if ( uste_parser_parse(parser) == -1 ) { send_errorpage(self, obuffer, roar_error, NULL); return; } root = uste_parser_get_rootnode(parser); err = roar_error; uste_parser_unref(parser); if ( root == NULL ) { send_errorpage(self, obuffer, err, NULL); return; } renderer = uste_renderer_new(); err = roar_error; if ( renderer == NULL ) { uste_node_unref(root); send_errorpage(self, obuffer, err, NULL); return; } uste_stdfunc_register_all(renderer); uste_libroar_register_all(renderer); rootkv = __res_vio_handle_uste_build_rootkv(self); err = roar_error; if ( rootkv == NULL ) { uste_node_unref(root); uste_renderer_unref(renderer); send_errorpage(self, obuffer, err, NULL); return; } uste_renderer_set_rootvar(renderer, rootkv); uste_var_unref(rootkv); buffer = uste_node_render(root, renderer); err = roar_error; uste_node_unref(root); uste_renderer_unref(renderer); if ( buffer == NULL ) { send_errorpage(self, obuffer, err, NULL); return; } header_send(obuffer, 200, NULL, content_type, -1); if ( buffer != NULL ) { if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) { roar_buffer_free(buffer); return; } } self->status = STATUS_DONE; } #endif static int __res_vio_check_uste(struct http_client * self, struct roar_buffer ** obuffer, const char * content_type) { const size_t len = 14; struct roar_buffer * buffer; void * data; ssize_t ret; int err; // TODO: use content type for some basic filtering. (void)content_type; *obuffer = NULL; if ( roar_buffer_new_data(&buffer, len, &data) == -1 ) return -1; ret = roar_vio_read(self->input.vio, data, len); err = roar_error; if ( ret < 1 ) { roar_buffer_free(buffer); roar_error = err; return -1; } *obuffer = buffer; if ( ret == (ssize_t)len ) { return !strncmp(data, "@@@TEMPLATE@@@", len); } else { if ( roar_buffer_set_len(buffer, ret) == -1 ) { *obuffer = NULL; roar_buffer_free(buffer); return -1; } // is this really a nice idea? return 0; } } static int __res_vio_header_send(struct http_client * self, struct roar_buffer ** obuffer) { static const char * index_files[] = {NULL, "index.html", "index.txt", "index"}; struct roar_buffer * buffer; struct roar_keyval * path; char filename[1024]; const char * slash = "/"; const char * content_type = NULL; int uste_check; size_t i; const char * indexfile = NULL; if ( self->pluginpara == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } path = roar_keyval_lookup(self->pluginpara->argv, "webroot", self->pluginpara->argc, 1); if ( path == NULL ) { if ( roar_error == ROAR_ERROR_NOENT ) roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( path->value == NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( strstr(self->path, "..") != NULL || strstr(self->path, "#") != NULL ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( (roar_mm_strlen(path->value) + roar_mm_strlen(self->path) + 2) > sizeof(filename) ) { roar_err_set(ROAR_ERROR_NAMETOOLONG); return -1; } if ( self->path[0] == '/' || path->value[strlen(path->value)-1] == '/' ) slash = ""; uste_check = -1; for (i = 0; uste_check == -1 && i < (sizeof(index_files)/sizeof(*index_files)); i++) { indexfile = index_files[i]; snprintf(filename, sizeof(filename), "%s%s%s%s%s", path->value, slash, self->path, indexfile == NULL ? "" : "/", indexfile == NULL ? "" : indexfile); self->input.vio = &(self->input.vio_store); if ( roar_vio_open_dstr_simple(self->input.vio, filename, ROAR_VIOF_READ|ROAR_VIOF_NONBLOCK) == -1 ) { continue; } if ( roar_vio_ctl(self->input.vio, ROAR_VIO_CTL_GET_MIMETYPE, &content_type) == -1 ) content_type = NULL; if ( content_type == NULL ) content_type = __res_vio_content_type_get(self, indexfile); uste_check = __res_vio_check_uste(self, &buffer, content_type); if ( uste_check == -1 ) roar_vio_unref(self->input.vio); } if ( uste_check == -1 ) return -1; if ( uste_check == 1 ) { if ( buffer != NULL ) roar_buffer_free(buffer); #ifdef ROAR_HAVE_LIBUSTE __res_vio_handle_uste(self, obuffer, content_type, filename); return 0; #else roar_vio_close(self->input.vio); send_errorpage(self, obuffer, ROAR_ERROR_NOSYS, NULL); return 0; #endif } header_send(obuffer, 200, NULL, content_type, -1); if ( buffer != NULL ) { if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) { roar_buffer_free(buffer); return -1; } } self->status = STATUS_RUNNING_DATA; return 0; } static int __res_vio_body_send(struct http_client * self, struct roar_buffer ** obuffer) { const size_t len = 1024; struct roar_buffer * buffer; void * data; ssize_t ret; if ( self->status == STATUS_DONE ) return 0; if ( roar_buffer_new_data(&buffer, len, &data) == -1 ) return -1; ret = roar_vio_read(self->input.vio, data, len); if ( ret == -1 && roar_error == ROAR_ERROR_AGAIN ) { ret = 0; } else if ( ret < 1 ) { roar_buffer_free(buffer); if ( roar_error != ROAR_ERROR_AGAIN ) { self->status = STATUS_DONE; roar_vio_close(self->input.vio); } return 0; } if ( roar_buffer_set_len(buffer, ret) == -1 ) { roar_buffer_free(buffer); return -1; } if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) { roar_buffer_free(buffer); return -1; } return 0; } static const struct resource_handle _g_resources[] = { { .uri = "/test/*", .rawdata = "Hello world!\n", .rawlen = 13, .content_type = NULL, .header_send = NULL, .body_send = NULL }, { .uri = "/szs/*", .rawdata = NULL, .rawlen = -1, .content_type = NULL, .header_send = NULL, .body_send = slow_zero_stream }, { .uri = "*", .rawdata = NULL, .rawlen = -1, .content_type = NULL, .header_send = __res_vio_header_send, .body_send = __res_vio_body_send } }; static inline int __ret(struct http_client * self, struct roar_buffer ** obuffer) { ROAR_DBG("__ret(self=%p, obuffer=%p{%p}): self->status=%i", self, obuffer, *obuffer, (int)self->status); if ( *obuffer != NULL ) return 0; if ( self->status == STATUS_DONE ) return -1; return 0; } static int __ctl(struct http_client * self, enum ctl_cmd cmd, void * argp) { switch (cmd) { case CMD_SET_CLIENTNAME: if ( argp == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } ROAR_DBG("__ctl(self=%p, cmd=%i, argp='%s') = ?", self, (int)cmd, (const char *)argp); switch (__host.hosttype) { case HOSTTYPE_GENERIC: roar_err_set(ROAR_ERROR_BADHOST); return -1; break; case HOSTTYPE_ROARD: __host.hostspec.roard.clients_set_name(self->clientid, argp); break; } break; } roar_err_set(ROAR_ERROR_BADRQC); return -1; } static void __init(struct roar_dl_librarypara * para) { // TODO add some init code here. if ( para == NULL ) return; if ( !roar_dl_para_check_version(para, "roard <0/RoarAudio>", "1.0beta8") ) { __host.hosttype = HOSTTYPE_ROARD; __host.hostspec.roard.clients_set_name = roar_dl_getsym(ROAR_DL_HANDLE_APPLICATION, "clients_set_name", -1); // check if *all* function have been found: if ( __host.hostspec.roard.clients_set_name == NULL ) { __host.hosttype = HOSTTYPE_GENERIC; } } } // this function is a wrapper for __init() with the code which should be inlined. static inline void _init(struct roar_dl_librarypara * para) { static int inited = 0; if (inited) return; __init(para); inited = 1; } static const struct resource_handle * resource_lookup_by_uri(const char * uri) { size_t i; for (i = 0; i < (sizeof(_g_resources)/sizeof(*_g_resources)); i++) { if ( !roar_mm_strselcmp(_g_resources[i].uri, uri) ) { return &(_g_resources[i]); } } roar_err_set(ROAR_ERROR_NOENT); return NULL; } static int resource_header_send(struct http_client * self, struct roar_buffer ** obuffer) { if ( self->resource->header_send != NULL ) return self->resource->header_send(self, obuffer); return header_send(obuffer, 200, NULL, self->resource->content_type, self->resource->rawlen); } static int resource_body_send(struct http_client * self, struct roar_buffer ** obuffer) { struct roar_buffer * buffer; void * data; int ret; if ( self->resource->body_send != NULL ) return self->resource->body_send(self, obuffer); if ( self->resource->rawlen == -1 ) { self->status = STATUS_DONE; roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( roar_buffer_new_data(&buffer, self->resource->rawlen, &data) == -1 ) { self->status = STATUS_DONE; return -1; } memcpy(data, self->resource->rawdata, self->resource->rawlen); ret = roar_buffer_moveintoqueue(obuffer, &buffer); self->status = STATUS_DONE; return ret; } static int header_parse(struct http_client * self) { void * data; size_t len; size_t i; char * start, * end; char * start_uri; char * start_headers, * end_headers = NULL; char * tmp; struct roar_keyval * c; if ( roar_buffer_get_datalen(self->input_buffer, &data, &len) == -1 ) return -1; ROAR_DBG("header_parse(self=%p): data='%*s'", self, (int)len, (const char*)data); if ( len < 4 ) return 0; for (i = 0; i < (len - 3); i++) { if ( ((const char*)data)[i] == '\r' ) { ROAR_DBG("header_parse(self=%p): i=%i", self, (int)i); if ( !strncmp(data + i, "\r\n\r\n", 4) ) { self->status = STATUS_END_OF_HEADER; end_headers = data + i; break; } } } if ( self->status != STATUS_END_OF_HEADER ) { for (i = 0; i < (len - 1); i++) { if ( ((const char*)data)[i] == '\n' ) { ROAR_DBG("header_parse(self=%p): i=%i", self, (int)i); if ( !strncmp(data + i, "\n\n", 2) ) { self->status = STATUS_END_OF_HEADER; end_headers = data + i; break; } } } } if ( self->status != STATUS_END_OF_HEADER ) return 0; *end_headers = 0; end = strstr(data, " "); if ( end == NULL ) { self->status = STATUS_BAD_HEADER; return 1; } *end = 0; end++; self->method = roar_mm_strdup(data); start = end; end = strstr(start, " "); if ( end == NULL ) { self->status = STATUS_BAD_HEADER; return 1; } *end = 0; end++; self->uri = roar_mm_strdup(start); start_uri = start; start = end; end = strstr(start, "\r"); if ( end == NULL ) end = strstr(start, "\n"); if ( end == NULL ) { self->status = STATUS_BAD_HEADER; return 1; } *end = 0; end++; self->proto = roar_mm_strdup(start); start_headers = end; start = start_uri; end = strstr(start, "?"); if ( end == NULL ) { self->path = roar_mm_strdup(start); } else { *end = 0; end++; self->path = roar_mm_strdup(start); self->query_string = roar_mm_strdup(end); } self->headerslen = 0; i = end_headers - start_headers + 1; self->headersstore = roar_mm_memdup(start_headers, i); if ( self->headersstore == NULL ) { self->status = STATUS_BAD_HEADER; // TODO: FIXME: not the right error, but works. ;) return -1; } start_headers = self->headersstore; end_headers = start_headers + i; for (tmp = start_headers; tmp < end_headers;) { for (; tmp < end_headers && (*tmp == '\r' || *tmp == '\n'); tmp++); if ( tmp == end_headers ) break; self->headerslen++; for (; tmp < end_headers && !(*tmp == '\r' || *tmp == '\n'); tmp++); } ROAR_DBG("header_parse(self=%p): self->headerslen=%i", self, (int)self->headerslen); self->headers = roar_mm_malloc(sizeof(struct roar_keyval)*(self->headerslen+1)); if ( self->headers == NULL ) { self->status = STATUS_BAD_HEADER; // TODO: FIXME: not the right error, but works. ;) return -1; } memset(self->headers, 0, sizeof(struct roar_keyval)*(self->headerslen+1)); c = self->headers; for (tmp = start_headers; tmp < end_headers;) { ROAR_DBG("header_parse(self=%p): tmp='%s'", self, tmp); for (; tmp < end_headers && (*tmp == '\r' || *tmp == '\n'); tmp++) *tmp = '\0'; if ( tmp == end_headers ) break; ROAR_DBG("header_parse(self=%p): tmp='%s'", self, tmp); c->key = tmp; ROAR_DBG("header_parse(self=%p): c->key='%s'", self, c->key); for (; tmp < end_headers && !(*tmp == '\r' || *tmp == '\n' || *tmp == ':'); tmp++); c->value = tmp; for (; tmp < end_headers && !(*tmp == '\r' || *tmp == '\n'); tmp++); c++; } c->key = NULL; c->value = NULL; for (i = 0; i < (size_t)self->headerslen; i++) { c = &(self->headers[i]); if ( c->value[0] == '\0' ) { c->value = NULL; continue; } c->value[0] = '\0'; c->value++; for (; c->value[0] == ' '; c->value++); if ( c->value[0] == '\0' ) c->value = NULL; } return 1; } static int header_send(struct roar_buffer ** obuffer, int status, const char * msg, const char * content_type, ssize_t len) { struct roar_buffer * buffer; size_t bufferlen = 1024; void * data; char buffer_len[64]; if ( roar_buffer_new_data(&buffer, bufferlen, &data) == -1 ) return -1; if ( msg == NULL ) { switch (status) { case 200: msg = "OK"; break; case 400: msg = "Bad Request"; break; case 404: msg = "File not found"; break; case 500: msg = "Internal server error"; break; default: msg = "<<<unknown status code>>>"; break; } } if ( content_type == NULL ) content_type = "text/plain"; if ( len == (ssize_t)-1 ) { buffer_len[0] = 0; } else { snprintf(buffer_len, sizeof(buffer_len), "Content-Length: %lu\r\n", (long unsigned int)len); } /* Date: Sun, 29 Jul 2012 01:08:15 GMT Cache-Control: no-cache,no-store Content-Type: text/html; charset=%s */ snprintf(data, bufferlen, "HTTP/1.0 %i %s\r\n" "Server: protocol-http (libroar plugin)\r\n" "Connection: close\r\n" "Content-Type: %s\r\n" "%s" "\r\n", status, msg, content_type, buffer_len ); if ( roar_buffer_set_len(buffer, roar_mm_strlen(data)) == -1 ) { roar_buffer_free(buffer); return -1; } if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) { roar_buffer_free(buffer); return -1; } return 0; } static void send_errorpage(struct http_client * self, struct roar_buffer ** obuffer, int error, const char * msg) { struct roar_buffer * buffer; const size_t bufferlen = 1024; void * data; int httperror; if ( roar_err_convert(&httperror, ROAR_ERROR_TYPE_HTTP, error, ROAR_ERROR_TYPE_ROARAUDIO) == -1 ) httperror = 500; if ( msg == NULL ) msg = roar_error2str(error); // send header and mark as done early so we can just return in case some of the later calls fail. header_send(obuffer, httperror, msg, "text/html", -1); self->status = STATUS_DONE; if ( roar_buffer_new_data(&buffer, bufferlen, &data) == -1 ) return; snprintf(data, bufferlen, "<html>\n" " <head><title>%i - %s\n" " \n" "

%i - %s


\n" " \n" "", httperror, msg, httperror, msg); _LIBROAR_IGNORE_RET(roar_buffer_set_len(buffer, roar_mm_strlen(data))); if ( roar_buffer_moveintoqueue(obuffer, &buffer) == -1 ) roar_buffer_free(buffer); } static void handle_client(struct http_client * self, struct roar_buffer ** obuffer) { struct roar_keyval * kv; // meta stuff: // try to set client name. kv = roar_keyval_lookup(self->headers, "user-agent", self->headerslen, 0); if ( kv != NULL && kv->value != NULL ) { __ctl(self, CMD_SET_CLIENTNAME, kv->value); } // first try lookup including query string. if nothing is found // retry search with only resource path. self->resource = resource_lookup_by_uri(self->uri); if ( self->resource == NULL ) self->resource = resource_lookup_by_uri(self->path); if ( self->resource == NULL ) { send_errorpage(self, obuffer, roar_error, NULL); return; } if ( resource_header_send(self, obuffer) == -1 ) { send_errorpage(self, obuffer, roar_error, NULL); return; } resource_body_send(self, obuffer); //send_errorpage(self, obuffer, ROAR_ERROR_CAUSALITY, NULL); // send_errorpage(self, obuffer, roar_random_uint16() % ROAR_ERROR_BADLICENSE, NULL); return; } static int _set_proto(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct http_client * self = roar_mm_malloc(sizeof(struct http_client)); (void)vio, (void)protopara, (void)protoparalen; if ( self == NULL ) return -1; _init(pluginpara); memset(self, 0, sizeof(*self)); self->status = STATUS_WAITING_FOR_HEADERS; self->headerslen = (ssize_t)-1; self->clientid = client; if ( pluginpara != NULL ) { roar_dl_para_ref(pluginpara); self->pluginpara = pluginpara; } *userdata = self; return __ret(self, obuffer); } static int _unset_proto(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct http_client * self = *userdata; (void)client, (void)vio, (void)obuffer, (void)protopara, (void)protoparalen, (void)pluginpara; if ( self->input_buffer != NULL ) roar_buffer_free(self->input_buffer); if ( self->method != NULL ) roar_mm_free(self->method); if ( self->proto != NULL ) roar_mm_free(self->proto); if ( self->uri != NULL ) roar_mm_free(self->uri); if ( self->path != NULL ) roar_mm_free(self->path); if ( self->query_string != NULL ) roar_mm_free(self->query_string); if ( self->headersstore != NULL ) roar_mm_free(self->headersstore); if ( self->headers != NULL ) roar_mm_free(self->headers); if ( self->pluginpara != NULL ) roar_dl_para_unref(self->pluginpara); roar_mm_free(self); *userdata = NULL; return 0; } #define _INCREMENT 256 static int _handle(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct http_client * self = *userdata; void * data; size_t oldlen; ssize_t ret; (void)client, (void)protopara, (void)protoparalen, (void)pluginpara; if ( self->status != STATUS_WAITING_FOR_HEADERS ) return __ret(self, obuffer); if ( self->input_buffer == NULL ) { if ( roar_buffer_new_data(&(self->input_buffer), _INCREMENT, &data) == -1 ) return -1; oldlen = 0; } else { if ( roar_buffer_get_len(self->input_buffer, &oldlen) == -1 ) return -1; if ( roar_buffer_set_len(self->input_buffer, oldlen + _INCREMENT) == -1 ) return -1; if ( roar_buffer_get_data(self->input_buffer, &data) == -1 ) return -1; } data += oldlen; ret = roar_vio_read(vio, data, _INCREMENT); if ( ret == (ssize_t)-1 ) { // we can safely ignore return value here as we return error anyway. _LIBROAR_IGNORE_RET(roar_buffer_set_len(self->input_buffer, oldlen)); return -1; } if ( roar_buffer_set_len(self->input_buffer, oldlen + ret) == -1 ) { ROAR_WARN("_handle(*): Can not reset buffer length. BAD. Error was: %s", roar_errorstring); return -1; } header_parse(self); if ( self->status == STATUS_BAD_HEADER ) { header_send(obuffer, 400, NULL, NULL, -1); self->status = STATUS_DONE; } else if ( self->status == STATUS_END_OF_HEADER ) { handle_client(self, obuffer); } return __ret(self, obuffer); } // this is a dummy function only used to kill the client after all data has been flushed. static int _flushed(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { struct http_client * self = *userdata; (void)client, (void)vio, (void)protopara, (void)protoparalen, (void)pluginpara; ROAR_DBG("_flushed(*) = ?"); if ( self->status == STATUS_RUNNING_DATA ) resource_body_send(self, obuffer); return __ret(self, obuffer); } static const struct roar_dl_proto proto = { .proto = ROAR_PROTO_HTTP, .description = "Hyper Text Transfer Protocol", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = _set_proto, .unset_proto = _unset_proto, .handle = _handle, .flush = NULL, .flushed = _flushed, .status = NULL }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, proto, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_http) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-http", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of the HTTP Protocol"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END //ll roaraudio-1.0beta11/plugins/universal/service-about.c0000644000175000017500000000465112264733635021105 0ustar phiphi//service-about.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2013-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include static int __show(const struct roar_dl_libraryname * libname) { struct roar_vio_calls * vio = roar_stdout; roar_vio_printf(vio, "---[ About %s ]---\n", libname->name); #define _var(x,y) \ if ( libname->x != NULL ) \ roar_vio_printf(vio, " %-16s: %s\n", y, libname->x); _var(libname, "Full Name"); _var(libversion, "Full Version"); _var(abiversion, "ABI Version"); _var(description, "Description"); _var(contact, "Contact"); _var(authors, "Other Authors"); _var(license, "License"); roar_vio_printf(vio, "---[ End of About ]---\n"); return 0; } static struct roar_service_about api = {.show = __show}; ROAR_DL_PLUGIN_REG_SERVICES_GET_API(get_api, api) static const struct roar_dl_service service[1] = { { .appname = NULL, .appabi = NULL, .servicename = ROAR_SERVICE_ABOUT_NAME, .serviceabi = ROAR_SERVICE_ABOUT_ABI, .description = "About dialog display API", .flags = ROAR_DL_SERVICE_FLAGS_NONE, .userdata = NULL, .get_api = get_api } }; ROAR_DL_PLUGIN_REG_SERVICES(service); ROAR_DL_PLUGIN_START(service_about) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("service-about", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This plugin provides a simple interface to about dialog display functions."); ROAR_DL_PLUGIN_REG_FNFUNC(ROAR_DL_FN_SERVICE); } ROAR_DL_PLUGIN_END //ll roaraudio-1.0beta11/plugins/universal/tic-tac-toe.c0000644000175000017500000002564012264733635020447 0ustar phiphi//tic-tac-toe.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define _FREE ' ' #define _PLAYER 'X' #define _COMPUTER 'O' #define _NOBODY '#' #define _DISPLAY \ /* Bring Telnet in right mode: */ \ /* IAC WILL ECHO IAC WILL SUPPRESS_GO_AHEAD IAC WONT LINEMODE */ \ /* 255 251 1 255 251 3 255 252 34 */ \ "\377\373\001\377\373\003\377\374\042" \ "\e[2J\e[H" \ " Tic Tac Toe\r\n" \ " (running: %s, API: %s)\r\n" \ "\r\n" \ "Game board: IDs:\r\n" \ " %c | %c | %c 7 | 8 | 9\r\n" \ "---+---+--- ---+---+---\r\n" \ " %c | %c | %c 4 | 5 | 6\r\n" \ "---+---+--- ---+---+---\r\n" \ " %c | %c | %c 1 | 2 | 3\r\n" \ "\r\n" \ "%s\r\n" #define _DISPLAY_BUFFER_LEN 1024 #define _HELP \ "\e[2J\e[H" \ " Tic Tac Toe\r\n" \ " (running: roard " ROAR_VERSION_STRING ")\r\n" \ "\r\n" \ "IDs: Alternative IDs:\r\n" \ " 7 | 8 | 9 a | s | d\r\n" \ "---+---+--- ---+---+---\r\n" \ " 4 | 5 | 6 f |SPC| h\r\n" \ "---+---+--- ---+---+---\r\n" \ " 1 | 2 | 3 j | k | l\r\n" \ "\r\n" \ "Other keys:\r\n" \ " q g , . - Quit\r\n" \ " n + - New game\r\n" \ " H 0 - Help\r\n" \ " e - Exit help / Redraw game\r\n" \ "\r\n" \ "%s\r\n" #define MSG__YOUR_TURN "It's your turn. -- press any ID or H for help, q to quit --" #define MSG__CANNOT_PUT_HERE "You can not put your mark here. -- try again another position --" #define MSG__WON_PLAYER "You won. -- press any key to continue or H for help, q to quit --" #define MSG__WON_COMPUTER "I won. -- press any key to continue or H for help, q to quit --" #define MSG__WON_NOBODY "Nobody won. -- press any key to continue or H for help, q to quit --" #define MSG__HELP "-- press e to continue or q to quit --" typedef char game_state[9]; struct test_result { int score_player, score_computer; int free; }; struct stats { int free; struct test_result results[9]; }; static void new_game(game_state * state) { memset(state, _FREE, sizeof(game_state)); } static int try_put(game_state * state, int id, char player) { if ( id < 0 || id > 8 ) return -1; if ( (*state)[id] == _FREE ) { (*state)[id] = player; return 0; } else { return -1; } }; static void analyze(struct stats * stats, game_state * state) { static const int textvec[3][3][2] = { {{0, 3}, {1, 3}, {2, 3}}, {{0, 1}, {3, 1}, {6, 1}}, {{0, 1}, {4, 0}, {8, -1}} }; struct test_result * res; int i, j; int test; stats->free = 0; for (i = 0; i < 9; i++) if ( (*state)[i] == _FREE ) stats->free++; for (test = 0; test < 3; test++) { for (i = 0; i < 3; i++) { res = &(stats->results[i+test*3]); res->score_player = 0; res->score_computer = 0; res->free = -1; for (j = 0; j < 3; j++) { switch ((*state)[textvec[test][j][0] + textvec[test][j][1]*i]) { case _PLAYER: res->score_player++; break; case _COMPUTER: res->score_computer++; break; case _FREE: res->free = textvec[test][j][0] + textvec[test][j][1]*i; break; } } } } } static char check_won(game_state * state) { struct stats stats; int i; analyze(&stats, state); for (i = 0; i < 9; i++) { if ( stats.results[i].score_player == 3 ) return _PLAYER; if ( stats.results[i].score_computer == 3 ) return _COMPUTER; } if ( stats.free == 0) return _NOBODY; return 0; } static void auto_move(game_state * state, int player_move) { static const int corner[4] = {0, 2, 6, 8}; static const int side[4] = {1, 3, 5, 7}; struct stats stats; struct test_result * res; int i; analyze(&stats, state); // step 0: try to win. for (i = 0; i < 9; i++) { res = &(stats.results[i]); if ( res->score_computer == 2 && res->free != -1 ) { if ( try_put(state, res->free, _COMPUTER) == 0 ) return; } } // step 1: block winning for (i = 0; i < 9; i++) { res = &(stats.results[i]); if ( res->score_player == 2 && res->free != -1 ) { if ( try_put(state, res->free, _COMPUTER) == 0 ) return; } } // step 2: fork // TODO: implement // step 3: block forking // TODO: implement // step 4: play center if ( try_put(state, 4, _COMPUTER) == 0 ) return; // step 5: "Opposite corner" for (i = 0; i < 4; i++) if ( player_move == corner[i] ) if ( try_put(state, 8 - player_move, _COMPUTER) == 0 ) return; // step 6: Empty corner for (i = 0; i < 4; i++) if ( try_put(state, corner[i], _COMPUTER) == 0 ) return; // step 7: Empty side for (i = 0; i < 4; i++) if ( try_put(state, side[i], _COMPUTER) == 0 ) return; } static void draw_help(struct roar_buffer ** obuffer) { struct roar_buffer * buf; ssize_t len = 0; void * data; if ( roar_buffer_new_data(&buf, _DISPLAY_BUFFER_LEN, &data) == -1 ) return; snprintf(data, _DISPLAY_BUFFER_LEN, _HELP, MSG__HELP); len = roar_mm_strlen(data); if ( roar_buffer_set_len(buf, len) == -1 ) { roar_buffer_free(buf); } _LIBROAR_IGNORE_RET(roar_buffer_moveintoqueue(obuffer, &buf)); } static void draw_game(game_state * state, const char * info, struct roar_buffer ** obuffer, struct roar_dl_librarypara * pluginpara) { struct roar_buffer * buf; ssize_t len = 0; void * data; if ( roar_buffer_new_data(&buf, _DISPLAY_BUFFER_LEN, &data) == -1 ) return; snprintf(data, _DISPLAY_BUFFER_LEN, _DISPLAY, pluginpara == NULL || pluginpara->appname == NULL ? "" : pluginpara->appname, pluginpara == NULL || pluginpara->abiversion == NULL ? "" : pluginpara->abiversion, (*state)[0], (*state)[1], (*state)[2], (*state)[3], (*state)[4], (*state)[5], (*state)[6], (*state)[7], (*state)[8], info); len = roar_mm_strlen(data); if ( roar_buffer_set_len(buf, len) == -1 ) { roar_buffer_free(buf); } _LIBROAR_IGNORE_RET(roar_buffer_moveintoqueue(obuffer, &buf)); } static int _set_proto(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { game_state * state; (void)client, (void)vio, (void)obuffer, (void)protopara, (void)protoparalen; ROAR_DBG("_set_proto(*) = ?"); state = roar_mm_malloc(sizeof(game_state)); if ( state == NULL ) return -1; new_game(state); *userdata = state; draw_game(state, MSG__YOUR_TURN, obuffer, pluginpara); ROAR_DBG("_set_proto(client=%i, vio=%p, obuffer=%p, userdata=%p{%p}, protopara=%p, protoparalen=?, pluginpara=%p) = 0", client, vio, obuffer, userdata, *userdata, protopara, pluginpara); return 0; } static char map_input(char c) { switch (c) { case ',': case '.': case 'g': return 'q'; break; case 'a': return '0'; break; case 's': return '1'; break; case 'd': return '2'; break; case 'f': return '3'; break; case ' ': return '4'; break; case 'h': return '5'; break; case 'j': return '6'; break; case 'k': return '7'; break; case 'l': return '8'; break; case '+': return 'n'; break; case '0': return 'H'; break; } if ( c > '9' ) return c; if ( c >= '7' ) return c - 7; if ( c >= '4' ) return c - 1; if ( c >= '1' ) return c + 5; return c; } static int _handle(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * protopara, ssize_t protoparalen, struct roar_dl_librarypara * pluginpara) { char buf[32]; ssize_t len; ssize_t i; const char * msg = MSG__YOUR_TURN; char won; int player_move = -1; char c; (void)client, (void)obuffer, (void)protopara, (void)protoparalen; ROAR_DBG("_handle(client=%i, vio=%p, obuffer=%p, userdata=%p{%p}, protopara=%p, protoparalen=?, pluginpara=%p) = ?", client, vio, obuffer, userdata, *userdata, protopara, pluginpara); len = roar_vio_read(vio, buf, sizeof(buf)); if ( len < 1 ) { return -1; } if ( check_won(*userdata) ) { for (i = 0; i < len; i++) { if ( map_input(buf[i]) == 'q' ) { return -1; } else { new_game(*userdata); draw_game(*userdata, MSG__YOUR_TURN, obuffer, pluginpara); return 0; } } } for (i = 0; i < len; i++) { c = map_input(buf[i]); switch (c) { case 'q': return -1; break; case 'n': new_game(*userdata); draw_game(*userdata, MSG__YOUR_TURN, obuffer, pluginpara); return 0; break; case 'H': draw_help(obuffer); return 0; break; case 'e': draw_game(*userdata, MSG__YOUR_TURN, obuffer, pluginpara); return 0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': if ( try_put(*userdata, c - '0', _PLAYER) == -1 ) { msg = MSG__CANNOT_PUT_HERE; draw_game(*userdata, msg, obuffer, pluginpara); return 0; } else { msg = MSG__YOUR_TURN; i = len; // end the loop. player_move = c - '0'; } break; } } won = check_won(*userdata); if ( !won && player_move != -1 ) { auto_move(*userdata, player_move); won = check_won(*userdata); } switch (won) { case _PLAYER: msg = MSG__WON_PLAYER; break; case _COMPUTER: msg = MSG__WON_COMPUTER; break; case _NOBODY: msg = MSG__WON_NOBODY; break; } draw_game(*userdata, msg, obuffer, pluginpara); ROAR_DBG("check_client(client=%i, vio=%p) = 0", client, vio); return 0; } static const struct roar_dl_proto proto = { .proto = ROAR_PROTO_GAME, .description = "Simple Tic-Tac-Toe game", .flags = ROAR_DL_PROTO_FLAGS_NONE, .set_proto = _set_proto, .unset_proto = NULL, .handle = _handle, .flush = NULL, .flushed = NULL, .status = NULL }; static int __reg_proto(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) { (void)para, (void)lib; ROAR_DL_PLUGIN_REG_FN(ROAR_DL_PROTO_SUBTYPE, proto, ROAR_DL_PROTO_VERSION); return 0; } ROAR_DL_PLUGIN_START(protocol_tic_tac_toe) { ROAR_DL_PLUGIN_META_PRODUCT_NIV("protocol-tic-tac-toe", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("Implementation of a the well known game Tic-Tac-Toe"); ROAR_DL_PLUGIN_REG(ROAR_DL_FN_PROTO, __reg_proto); } ROAR_DL_PLUGIN_END //ll roaraudio-1.0beta11/plugins/xmms/0000755000175000017500000000000012267553243015135 5ustar phiphiroaraudio-1.0beta11/plugins/xmms/Makefile0000644000175000017500000000132112072575525016573 0ustar phiphiTARGET=libroar.so OBJ=roar.o gui.o include ../../Makefile.conf include ../../Makefile.inc include Makefile.conf #DEFINES=-DDEBUG CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) -I../../include $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC) $(GTK_CFLAFS) $(XMMS_CFLAGS) LDFLAGS+= $(DEBUG_g) $(Wall) $(SHARED) $(LDPATH) -L../../lib LIBS = $(LIBROAR) $(GTK_LIBS) $(XMMS_LIBS) all: ${TARGET} clean: rm -f ${TARGET} *.o new: clean all install: libroar.so mkdir -p ${DESTDIR}${INSTALL_DIR} cp libroar.so ${DESTDIR}${INSTALL_DIR}/ semi-install: libroar.so mkdir -p ${DESTDIR}${INSTALL_DIR} ln -fs `pwd`/libroar.so ${DESTDIR}${INSTALL_DIR}/ libroar.so: $(OBJ) $(CC) $(LDFLAGS) -o libroar.so $(OBJ) $(LIBS) roaraudio-1.0beta11/plugins/xmms/all.h0000644000175000017500000000454212264733636016066 0ustar phiphi//all.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of the XMMS RoarAudio output plugin a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _ALL_H_ #define _ALL_H_ #include //#include "xmms/i18n.h" #include #include #include #include #include "xmms/plugin.h" #include "xmms/xmmsctrl.h" #include "xmms/dirbrowser.h" #include "xmms/configfile.h" #include "xmms/util.h" #define _(x) (x) gint ctrlsocket_get_session_id(void); void roar_init(void); void roar_about(void); void roar_configure(void); void roar_get_volume(int *l, int *r); void roar_set_volume(int l, int r); void roar_mixer_init(void); void roar_mixer_init_vol(int l, int r); int roar_playing(void); int roar_free(void); void roar_write(void *ptr, int length); void roar_close(void); void roar_flush(int time); void roar_pause(short p); int roar_open(AFormat fmt, int rate, int nch); int roar_get_output_time(void); int roar_get_written_time(void); int roar_update_metadata(void); int roar_chk_metadata(void); #define STATE_CONNECTED 1 #define STATE_PLAYING 2 #define STATE_NORECONNECT 4 struct xmms_roar_out { int state; char * server; struct roar_connection con; struct roar_stream stream; struct roar_vio_calls vio; long unsigned int written; long unsigned int bps; int session; int pause; struct { int l, r; } mixer; struct { int server_type; int port; char * player_name; } cfg; } g_inst; #endif //ll roaraudio-1.0beta11/plugins/xmms/configure0000755000175000017500000000337211204073756017045 0ustar phiphi#!/bin/sh . ../configure.inc HAVE_ROAR=false while [ "$1" != '' ] do case "$1" in --install-dir|--inst-dir) INSTALL_DIR="$2" shift; ;; --pkg-config) PKG_CONFIG="$2" shift; ;; --force-have-roar) HAVE_ROAR=true ;; --help|-h) cat << EOF Usage: ./configure [OPTIONS]... Options: --help - Show this help --inst-dir DIR - Install dir --force-have-roar - Force to assume libroar is ok --pkg-config PKGCONF - Set filename for pkg-config EOF exit 0 ;; *) echo 'Unknown option. Try ./configure --help' exit 2 esac shift; done on_error () { exit 1; } check_cc; check_pkg_config; echo -n 'testing for gtk... ' #pkg-config #if [ "$PKG_CONFIG" != '' ] #then # GTK_LIBS=`$PKG_CONFIG --libs gtk+-2.0 2> /dev/null` # GTK_CFLAFS=`$PKG_CONFIG --cflags gtk+-2.0 2> /dev/null` #else GTK_LIBS=`gtk-config --libs 2> /dev/null` GTK_CFLAFS=`gtk-config --cflags 2> /dev/null` #fi if [ "$GTK_LIBS" = '' -a "$GTK_CFLAFS" = '' ] then echo no. on_error; else echo yes fi echo -n 'testing for xmms... ' XMMS_LIBS=`xmms-config --libs 2> /dev/null` XMMS_CFLAGS=`xmms-config --cflags 2> /dev/null` if [ "$XMMS_LIBS" = '' -a "$XMMS_CFLAGS" = '' ] then echo no. on_error; else echo yes fi echo -n 'testing for xmms plugin dir... ' if [ "$INSTALL_DIR" = '' ] then INSTALL_DIR=`xmms-config --output-plugin-dir` if [ "$INSTALL_DIR" = '' ] then echo not found. on_error; else echo "$INSTALL_DIR" fi else echo "$INSTALL_DIR" fi check_libroar; rm -f tests tests.c echo creating Makefile.conf... { echo "CC=$CC" echo echo "GTK_LIBS=$GTK_LIBS" echo "GTK_CFLAFS=$GTK_CFLAFS" echo echo "XMMS_LIBS=$XMMS_LIBS" echo "XMMS_CFLAGS=$XMMS_CFLAGS" echo echo "INSTALL_DIR=$INSTALL_DIR" } > Makefile.conf #ll roaraudio-1.0beta11/plugins/xmms/gui.c0000644000175000017500000003252012264733636016072 0ustar phiphi//gui.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of the XMMS RoarAudio output plugin a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "all.h" // ABOUT: void roar_about(void) { static GtkWidget *dialog; if (dialog != NULL) return; dialog = xmms_show_message( _("About RoarAudio Plugin"), _("RoarAudio XMMS Plugin..." ), _("OK"), FALSE, NULL, NULL); gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog); } // CONFIG: void on_button_ok_enter(GtkButton * button, gpointer user_data) { } void roar_configure(void) { GtkWidget *config_win; GtkWidget *vbox_main; GtkWidget *tabs_main; GtkWidget *frame_server; GtkWidget *alignment_server; GtkWidget *table1; GtkWidget *label_server_type; GtkWidget *label_server_host; GtkWidget *label_server_port; GtkObject *input_server_port_adj; GtkWidget *input_server_port; GtkWidget *input_server_host; GtkWidget *input_server_type; GtkWidget *label_host; GtkWidget *label_server; GtkWidget *frame_proxy; GtkWidget *alignment_proxy; GtkWidget *table2; GtkWidget *label_proxy_type; GtkWidget *label_proxy_addr; GtkWidget *input_proxy_host; GtkWidget *input_proxy_type; GtkWidget *label_frame_proxy; GtkWidget *label_proxy; GtkWidget *vbox_meta; GtkWidget *frame_meta_player; GtkWidget *alignment1; GtkWidget *hbox_meta_player; GtkWidget *label_player_name; GtkWidget *input_meta_player_name; GtkWidget *label_player; GtkWidget *frame_meta_title; GtkWidget *alignment2; GtkWidget *hbox_meta_title; GtkWidget *input_meta_send_title; GtkWidget *input_meta_send_filename; GtkWidget *label_meta_title; GtkWidget *label_meta; GtkWidget *hbox_buttons; GtkWidget *button_ok; GtkWidget *button_cancel; config_win = gtk_window_new(GTK_WINDOW_DIALOG); gtk_window_set_title(GTK_WINDOW(config_win), _("RoarAudio Plugin - Configuration")); // gtk_window_set_destroy_with_parent(GTK_WINDOW(config_win), TRUE); // gtk_window_set_icon_name(GTK_WINDOW(config_win), "gtk-preferences"); gtk_widget_show (config_win); vbox_main = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_main); gtk_container_add (GTK_CONTAINER (config_win), vbox_main); tabs_main = gtk_notebook_new (); gtk_widget_show (tabs_main); gtk_box_pack_start (GTK_BOX (vbox_main), tabs_main, TRUE, TRUE, 0); frame_server = gtk_frame_new (NULL); gtk_widget_show (frame_server); gtk_container_add (GTK_CONTAINER (tabs_main), frame_server); gtk_frame_set_shadow_type (GTK_FRAME (frame_server), GTK_SHADOW_NONE); alignment_server = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment_server); gtk_container_add (GTK_CONTAINER (frame_server), alignment_server); // gtk_alignment_set_padding (GTK_ALIGNMENT (alignment_server), 0, 0, 12, 0); table1 = gtk_table_new (3, 2, FALSE); gtk_widget_show (table1); gtk_container_add (GTK_CONTAINER (alignment_server), table1); label_server_type = gtk_label_new (_("Server Type:")); gtk_widget_show (label_server_type); gtk_table_attach (GTK_TABLE (table1), label_server_type, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_server_type), 0, 0.5); label_server_host = gtk_label_new (_("Host or Path:")); gtk_widget_show (label_server_host); gtk_table_attach (GTK_TABLE (table1), label_server_host, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_server_host), 0, 0.5); label_server_port = gtk_label_new (_("Port:")); gtk_widget_show (label_server_port); gtk_table_attach (GTK_TABLE (table1), label_server_port, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_server_port), 0, 0.5); input_server_port_adj = gtk_adjustment_new (16002, 0, 65535, 1, 10, 10); input_server_port = gtk_spin_button_new (GTK_ADJUSTMENT (input_server_port_adj), 1, 0); gtk_widget_show (input_server_port); gtk_table_attach (GTK_TABLE (table1), input_server_port, 1, 2, 2, 3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); input_server_host = gtk_entry_new (); gtk_widget_show (input_server_host); gtk_table_attach (GTK_TABLE (table1), input_server_host, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* input_server_type = gtk_combo_box_entry_new_text (); gtk_widget_show (input_server_type); gtk_table_attach (GTK_TABLE (table1), input_server_type, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); gtk_combo_box_append_text (GTK_COMBO_BOX (input_server_type), _("Local")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_server_type), _("TCP/IP")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_server_type), _("DECnet")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_server_type), _("Fork")); */ label_host = gtk_label_new (_("Host:")); gtk_widget_show (label_host); // gtk_frame_set_label_widget (GTK_FRAME (frame_server), label_host); // gtk_label_set_use_markup (GTK_LABEL (label_host), TRUE); label_server = gtk_label_new (_("Server & Network")); gtk_widget_show (label_server); gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs_main), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs_main), 0), label_server); frame_proxy = gtk_frame_new (NULL); gtk_widget_show (frame_proxy); gtk_container_add (GTK_CONTAINER (tabs_main), frame_proxy); gtk_frame_set_shadow_type (GTK_FRAME (frame_proxy), GTK_SHADOW_NONE); alignment_proxy = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment_proxy); gtk_container_add (GTK_CONTAINER (frame_proxy), alignment_proxy); // gtk_alignment_set_padding (GTK_ALIGNMENT (alignment_proxy), 0, 0, 12, 0); table2 = gtk_table_new (2, 2, FALSE); gtk_widget_show (table2); gtk_container_add (GTK_CONTAINER (alignment_proxy), table2); label_proxy_type = gtk_label_new (_("Type:")); gtk_widget_show (label_proxy_type); gtk_table_attach (GTK_TABLE (table2), label_proxy_type, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_proxy_type), 0, 0.5); label_proxy_addr = gtk_label_new (_("Proxy Address")); gtk_widget_show (label_proxy_addr); gtk_table_attach (GTK_TABLE (table2), label_proxy_addr, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_proxy_addr), 0, 0.5); input_proxy_host = gtk_entry_new (); gtk_widget_show (input_proxy_host); gtk_table_attach (GTK_TABLE (table2), input_proxy_host, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); /* input_proxy_type = gtk_combo_box_entry_new_text (); gtk_widget_show (input_proxy_type); gtk_table_attach (GTK_TABLE (table2), input_proxy_type, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); gtk_combo_box_append_text (GTK_COMBO_BOX (input_proxy_type), _("None")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_proxy_type), _("SOCKS4")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_proxy_type), _("SOCKS4a")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_proxy_type), _("SOCKS4d")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_proxy_type), _("HTTP Connect")); gtk_combo_box_append_text (GTK_COMBO_BOX (input_proxy_type), _("SSH")); */ label_frame_proxy = gtk_label_new (_("Proxy")); gtk_widget_show (label_frame_proxy); /* gtk_frame_set_label_widget (GTK_FRAME (frame_proxy), label_frame_proxy); gtk_label_set_use_markup (GTK_LABEL (label_frame_proxy), TRUE); */ label_proxy = gtk_label_new (_("Proxy")); gtk_widget_show (label_proxy); gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs_main), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs_main), 1), label_proxy); vbox_meta = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_meta); gtk_container_add (GTK_CONTAINER (tabs_main), vbox_meta); frame_meta_player = gtk_frame_new (NULL); gtk_widget_show (frame_meta_player); gtk_box_pack_start (GTK_BOX (vbox_meta), frame_meta_player, TRUE, TRUE, 0); gtk_frame_set_shadow_type (GTK_FRAME (frame_meta_player), GTK_SHADOW_NONE); alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment1); gtk_container_add (GTK_CONTAINER (frame_meta_player), alignment1); // gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 12, 0); hbox_meta_player = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox_meta_player); gtk_container_add (GTK_CONTAINER (alignment1), hbox_meta_player); label_player_name = gtk_label_new (_("Player Name:")); gtk_widget_show (label_player_name); gtk_box_pack_start (GTK_BOX (hbox_meta_player), label_player_name, FALSE, FALSE, 0); input_meta_player_name = gtk_entry_new (); gtk_widget_show (input_meta_player_name); gtk_box_pack_start (GTK_BOX (hbox_meta_player), input_meta_player_name, TRUE, TRUE, 0); gtk_entry_set_text (GTK_ENTRY (input_meta_player_name), _("XMMS")); label_player = gtk_label_new (_("Player")); gtk_widget_show (label_player); /* gtk_frame_set_label_widget (GTK_FRAME (frame_meta_player), label_player); gtk_label_set_use_markup (GTK_LABEL (label_player), TRUE); */ frame_meta_title = gtk_frame_new (NULL); gtk_widget_show (frame_meta_title); gtk_box_pack_start (GTK_BOX (vbox_meta), frame_meta_title, TRUE, TRUE, 0); gtk_frame_set_shadow_type (GTK_FRAME (frame_meta_title), GTK_SHADOW_NONE); alignment2 = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_widget_show (alignment2); gtk_container_add (GTK_CONTAINER (frame_meta_title), alignment2); // gtk_alignment_set_padding (GTK_ALIGNMENT (alignment2), 0, 0, 12, 0); hbox_meta_title = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox_meta_title); gtk_container_add (GTK_CONTAINER (alignment2), hbox_meta_title); /* input_meta_send_title = gtk_check_button_new_with_mnemonic (_("Send song title to server")); gtk_widget_show (input_meta_send_title); gtk_box_pack_start (GTK_BOX (hbox_meta_title), input_meta_send_title, FALSE, FALSE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (input_meta_send_title), TRUE); input_meta_send_filename = gtk_check_button_new_with_mnemonic (_("Send song filename to server")); gtk_widget_show (input_meta_send_filename); gtk_box_pack_start (GTK_BOX (hbox_meta_title), input_meta_send_filename, FALSE, FALSE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (input_meta_send_filename), TRUE); */ label_meta_title = gtk_label_new (_("Current Song")); gtk_widget_show (label_meta_title); /* gtk_frame_set_label_widget (GTK_FRAME (frame_meta_title), label_meta_title); gtk_label_set_use_markup (GTK_LABEL (label_meta_title), TRUE); */ label_meta = gtk_label_new (_("Meta Data")); gtk_widget_show (label_meta); gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs_main), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs_main), 2), label_meta); hbox_buttons = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox_buttons); gtk_box_pack_start (GTK_BOX (vbox_main), hbox_buttons, TRUE, TRUE, 0); button_ok = gtk_button_new_with_label(_("OK")); gtk_box_pack_start (GTK_BOX (hbox_buttons), button_ok, FALSE, FALSE, 0); button_cancel = gtk_button_new_with_label(_("Cancel")); gtk_signal_connect_object(GTK_OBJECT(button_cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(config_win)); gtk_box_pack_start (GTK_BOX (hbox_buttons), button_cancel, FALSE, FALSE, 0); /* button_ok = gtk_button_new_from_stock ("gtk-ok"); gtk_widget_show (button_ok); gtk_box_pack_start (GTK_BOX (hbox_buttons), button_ok, FALSE, FALSE, 0); button_cancel = gtk_button_new_from_stock ("gtk-cancel"); gtk_widget_show (button_cancel); gtk_box_pack_start (GTK_BOX (hbox_buttons), button_cancel, FALSE, FALSE, 0); g_signal_connect_swapped ((gpointer) button_ok, "clicked", G_CALLBACK (on_button_ok_enter), GTK_OBJECT (config_win)); g_signal_connect_swapped ((gpointer) button_cancel, "clicked", G_CALLBACK (gtk_widget_destroy), GTK_OBJECT (config_win)); */ } //ll roaraudio-1.0beta11/plugins/xmms/roar.c0000644000175000017500000001774712264733636016267 0ustar phiphi//roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of the XMMS RoarAudio output plugin a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "all.h" OutputPlugin roar_op = { NULL, NULL, "RoarAudio XMMS Plugin", /* Description */ roar_init, roar_about, roar_configure, roar_get_volume, roar_set_volume, roar_open, roar_write, roar_close, roar_flush, roar_pause, roar_free, roar_playing, roar_get_output_time, roar_get_written_time, }; OutputPlugin *get_oplugin_info(void) { return &roar_op; } void roar_init(void) { ConfigFile * cfgfile; cfgfile = xmms_cfg_open_default_file(); g_inst.state = 0; g_inst.server = NULL; g_inst.session = ctrlsocket_get_session_id(); g_inst.mixer.l = -1; g_inst.mixer.r = -1; xmms_cfg_read_string(cfgfile, "ROAR", "server", &g_inst.server); xmms_cfg_read_string(cfgfile, "ROAR", "player_name", &g_inst.cfg.player_name); xmms_cfg_free(cfgfile); if ( g_inst.cfg.player_name == NULL ) g_inst.cfg.player_name = "XMMS"; ROAR_DBG("roar_init(*) = (void)"); } int roar_playing(void) { return FALSE; } void roar_write(void *ptr, int length) { ssize_t r; if ( g_inst.pause ) return; ROAR_DBG("roar_write(ptr=%p, length=%i) = (void)", ptr, length); while (length) { if ( (r = roar_vio_write(&(g_inst.vio), ptr, length >= 1764*4 ? 1764*4 : length)) != -1 ) { g_inst.written += r; ptr += r; length -= r; } else { if ( errno == EAGAIN ) { xmms_usleep(1000); } else { return; } } } } int roar_open(AFormat fmt, int rate, int nch) { int codec = ROAR_CODEC_DEFAULT; int bits; if ( !(g_inst.state & STATE_CONNECTED) ) { if ( roar_simple_connect(&(g_inst.con), g_inst.server, g_inst.cfg.player_name) == -1 ) { return FALSE; } g_inst.state |= STATE_CONNECTED; } bits = 16; switch (fmt) { case FMT_S8: bits = 8; codec = ROAR_CODEC_DEFAULT; break; case FMT_U8: bits = 8; codec = ROAR_CODEC_PCM_U_LE; // _LE, _BE, _PDP,... all the same for 8 bit output break; case FMT_U16_LE: codec = ROAR_CODEC_PCM_U_LE; break; case FMT_U16_BE: codec = ROAR_CODEC_PCM_U_BE; break; case FMT_U16_NE: #if BYTE_ORDER == BIG_ENDIAN codec = ROAR_CODEC_PCM_U_BE; #elif BYTE_ORDER == LITTLE_ENDIAN codec = ROAR_CODEC_PCM_U_LE; #else codec = ROAR_CODEC_PCM_U_PDP; #endif break; case FMT_S16_LE: codec = ROAR_CODEC_PCM_S_LE; break; case FMT_S16_BE: codec = ROAR_CODEC_PCM_S_BE; break; case FMT_S16_NE: codec = ROAR_CODEC_DEFAULT; break; } g_inst.bps = nch * rate * bits / 8; roar_close(); if ( roar_vio_simple_new_stream_obj(&(g_inst.vio), &(g_inst.con), &(g_inst.stream), rate, nch, bits, codec, ROAR_DIR_PLAY, -1) == -1 ) { roar_disconnect(&(g_inst.con)); g_inst.state |= STATE_CONNECTED; g_inst.state -= STATE_CONNECTED; if ( !(g_inst.state & STATE_NORECONNECT) ) { g_inst.state |= STATE_NORECONNECT; xmms_usleep(100000); return roar_open(fmt, rate, nch); } else { g_inst.state -= STATE_NORECONNECT; return FALSE; } } g_inst.state |= STATE_PLAYING; g_inst.written = 0; g_inst.pause = 0; _LIBROAR_IGNORE_RET(roar_stream_set_role(&(g_inst.con), &(g_inst.stream), ROAR_ROLE_MUSIC)); roar_update_metadata(); roar_set_volume(g_inst.mixer.l, g_inst.mixer.r); return TRUE; } void roar_close(void) { int was_playing = g_inst.state & STATE_PLAYING; g_inst.state |= STATE_PLAYING; g_inst.state -= STATE_PLAYING; if ( was_playing ) { roar_vio_close(&(g_inst.vio)); xmms_usleep(10000); // give the server 10ms of extra time } g_inst.written = 0; ROAR_DBG("roar_close(void) = (void)"); } void roar_pause(short p) { g_inst.pause = p; } int roar_free(void) { if ( g_inst.pause ) return 0; else return 1000000; // ??? } void roar_flush(int time) { gint64 r = time; r *= g_inst.bps; r /= 1000; g_inst.written = r; } int roar_get_output_time(void) { return roar_get_written_time(); } int roar_get_written_time(void) { gint64 r; if ( !g_inst.bps ) { ROAR_DBG("roar_get_written_time(void) = 0"); return 0; } r = g_inst.written; r *= 1000; // sec -> msec r /= g_inst.bps; ROAR_DBG("roar_get_written_time(void) = %lu", r); return r; } // META DATA: int roar_update_metadata(void) { struct roar_meta meta; char empty = 0; char * info; char * delm; int pos; pos = xmms_remote_get_playlist_pos(g_inst.session); meta.value = ∅ meta.key[0] = 0; meta.type = ROAR_META_TYPE_NONE; roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_CLEAR, &meta); info = xmms_remote_get_playlist_file(g_inst.session, pos); if ( info ) { if ( strncmp(info, "http:", 5) == 0 ) meta.type = ROAR_META_TYPE_FILEURL; else meta.type = ROAR_META_TYPE_FILENAME; meta.value = info; ROAR_DBG("roar_update_metadata(*): setting meta data: type=%i, strlen(value)=%i", meta.type, strlen(info)); roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta); free(info); } info = xmms_remote_get_playlist_title(g_inst.session, pos); if ( info ) { if ( (delm = strstr(info, " - ")) != NULL ) { *delm = 0; meta.value = info; meta.type = ROAR_META_TYPE_ARTIST; roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta); meta.value = delm + 3; } else { meta.value = info; } meta.type = ROAR_META_TYPE_TITLE; roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta); free(info); } meta.value = ∅ meta.type = ROAR_META_TYPE_NONE; roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_FINALIZE, &meta); return 0; } int roar_chk_metadata(void) { static int old_pos = -1; static char * old_title = "NEW TITLE"; int pos; char * title; int need_update = 0; pos = xmms_remote_get_playlist_pos(g_inst.session); if ( pos != old_pos ) { old_pos = pos; need_update = 1; } else { title = xmms_remote_get_playlist_title(g_inst.session, pos); if ( strcmp(title, old_title) ) { free(old_title); old_title = title; need_update = 1; } else { free(title); } } if ( need_update ) { roar_update_metadata(); } return 0; } // MIXER: void roar_get_volume(int *l, int *r) { int channels; struct roar_mixer_settings mixer; float fs; if ( !(g_inst.state & STATE_CONNECTED) || !(g_inst.state & STATE_PLAYING) ) { *l = g_inst.mixer.l; *r = g_inst.mixer.r; return; } if ( roar_get_vol(&(g_inst.con), g_inst.stream.id, &mixer, &channels) == -1 ) { *l = *r = 100; return; } fs = (float)mixer.scale/100.; if ( channels == 1 ) { *l = *r = mixer.mixer[0]/fs; } else { *l = mixer.mixer[0]/fs; *r = mixer.mixer[1]/fs; } } void roar_set_volume(int l, int r) { struct roar_mixer_settings mixer; if ( !(g_inst.state & STATE_CONNECTED) ) return; if ( l == -1 ) l = 100; if ( r == -1 ) r = 100; g_inst.mixer.l = l; g_inst.mixer.r = r; if ( !(g_inst.state & STATE_PLAYING) ) return; mixer.mixer[0] = l; mixer.mixer[1] = r; mixer.scale = 100; _LIBROAR_IGNORE_RET(roar_set_vol(&(g_inst.con), g_inst.stream.id, &mixer, 2, ROAR_SET_VOL_UNMAPPED)); } //ll roaraudio-1.0beta11/roarclients/0000755000175000017500000000000012267553244015016 5ustar phiphiroaraudio-1.0beta11/roarclients/Makefile0000644000175000017500000000664512072575525016471 0ustar phiphiTARGETS_DEVEL=roartypes roar-config TARGETS_EXAMPLE=roarvorbis roarsin TARGETS_IO=roarcat roarcatplay roarcatvio roarbidir roarmon roarmonhttp roarradio TARGETS_CTL=roarctl roarlight roarinterconnect roarclientpass TARGETS_DSP=roarfilt roarvumeter roardtmf TARGETS_MISC=roarsockconnect roarphone roarshout TARGETS_M= TARGETS_VIO=roarvio TARGETS_PLUGINS=roarpluginrunner roarpluginapplication #TARGETS_TESTS=zcattest pgptest pipetest polytest #TARGETS_OLD=roarcatpassfh roarsocktypes TARGETS=$(TARGETS_IO) $(TARGETS_CTL) $(TARGETS_DSP) $(TARGETS_MISC) $(TARGETS_DEVEL) $(TARGETS_EXAMPLE) $(TARGETS_M) $(TARGETS_VIO) $(TARGETS_PLUGINS) # tools we maybe want to kick of the package TARGETS += $(TARGETS_TESTS) $(TARGETS_OLD) TOOLS=roarify include ../Makefile.conf include ../Makefile.inc #DEFINES = -DDEBUG INCLUDE = -I../include -I./include CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) LDFLAGS += $(DEBUG_g) $(Wall) -L../lib/ $(LDPATH) LIBS = $(LIBROAR) SHOUTLIBS = $(lib_shout) $(pthread) $(LIBS) VORBISLIBS = $(lib_vorbisfile) $(lib_vorbis) $(lib_ogg) $(LIBS) LNL = $(CC) $(LDFLAGS) -o $@ $+ L = $(LNL) $(LIBS) all: ${TARGETS} $(TOOLS) cp $(cp_v) ${TARGETS} $(TOOLS) ../lib/ clean: rm -f ${TARGETS} ${TOOLS} *.o new: clean all roarcat: roarcat.o $L roarcatad: roarcatad.o $L roarcat2sock: roarcat2sock.o $L roarcatsendfile: roarcatsendfile.o $L roarcatplay: roarcatplay.o $L roarcatpassfh: roarcatpassfh.o $L roarcatvio: roarcatvio.o $L roarradio: roarradio.o $L roarctl: roarctl.o $L $(LIBROARDSP) $(lib_m) roarmon: roarmon.o $L roarmonhttp: roarmonhttp.o $L roarinterconnect: roarinterconnect.o $L $(lib_esd) $(LIBROAREIO) $(lib_rsound) roarclientpass: roarclientpass.o $L roarbidir: roarbidir.o $L roarphone: roarphone.o ${CC} ${LDFLAGS} -o roarphone roarphone.o $(LIBROARDSP) $(LIBROAREIO) $(LIBS) roarfilt: roarfilt.o ${CC} ${LDFLAGS} -o roarfilt roarfilt.o $(LIBROARDSP) $(LIBS) $(lib_m) roarsin: roarsin.o ${CC} ${LDFLAGS} -o roarsin roarsin.o $(LIBROARDSP) $(LIBS) $(lib_m) roarvumeter: roarvumeter.o ${CC} ${LDFLAGS} -o roarvumeter roarvumeter.o $(LIBS) $(LIBROARDSP) $(lib_m) roardtmf: roardtmf.o ${CC} ${LDFLAGS} -o roardtmf roardtmf.o $(LIBS) $(LIBROARDSP) roarsockconnect: roarsockconnect.o $L roarvio: roarvio.o $L roarpluginrunner: roarpluginrunner.o $L $(lib_dl) roartypes: roartypes.o $L roarsocktypes: roarsocktypes.o $L roar-config: roar-config.o $(LNL) ../lib/libroar.a $(LIBROAR_NS) roarvorbis: roarvorbis.o ${CC} ${LDFLAGS} -o roarvorbis roarvorbis.o $(VORBISLIBS) $(LIBS) roarshout: roarshout.o ${CC} ${LDFLAGS} -o roarshout roarshout.o $(SHOUTLIBS) $(LIBS) polytest: polytest.o ${CC} ${LDFLAGS} -o polytest polytest.o $(LIBROARDSP) $(LIBS) roarlight: roarlight.o ${CC} ${LDFLAGS} -o roarlight roarlight.o $(LIBROARLIGHT) $(LIBS) pinentrytest: pinentrytest.o $L zcattest: zcattest.o $L pgptest: pgptest.o $L pipetest: pipetest.o $L roarfctest: roarfctest.o ${CC} ${LDFLAGS} -o roarfctest roarfctest.o $(LIBROARDSP) $(LIBS) $(lib_m) roarify.sht: roarify: roarify.sht sed 's#%%%PREFIX_COMP_LIBS%%%#$(PREFIX_COMP_LIBS)#g; s#%%%PREFIX_COMP_BINS%%%#$(PREFIX_COMP_BINS)#g; s#%%%PREFIX_LIB%%%#$(PREFIX_LIB)#g; s#%%%VERSION%%%#$(COMMON_SOVERSION)#g;' < roarify.sht > roarify chmod +rx roarify roarpluginapplication.sht: roarpluginapplication: roarpluginapplication.sht cp roarpluginapplication.sht roarpluginapplication chmod +rx roarpluginapplication roaraudio-1.0beta11/roarclients/pgptest.c0000644000175000017500000000401112264733637016647 0ustar phiphi//pgptest.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUF_MAX 1024 #define FILENAME "/tmp/bla.asc" #define PASSWORD "test" #define STRING "Hello world!\n" int main (void) { char buf[BUF_MAX]; size_t len; struct roar_vio_calls file, pgp; if ( roar_vio_open_file(&file, FILENAME, O_CREAT|O_TRUNC|O_WRONLY, 0666) == -1 ) { ROAR_ERR("roar_vio_open_file(&file, FILENAME, O_CREAT|O_TRUNC|O_WRONLY, 0666) = -1"); return 1; } if ( roar_vio_open_pgp_encrypt_sym(&pgp, &file, PASSWORD, ROAR_VIO_PGP_OPTS_ASCII) == -1 ) { ROAR_ERR("roar_vio_open_pgp_encrypt_sym(&pgp, &file, PASSWORD, ROAR_VIO_PGP_OPTS_ASCII) = -1"); return 1; } roar_vio_write(&pgp, STRING, strlen(STRING)); roar_vio_close(&pgp); if ( roar_vio_open_file(&file, FILENAME, O_RDONLY, 0666) == -1 ) { ROAR_ERR("roar_vio_open_file(&file, FILENAME, O_RDONLY, 0666) = -1"); return 1; } if ( roar_vio_open_pgp_decrypt(&pgp, &file, PASSWORD) == -1 ) { ROAR_ERR("roar_vio_open_pgp_decrypt(&pgp, &file, PASSWORD) = -1"); return 1; } while ((len = roar_vio_read(&pgp, buf, BUF_MAX))) write(ROAR_STDOUT, buf, len); roar_vio_close(&pgp); return 0; } //ll roaraudio-1.0beta11/roarclients/pipetest.c0000644000175000017500000000331512264733640017016 0ustar phiphi//pipetest.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #define BUF_MAX 1024 int main (void) { #ifdef ROAR_HAVE_FORK char buf[BUF_MAX]; struct roar_vio_calls s0, s1; struct roar_vio_calls * me; if ( roar_vio_open_pipe(&s0, &s1, ROAR_VIO_PIPE_TYPE_AUTO, O_RDWR) == -1 ) { fprintf(stderr, "Error: can not create pipe\n"); } switch (fork()) { case 0: me = &s0; roar_vio_close(&s1); break; default: me = &s1; roar_vio_close(&s0); } snprintf(buf, BUF_MAX, "Hello from pid %i\n", getpid()); roar_vio_write(me, buf, strlen(buf)); buf[0] = 0; roar_vio_read(me, buf, BUF_MAX); printf("This is pid %i: %s", getpid(), buf); roar_vio_close(me); roar_sleep(1); // wait for the other child... return 0; #else fprintf(stderr, "Error: no fork() support!\n"); return 1; #endif } //ll roaraudio-1.0beta11/roarclients/polytest.c0000644000175000017500000000244212264733640017044 0ustar phiphi//polytest.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #define BUF_MAX 1024 int main (void) { int16_t in[BUF_MAX]; int16_t out[BUF_MAX]; size_t il = 10; size_t ol = 20; size_t i; int tmp; for (i = 0; i < il; i++) { scanf("%i", &tmp); in[i] = tmp; } roar_conv_poly4_16(out, in, ol, il); for (i = 0; i < ol; i++) printf("%i\n", out[i]); return 0; } //ll roaraudio-1.0beta11/roarclients/roar-config.c0000644000175000017500000002343712264733641017377 0ustar phiphi//roar-config.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include static const struct { const char * name; const char * cflags; const char * libs; } flags[] = { // native/own libs: {"roar", ROAR_CFLAGS, ROAR_LIBS }, // NOTE: libroar *MUST* be the first entry {"roardsp", ROAR_CFLAGS, ROAR_LIBS_DSP }, {"roarmidi", ROAR_CFLAGS, ROAR_LIBS_MIDI }, {"roarlight", ROAR_CFLAGS, ROAR_LIBS_LIGHT }, {"roareio", ROAR_CFLAGS, ROAR_LIBS_EIO }, // comp libs: {"roaresd", ROAR_CFLAGS, ROAR_LIBS_C_ESD }, {"esd", ROAR_CFLAGS, ROAR_LIBS_C_ESD }, {"roarartsc", ROAR_CFLAGS, ROAR_LIBS_C_ARTSC}, {"artsc", ROAR_CFLAGS, ROAR_LIBS_C_ARTSC}, {"roarpulse", ROAR_CFLAGS, ROAR_LIBS_C_PULSE}, {"pulse", ROAR_CFLAGS, ROAR_LIBS_C_PULSE}, {"roarpulse-simple", ROAR_CFLAGS, ROAR_LIBS_C_PULSE_SIMPLE}, {"pulse-simple", ROAR_CFLAGS, ROAR_LIBS_C_PULSE_SIMPLE}, {"roarsndio", ROAR_CFLAGS, ROAR_LIBS_C_SNDIO}, {"sndio", ROAR_CFLAGS, ROAR_LIBS_C_SNDIO}, {"roaryiff", ROAR_CFLAGS, ROAR_LIBS_C_YIFF }, {"Y2", ROAR_CFLAGS, ROAR_LIBS_C_YIFF }, {NULL, NULL, NULL} }, * flags_ptr = NULL; struct version { int major, minor, revision; }; static struct version parse_version(const char * version) { struct version ret = {-1, -1, -1}; char * next; if ( !strcasecmp(version, "current") ) version = ROAR_VERSION_COMMON; ret.major = strtoll(version, &next, 0); ret.minor = strtoll(next+1, &next, 0); ret.revision = strtoll(next+1, &next, 0); return ret; } static int compare_versions_eq(struct version a, struct version b) { return a.major == b.major && a.minor == b.minor && a.revision == b.revision; } static int compare_versions_gt(struct version a, struct version b) { if ( a.major > b.major ) return 1; if ( a.minor > b.minor ) return 1; if ( a.revision > b.revision ) return 1; return 0; } static int compare_versions_ge(struct version a, struct version b) { return compare_versions_gt(a, b) || compare_versions_eq(a, b); } static int compare_versions_lt(struct version a, struct version b) { return compare_versions_gt(b, a); } static int compare_versions_le(struct version a, struct version b) { return compare_versions_lt(a, b) || compare_versions_eq(a, b); } static const struct { const char * op; int neg; int (*func)(struct version a, struct version b); } compare_versions_funcs[] = { {"eq", 0, compare_versions_eq}, {"ne", 1, compare_versions_eq}, {"gt", 0, compare_versions_gt}, {"ge", 0, compare_versions_ge}, {"lt", 0, compare_versions_lt}, {"le", 0, compare_versions_le} }; static int compare_versions(const char * a, const char * op, const char * b) { struct version va = parse_version(a); struct version vb = parse_version(b); size_t i; int ret; ROAR_DBG("compare_versions(a='%s', op='%s', b='%s'): {%i, %i, %i} <%s> {%i, %i, %i}\n", a, op, b, va.major, va.minor, va.revision, op, vb.major, vb.minor, vb.revision); for (i = 0; i < (sizeof(compare_versions_funcs)/sizeof(*compare_versions_funcs)); i++) { if ( !strcasecmp(compare_versions_funcs[i].op, op) ) { ret = compare_versions_funcs[i].func(va, vb); if ( compare_versions_funcs[i].neg ) ret = ret ? 0 : 1; return ret ? 0 : 32; } } ROAR_ERR("compare_versions(*): Operator \"%s\" not found.", op); return 1; } void print_path(const char * name, int null_as_universal, const char * product, const char * provider) { char * path = roar_libroar_get_path(name, null_as_universal, product, provider); if ( path == NULL ) { fprintf(stderr, "Error: Can not get path: %s: %s\n", name, roar_errorstring); return; } printf("%s\n", path); roar_mm_free(path); } void list_path(int null_as_universal, const char * product, const char * provider) { const char * names[32]; char * path; size_t offset = 0; ssize_t ret; ssize_t i; const char * err; size_t errlen; while (1) { ret = roar_libroar_list_path(names, sizeof(names)/sizeof(*names), offset); if ( ret < 1 ) break; offset += (size_t)ret; for (i = 0; i < ret; i++) { path = roar_libroar_get_path(names[i], null_as_universal, product, provider); if ( path == NULL && roar_error == ROAR_ERROR_INVAL ) path = roar_libroar_get_path(names[i], 0, product, NULL); if ( path == NULL && roar_error == ROAR_ERROR_INVAL ) path = roar_libroar_get_path(names[i], 0, NULL, NULL); if ( path == NULL ) { err = roar_errorstring; errlen = roar_mm_strlen(err) + roar_mm_strlen("") + 1; path = roar_mm_malloc(errlen); if ( path == NULL ) continue; snprintf(path, errlen, "", err); } printf("%-24s: %s\n", names[i], path); roar_mm_free(path); } } } void print_renderpath(const char * path) { char buf[1024]; if ( roar_env_render_path_r(buf, sizeof(buf), path) != 0 ) { fprintf(stderr, "Error: Can not render path: %s: %s\n", path, roar_errorstring); return; } printf("%s\n", buf); } void usage (void) { printf("Usage: roar-config --version\n" " roar-config --compare-versions VERSIONA OPERATOR VERSIONB\n" " roar-config [{--output-pc|--output-normal}] [--libs] [--cflags] [LIB]\n" " roar-config [--product PRODUCT] [--provider PROVIDER] [--universal] {--path PATH|--list-path}\n" " roar-config --render-path PATH\n"); printf("\nOptions:\n\n"); printf(" --help - Show this help\n" " --version - Show version of library\n" " --compare-versions A OP B\n" " - Compare version A against B with operator OP.\n" " --path NAME - Print path NAME\n" " --list-path - Print all known paths\n" " --product PRODUCT - Product string for --path/--list-path\n" " --provider PROVIDER - Provider string for --path/--list-path\n" " --universal - Use universal path for --path/--list-path\n" " --render-path PATH - Print a rendered path\n" " --libs - Show linker flags (-lxxx) needed to link library\n" " --cflags - Show compiler flags needed to link library\n" " --output-pc - Output PC format\n" " --output-normal - Output in \"classical\" format\n" ); } #define _strcat(buf, n) strncat(buf, n, sizeof(buf)-1-strlen(buf)) int main (int argc, char * argv[]) { enum { NORMAL, PC } mode = NORMAL; int null_as_universal = 0; const char * product = NULL; const char * provider = NULL; int i, h; int cflags = 0; int libs = 0; char buf[1024] = {0}; if ( argc == 1 ) { usage(); return 0; } for (i = 1; i < argc; i++) { if ( !strcmp(argv[i], "--version") ) { printf("%s\n", ROAR_VERSION_COMMON); } else if ( !strcmp(argv[i], "--help") || !strcmp(argv[i], "-h") ) { usage(); return 0; } else if ( !strcmp(argv[i], "--compare-versions") ) { return compare_versions(argv[i+1], argv[i+2], argv[i+3]); } else if ( !strcmp(argv[i], "--product") ) { product = argv[++i]; } else if ( !strcmp(argv[i], "--provider") ) { provider = argv[++i]; } else if ( !strcmp(argv[i], "--universal") ) { null_as_universal = 1; } else if ( !strcmp(argv[i], "--path") ) { print_path(argv[++i], null_as_universal, product, provider); } else if ( !strcmp(argv[i], "--list-path") ) { list_path(null_as_universal, product, provider); } else if ( !strcmp(argv[i], "--render-path") ) { print_renderpath(argv[++i]); } else if ( !strcmp(argv[i], "--libs") ) { libs = 1; } else if ( !strcmp(argv[i], "--cflags") ) { cflags = 1; } else if ( !strcmp(argv[i], "--output-normal") ) { mode = NORMAL; } else if ( !strcmp(argv[i], "--output-pc") ) { mode = PC; } else if ( flags_ptr == NULL ) { if ( !strncmp(argv[i], "lib", 3) ) argv[i] += 3; for (h = 0; flags[h].name != NULL; h++) { if ( !strcasecmp(argv[i], flags[h].name) ) flags_ptr = &(flags[h]); } if ( flags_ptr == NULL ) { fprintf(stderr, "Unknown lib: %s\n", argv[i]); return 2; } } else { fprintf(stderr, "Unknown option: %s\n", argv[i]); usage(); return 1; } } if ( flags_ptr == NULL ) flags_ptr = &(flags[0]); switch (mode) { case NORMAL: if ( cflags || libs ) { if ( cflags ) _strcat(buf, flags_ptr->cflags); if ( libs ) _strcat(buf, flags_ptr->libs); puts(buf); } break; case PC: printf("prefix="); print_path("prefix", 0, NULL, NULL); printf("exec_prefix=${prefix}\n"); printf("libdir="); print_path("prefix-lib", 0, NULL, NULL); printf("includedir="); print_path("prefix-inc", 0, NULL, NULL); printf("\n"); printf( "Name: lib%s\n" "Description: lib%s is part of RoarAudio Sound System\n" "Version: %s\n" // "Requires: libroar\n" "Conflicts:\n" "Libs: -L${libdir} %s\n" "Cflags: -I${includedir} %s\n", flags_ptr->name, flags_ptr->name, ROAR_VERSION_COMMON, flags_ptr->libs, flags_ptr->cflags ); break; } return 0; } //ll roaraudio-1.0beta11/roarclients/roarbidir.c0000644000175000017500000001071212264733641017136 0ustar phiphi//roarbidir.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUFSIZE 1024 void usage (void) { printf("roarbidir [OPTIONS]... [IN_FILE]\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --help - Show this help\n" ); } int main (int argc, char * argv[]) { struct roar_audio_info info; const char * server = NULL; const char * k; int i; struct roar_vio_defaults def; struct roar_vio_calls in_store; struct roar_vio_calls * in = NULL, * out = NULL; struct roar_vio_calls * vss_vio = NULL; roar_vs_t * vss; struct roar_vio_select vios[2]; char buf[BUFSIZE]; int err; ssize_t ret; if ( roar_profile2info(&info, "default") == -1 ) return 1; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 ) return 1; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) { ROAR_CKHAVEARGS(1); info.codec = roar_str2codec(argv[++i]); } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( in == NULL ) { if ( roar_vio_open_dstr(&in_store, k, &def, 1) == -1 ) { fprintf(stderr, "Error: can not open file: %s: %s\n", k, roar_error2str(roar_error)); return 1; } in = &in_store; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( (vss = roar_vs_new_simple(server, "roarbidir", info.rate, info.channels, info.codec, info.bits, ROAR_DIR_BIDIR, &err)) == NULL ) { fprintf(stderr, "Error: can not start playback: %s\n", roar_error2str(err)); if ( in != NULL ) roar_vio_close(in); return 1; } if ( in == NULL ) in = roar_stdin; if ( out == NULL ) out = roar_stdout; vss_vio = roar_vs_vio_obj(vss, NULL); while (1) { memset(vios, 0, sizeof(vios)); ROAR_VIO_SELECT_SETVIO(&(vios[0]), vss_vio, ROAR_VIO_SELECT_READ); ROAR_VIO_SELECT_SETVIO(&(vios[1]), in, ROAR_VIO_SELECT_READ); if ( (ret = roar_vio_select(vios, 2, NULL, NULL)) == -1 ) break; if ( ret < 0 ) continue; if ( vios[0].eventsa & ROAR_VIO_SELECT_READ ) { if ( (ret = roar_vs_read(vss, buf, sizeof(buf), NULL)) == -1 ) break; if ( roar_vio_write(out, buf, ret) != ret ) break; } if ( vios[1].eventsa & ROAR_VIO_SELECT_READ ) { if ( (ret = roar_vio_read(in, buf, sizeof(buf))) == -1 ) break; if ( roar_vs_write(vss, buf, ret, NULL) != ret ) break; } } roar_vs_close(vss, ROAR_VS_TRUE, NULL); roar_vio_close(in); return 0; } //ll roaraudio-1.0beta11/roarclients/roarcat.c0000644000175000017500000002063312264733642016620 0ustar phiphi//roarcat.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUFSIZE 1024 void usage (void) { printf("roarcat [OPTIONS]... [FILE]\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --wave - Use Wave Audio (PCM) as input\n" " --midi - Use MIDI Audio as input\n" " --light - Use light control input\n" " --raw - Use raw input\n" " --complex - Use complex input\n" " --rdtcs - Use Radio Data and Transmitter Control System input\n" " --rel-id ID - Set ID of relative stream\n" " --role ROLE - Set stream role\n" " --help - Show this help\n" ); } int main (int argc, char * argv[]) { struct roar_audio_info info = { .rate = ROAR_AUDIO_INFO_INVALID, .bits = ROAR_AUDIO_INFO_INVALID, .channels = ROAR_AUDIO_INFO_INVALID, .codec = ROAR_AUDIO_INFO_INVALID}; int dir = ROAR_DIR_PLAY; int rel_id = -1; int role = ROAR_ROLE_UNKNOWN; const char * server = NULL; const char * k; int i; const char * name = "roarcat"; struct roar_connection con; struct roar_stream s; struct roar_vio_calls file, * stream; struct roar_vio_defaults def; int file_opened = 0; // TODO: make use of roar_stdin. if ( roar_vio_open_fh(&file, ROAR_STDIN) == -1 ) return 1; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 ) return 1; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "--server") || !strcmp(k, "-s") ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( !strcmp(k, "-n") ) { ROAR_CKHAVEARGS(1); name = argv[++i]; } else if ( !strcmp(k, "--rate") || !strcmp(k, "-r") || !strcmp(k, "-R") ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( !strcmp(k, "--bits") || !strcmp(k, "-B") ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( !strcmp(k, "-b") ) { info.bits = 8; } else if ( !strcmp(k, "--channels") || !strcmp(k, "--chans") || !strcmp(k, "-C") ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( !strcmp(k, "-m") ) { info.channels = 1; } else if ( !strcmp(k, "--codec") || !strcmp(k, "-E") ) { ROAR_CKHAVEARGS(1); if ( (info.codec = roar_str2codec(argv[++i])) == ROAR_AUDIO_INFO_INVALID ) { fprintf(stderr, "Error: Unknown codec: %s\n", argv[i]); return 1; } } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( !strcmp(k, "--wave") ) { dir = ROAR_DIR_PLAY; } else if ( !strcmp(k, "--midi") ) { dir = ROAR_DIR_MIDI_IN; } else if ( !strcmp(k, "--light") ) { dir = ROAR_DIR_LIGHT_IN; } else if ( !strcmp(k, "--raw") ) { dir = ROAR_DIR_RAW_IN; } else if ( !strcmp(k, "--complex") ) { dir = ROAR_DIR_COMPLEX_IN; } else if ( !strcmp(k, "--rdtcs") ) { dir = ROAR_DIR_RDTCS_IN; } else if ( !strcmp(k, "--rel-id") ) { ROAR_CKHAVEARGS(1); rel_id = atoi(argv[++i]); } else if ( !strcmp(k, "--role") ) { ROAR_CKHAVEARGS(1); role = roar_str2role(argv[++i]); } else if ( !strcmp(k, "--help") || !strcmp(k, "-h") ) { usage(); return 0; } else if ( !file_opened ) { file_opened = 1; if ( roar_vio_open_dstr(&file, k, &def, 1) == -1 ) { fprintf(stderr, "Error: can not open file: %s: %s\n", k, roar_error2str(roar_error)); return 1; } } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } switch (dir) { case ROAR_DIR_PLAY: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = ROAR_RATE_DEFAULT; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_BITS_DEFAULT; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_CHANNELS_DEFAULT; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DEFAULT; break; case ROAR_DIR_MIDI_IN: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = 0; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_MIDI_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_MIDI_CHANNELS_DEFAULT; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_MIDI; break; case ROAR_DIR_LIGHT_IN: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = 0; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_LIGHT_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = 0; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DMX512; break; case ROAR_DIR_COMPLEX_IN: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = ROAR_COMPLEX_RATE; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_COMPLEX_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_COMPLEX_CHANNELS; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_COMPLEX_CODEC; break; case ROAR_DIR_RDTCS_IN: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = ROAR_RDTCS_RATE; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_RDTCS_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_RDTCS_CHANNELS; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_RDTCS_CODEC; break; case ROAR_DIR_RAW_IN: default: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = 0; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = 0; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = 0; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DEFAULT; break; } if ( roar_simple_connect(&con, server, name) == -1 ) { fprintf(stderr, "Error: can not connect to server: %s\n", roar_error2str(roar_error)); return 10; } if ( roar_stream_new_by_info(&s, &info) == -1 ) { fprintf(stderr, "Error: can not create stream\n"); roar_disconnect(&con); return 20; } if ( rel_id != -1 ) { if ( roar_stream_set_rel_id(&s, rel_id) ) { fprintf(stderr, "Error: can not set id or realative stream\n"); roar_disconnect(&con); return 21; } } if ( roar_stream_connect(&con, &s, dir, -1) == -1 ) { fprintf(stderr, "Error: can not connect stream to server\n"); roar_disconnect(&con); return 11; } if ( role != ROAR_ROLE_UNKNOWN ) { if ( roar_stream_set_role(&con, &s, role) == -1 ) { fprintf(stderr, "Warning: can not set stream role\n"); } } if ( roar_stream_exec(&con, &s) == -1 ) { fprintf(stderr, "Error: can not exec stream\n"); roar_disconnect(&con); return 12; } if ( (stream = roar_get_connection_vio2(&con)) == NULL ) { fprintf(stderr, "Error: can not get stream vio\n"); roar_disconnect(&con); return 13; } if ( roar_vio_copy_data(stream, &file) == -1 ) { fprintf(stderr, "Error: can not copy data from source to server.\n"); roar_vio_close(stream); roar_vio_close(&file); return 14; } roar_vio_close(stream); roar_vio_close(&file); return 0; } //ll roaraudio-1.0beta11/roarclients/roarcatpassfh.c0000644000175000017500000000547012264733643020030 0ustar phiphi//roarcatpassfh.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUFSIZE (1024*2) void usage (void) { printf("roarcatpassfh [OPTIONS]...\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate RATE - Set sample rate\n" " --bits BITS - Set bits per sample\n" " --chans CHANNELS - Set number of channels\n" " --codec CODEC - Set the codec\n" " --help - Show this help\n" ); } int main (int argc, char * argv[]) { int rate = 44100; int bits = 16; int channels = 2; int codec = ROAR_CODEC_DEFAULT; char * server = NULL; char * k; int i; int in = ROAR_STDIN; struct roar_connection con; struct roar_stream s; roar_debug_bin_obsolete(argv[0], "roarcat", NULL); for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 ) { rate = atoi(argv[++i]); } else if ( strcmp(k, "--bits") == 0 ) { bits = atoi(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 ) { channels = atoi(argv[++i]); } else if ( strcmp(k, "--codec") == 0 ) { codec = roar_str2codec(argv[++i]); } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( roar_simple_connect(&con, server, "roarcatpassfh") == -1 ) { ROAR_DBG("roar_simple_play(*): roar_simple_connect() faild!"); return 1; } if ( roar_stream_new(&s, rate, channels, bits, codec) == -1 ) { roar_disconnect(&con); return 1; } if ( roar_stream_connect(&con, &s, ROAR_DIR_PLAY, -1) == -1 ) { roar_disconnect(&con); return 1; } if ( roar_stream_passfh(&con, &s, in) == -1 ) { roar_disconnect(&con); return 1; } close(in); roar_sleep(1000); roar_disconnect(&con); return 0; } //ll roaraudio-1.0beta11/roarclients/roarcatplay.c0000644000175000017500000001070612264733643017507 0ustar phiphi//roarcatplay.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUFSIZE 1024 void usage (void) { printf("roarcatplay [OPTIONS]... [FILE]\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --simple - Use the simple interface (default)\n" " --verbose - Use verbose output\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --help - Show this help\n" ); } int main (int argc, char * argv[]) { struct roar_audio_info info = {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_AUDIO_INFO_INVALID}; int auinfo_changed = 0; const char * server = NULL; const char * file = NULL; const char * k; int i; int verbose = 0; roar_vs_t * vss; int err; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 || strcmp(k, "-s") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--simple") == 0 ) { /* no op */ } else if ( strcmp(k, "--verbose") == 0 || strcmp(k, "-v") == 0 ) { verbose++; } else if ( strcmp(k, "-n") == 0 ) { ROAR_CKHAVEARGS(1); i++; roar_debug_option_obsolete(argv[0], "-n", NULL, "Will ignore it for now."); } else if ( !strcmp(k, "--rate") || !strcmp(k, "-R") ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "--bits") || !strcmp(k, "-B") ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "--channels") || !strcmp(k, "--chans") || !strcmp(k, "-C") ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "--codec") || !strcmp(k, "-E") ) { ROAR_CKHAVEARGS(1); info.codec = roar_str2codec(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } auinfo_changed = 1; } else if ( strcmp(k, "--help") == 0 || strcmp(k, "-h") == 0 ) { usage(); return 0; } else if ( file == NULL ) { file = argv[i]; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( file == NULL ) file = "fh:stdin"; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DEFAULT; if ( (vss = roar_vs_new(server, "roarcatplay", &err)) == NULL ) { fprintf(stderr, "Error: can not connect to server: %s: %s\n", server == NULL ? "(default)" : server, roar_error2str(err)); return 10; } if ( auinfo_changed ) { if ( roar_vs_stream(vss, &info, ROAR_DIR_PLAY, &err) == -1 ) { fprintf(stderr, "Error: can not create new stream: %s\n", roar_error2str(err)); roar_vs_close(vss, ROAR_VS_TRUE, NULL); return 10; } } if ( roar_vs_file_simple(vss, file, &err) == -1 ) { fprintf(stderr, "Error: can not open file: %s: %s\n", file, roar_error2str(err)); roar_vs_close(vss, ROAR_VS_TRUE, NULL); return 10; } roar_vs_run(vss, NULL); roar_vs_sync(vss, ROAR_VS_WAIT, NULL); roar_vs_close(vss, ROAR_VS_FALSE, NULL); return 0; } //ll roaraudio-1.0beta11/roarclients/roarcatvio.c0000644000175000017500000001017012264733644017333 0ustar phiphi//roarcatvio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUFSIZE 1024 void usage (void) { printf("roarcatvio [OPTIONS]... [FILE]\n"); printf("\nOptions:\n\n"); printf(" --server -s SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --help - Show this help\n" ); } int main (int argc, char * argv[]) { struct roar_audio_info info = {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_AUDIO_INFO_INVALID}; int auinfo_changed = 0; const char * server = NULL; const char * k; int i; const char * name = "roarcatvio"; roar_vs_t * vss; const char * filename = NULL; int err; roar_debug_bin_obsolete(argv[0], "roarcatplay", NULL); for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "--server") || !strcmp(k, "-s") ) { server = argv[++i]; } else if ( !strcmp(k, "-n") ) { name = argv[++i]; } else if ( !strcmp(k, "--rate") || !strcmp(k, "-r") || !strcmp(k, "-R") ) { info.rate = roar_str2rate(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "--bits") || !strcmp(k, "-B") ) { info.bits = roar_str2bits(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "-b") ) { info.bits = 8; auinfo_changed = 1; } else if ( !strcmp(k, "--channels") || !strcmp(k, "--chans") || !strcmp(k, "-C") ) { info.channels = roar_str2channels(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "-m") ) { info.channels = 1; auinfo_changed = 1; } else if ( !strcmp(k, "--codec") || !strcmp(k, "-E") ) { info.codec = roar_str2codec(argv[++i]); auinfo_changed = 1; } else if ( !strcmp(k, "--aiprofile") ) { if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } auinfo_changed = 1; } else if ( !strcmp(k, "--help") ) { usage(); return 0; } else if ( filename == NULL ) { filename = k; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DEFAULT; if ( (vss = roar_vs_new(server, name, &err)) == NULL ) { fprintf(stderr, "Error: can not connect to server: %s: %s\n", server == NULL ? "(default)" : server, roar_error2str(err)); return 10; } if ( auinfo_changed ) { if ( roar_vs_stream(vss, &info, ROAR_DIR_PLAY, &err) == -1 ) { fprintf(stderr, "Error: can not create new stream: %s\n", roar_error2str(err)); roar_vs_close(vss, ROAR_VS_TRUE, NULL); return 10; } } if ( roar_vs_file_simple(vss, filename, &err) == -1 ) { fprintf(stderr, "Error: can not open file: %s: %s\n", filename, roar_error2str(err)); roar_vs_close(vss, ROAR_VS_TRUE, NULL); return 10; } roar_vs_run(vss, NULL); roar_vs_sync(vss, ROAR_VS_WAIT, NULL); roar_vs_close(vss, ROAR_VS_FALSE, NULL); return 0; } //ll roaraudio-1.0beta11/roarclients/roarclientpass.c0000644000175000017500000002002312264733644020211 0ustar phiphi//roarclientpass.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * ckport: ignore-symbol: roar_socket_open of target libroar0 -- Used to get a clientfh. */ #include void usage (void) { printf("roarclientpass [OPTIONS]...\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --stdin - Client is on stdin\n" " --stdout - Client is on stdout\n" " --stdio - Same as --stdin --stdout\n" " --stderr - Client is on stderr\n" " --client-fh FH - Client is on FH\n" " --proto PROTO - Client uses protocol PROTO (default: RoarAudio)\n" " --byteorder BO - Client uses byteorder BO (default: network)\n" " --listen - This is a listen mode connection\n" " --command CMD - Command to use: passfh or exec (default: passfh)\n" " --mode MODE - Set mode of operation: none, listen, connect (default: none)\n" " --bind BIND - Set host/node/path for mode listen and connect\n" " --port PORT - Set port for mode listen and connect\n" // " --type TYPE - Set type for mode listen and connect (default: unknown)\n" " --help - Show this help\n" ); } #define _BV(x) (1<<(x)) #define F_STDIN _BV(ROAR_STDIN) #define F_STDOUT _BV(ROAR_STDOUT) #define F_STDERR _BV(ROAR_STDERR) int run (int client, int in, int out) { struct roar_vio_calls socks[3]; struct roar_vio_select vios[4]; int alive = 1; int ret; ssize_t len; char buf[1024]; int i; roar_vio_open_fh_socket(&(socks[0]), client); roar_vio_open_fh_socket(&(socks[1]), in); roar_vio_open_fh_socket(&(socks[2]), out); while (alive) { ROAR_VIO_SELECT_SETVIO(&(vios[0]), &(socks[0]), ROAR_VIO_SELECT_READ); ROAR_VIO_SELECT_SETVIO(&(vios[1]), &(socks[0]), ROAR_VIO_SELECT_WRITE); ROAR_VIO_SELECT_SETVIO(&(vios[2]), &(socks[1]), ROAR_VIO_SELECT_READ); ROAR_VIO_SELECT_SETVIO(&(vios[3]), &(socks[2]), ROAR_VIO_SELECT_WRITE); while (1) { ret = roar_vio_select(vios, 4, NULL, NULL); if ( ret < 0 ) break; if ( ret == 0 ) continue; if ( vios[0].eventsa && vios[3].eventsa ) break; if ( vios[1].eventsa && vios[2].eventsa ) break; for (i = 0; i < 4; i++) if ( vios[i].eventsa ) vios[i].eventsq |= ROAR_VIO_SELECT_NO_RETEST; } if ( ret < 0 ) break; if ( (vios[0].eventsa & ROAR_VIO_SELECT_READ) && (vios[3].eventsa & ROAR_VIO_SELECT_WRITE) ) { len = roar_vio_read(&(socks[0]), buf, sizeof(buf)); if ( len < 1 ) { alive = 0; } else { if ( roar_vio_write(&(socks[2]), buf, len) != len ) break; } } if ( (vios[1].eventsa & ROAR_VIO_SELECT_WRITE) && (vios[2].eventsa & ROAR_VIO_SELECT_READ) ) { len = roar_vio_read(&(socks[1]), buf, sizeof(buf)); if ( len < 1 ) { alive = 0; } else { if ( roar_vio_write(&(socks[0]), buf, len) != len ) break; } } } roar_vio_close(&(socks[0])); roar_vio_close(&(socks[1])); roar_vio_close(&(socks[2])); return 0; } int main (int argc, char * argv[]) { struct roar_connection con; struct roar_client client; const char * server = NULL; const char * k; int i; int clientfh = -1; int cflags = 0; int flags = 0; int proto = ROAR_PROTO_ROARAUDIO; int byteorder = ROAR_BYTEORDER_NETWORK; int mode = ROAR_SOCKET_MODE_NONE; int type = ROAR_SOCKET_TYPE_UNKNOWN; const char * host = NULL; int port = -1; enum {PASSFH, EXEC} command = PASSFH; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "--server") || !strcmp(k, "-s") ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( !strcmp(k, "--stdin") ) { cflags |= F_STDIN; } else if ( !strcmp(k, "--stdout") ) { cflags |= F_STDOUT; } else if ( !strcmp(k, "--stderr") ) { cflags |= F_STDERR; } else if ( !strcmp(k, "--stdio") ) { cflags |= F_STDIN|F_STDOUT; } else if ( !strcmp(k, "--client-fh") ) { ROAR_CKHAVEARGS(1); clientfh = atoi(argv[++i]); } else if ( !strcmp(k, "--proto") ) { ROAR_CKHAVEARGS(1); proto = roar_str2proto(argv[++i]); } else if ( !strcmp(k, "--byteorder") ) { ROAR_CKHAVEARGS(1); byteorder = roar_str2byteorder(argv[++i]); } else if ( !strcmp(k, "--listen") ) { flags |= ROAR_CLIENTPASS_FLAG_LISTEN; } else if ( !strcmp(k, "--command") ) { ROAR_CKHAVEARGS(1); k = argv[++i]; if ( !strcasecmp(k, "passfh") ) { command = PASSFH; } else if ( !strcasecmp(k, "exec") ) { command = EXEC; } else { ROAR_ERR("unknown command: %s", k); return 1; } } else if ( !strcmp(k, "--mode") ) { ROAR_CKHAVEARGS(1); k = argv[++i]; if ( !strcasecmp(k, "none") ) { mode = ROAR_SOCKET_MODE_NONE; } else if ( !strcasecmp(k, "listen") ) { mode = ROAR_SOCKET_MODE_LISTEN; flags |= ROAR_CLIENTPASS_FLAG_LISTEN; } else if ( !strcasecmp(k, "connect") ) { mode = ROAR_SOCKET_MODE_CONNECT; flags |= ROAR_CLIENTPASS_FLAG_LISTEN; flags -= ROAR_CLIENTPASS_FLAG_LISTEN; } else { ROAR_ERR("unknown mode: %s", k); return 1; } } else if ( !strcmp(k, "--bind") ) { ROAR_CKHAVEARGS(1); host = argv[++i]; } else if ( !strcmp(k, "--port") ) { ROAR_CKHAVEARGS(1); port = atoi(argv[++i]); } else if ( !strcmp(k, "--help") || !strcmp(k, "-h") ) { usage(); return 0; } else { ROAR_ERR("unknown argument: %s", k); usage(); return 1; } } if ( cflags & F_STDERR ) { #ifdef ROAR_HAVE_SYSLOG roar_debug_set_stderr_mode(ROAR_DEBUG_MODE_SYSLOG); #else roar_debug_set_stderr_vio(roar_stderr); #endif } else { roar_debug_set_stderr_vio(roar_stderr); } if ( mode != ROAR_SOCKET_MODE_NONE ) { if ( clientfh != -1 ) { ROAR_ERR("Too may socket types given"); return 30; } if ( host == NULL ) { ROAR_ERR("No bind address given. Use --bind."); return 33; } clientfh = roar_socket_open(mode, type, host, port); if ( clientfh == -1 ) { ROAR_ERR("Unabled to open socket"); return 31; } } if ( clientfh == -1 ) { if ( cflags & F_STDIN ) { clientfh = ROAR_STDIN; } else if ( cflags & F_STDOUT ) { clientfh = ROAR_STDOUT; } else if ( cflags & F_STDERR ) { clientfh = ROAR_STDERR; } else { ROAR_ERR("No client socket given"); return 32; } } roar_client_new(&client); roar_client_set_proto(&client, proto, byteorder); if ( command != EXEC ) roar_client_set_fh(&client, clientfh); if ( roar_simple_connect(&con, server, "roarclientpass") == -1 ) { ROAR_ERR("Can not connect to server"); return 10; } switch (command) { case PASSFH: if ( roar_client_pass(&con, &client, flags) == -1 ) { ROAR_ERR("Can not pass client fh to server"); roar_disconnect(&con); return 20; } break; case EXEC: if ( roar_client_exec(&con, &client, flags) == -1 ) { ROAR_ERR("Can not exec client on server"); roar_disconnect(&con); return 20; } if ( run(client.fh, clientfh, cflags & F_STDOUT ? ROAR_STDOUT : clientfh) == -1 ) { ROAR_ERR("Can not run data copy runner"); return 20; } return 0; break; } roar_disconnect(&con); return 0; } //ll roaraudio-1.0beta11/roarclients/roarctl.c0000644000175000017500000012324412264733645016640 0ustar phiphi//roarctl.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * ckport: ignore-symbol: roar_req of target libroar0 -- Used within ping command. */ #define _UNITS_T_BASE_USEC #include #include #include #if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_SETUID) #define _POSIX_USERS #endif #ifdef _POSIX_USERS #include #include #endif #include #include #ifdef ROAR_HAVE_LIBM #include #endif int g_verbose = 0; void display_client (struct roar_connection * con, int id); void display_stream (struct roar_connection * con, int id); int display_mixer (struct roar_connection * con, int stream); int show_meta_all (struct roar_connection * con, int id); void usage (void) { printf("roarctl [OPTIONS]... COMMAND [OPTS] [COMMAND [OPTS] [COMMAND [OPTS] [...]]]\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --help - Show this help\n" " --verbose -v - Show verbose output\n" " --list-aiprofiles - Show audio info profiles and exit\n" " --list-libstandards - Gets list of library (libroar) supported standards\n" " --enum-servers - Show a list of possible servers\n" " --hash-password - Hash a password and exit\n" ); printf("\nCommands:\n\n"); printf( " help - Show this help\n" " sleep TIME - Sleeps for TIME seconds\n" #ifdef ROAR_HAVE_GETTIMEOFDAY " ping NUM - Do NUM pings using NOOP commands\n" #endif " servername - Show name of server currently connected to\n" " whoami - Get own client ID\n" "\n" " beep - Ask the server to beep.\n" "\n" " listaiprofiles - list audio info profiles\n" " aiprofileget PROFILE - show audio info profile PROFILE\n" "\n" " standby, off - Go into standby mode\n" " resume, on - Go into active mode\n" " standbymode - Show current standby mode\n" " exit - Quits the roard (must be used as last command)\n" " terminate - Like exit but let the server up to serve still connected clients,\n" " new clients cann't connect and the server terminates after the last\n" " client disconnected\n" "\n" " volume ID CHAN [scale S] V0 V1...\n" " - Sets volume for stream ID\n" " CHAN is the number of channels or 'mono' or 'stereo'\n" " if mono or stereo is chosen roarctl trys to set\n" " sensfull values for all channels even if the output\n" " is has more channels.\n" " An optional scale can be given using S.\n" " all other args are the volumes of the channels\n" " you may use integer or percent values.\n" " percent values can floating points.\n" "\n" " flag ID FLAGS - Sets flags FLAGS on stream ID. FLAGS may be a comma\n" " separated list of flags.\n" " unflag ID FLAGS - Unsets flags on a stream. See flag.\n" " toogleflag ID FLAGS - Toggels flags on a stream. See flag.\n" " protectflag ID FLAGS - Protects flags on a stream. Those flags can not be\n" " changed anymore after the they got protected. See flag.\n" "\n" " role ID ROLE - Set role ROLE on stream ID.\n" "\n" " kick TYPE ID - Kicks object of TYPE with id ID\n" " Types: client stream sample source\n" " newvirtual P D E R B C - Adds a new virtual (child) stream\n" " Parameters:\n" " P: Parent stream ID, D: Direction,\n" " E: codEc, R: sample Rate,\n" " B: bits per sample, C: nummer of channels\n" "\n" " metaget ID TYPE - Read meta date of type TYPE from stream ID\n" // TODO: document metaset here. " metasave ID FILE - Saves meta data of stream ID to file FILE\n" " metaload ID FILE - Loads meta data from file FILE and set it on stream ID\n" "\n" " serverinfo - Gets general information about the server\n" " libinfo - Gets general information about the library (libroar)\n" " servertime - Gets server's time\n" " serveroinfo - Gets Information about server output\n" " serveroinfo2 DIR - Gets Information about server output for stream direction dir\n" "\n" " serverstandards - Gets list of server supported standards\n" " libstandards - Gets list of library (libroar) supported standards\n" "\n" " listclients - Gets Information about clients\n" " clientinfo ID - Gets Information about client ID\n" " liststreams - Gets Information about streams\n" " streaminfo ID - Gets Information about stream ID\n" " allinfo - Get all infos\n" ); } static void _bin2hex(char * out, char * in, size_t inlen, int uppercase) { const char * tab = uppercase ? "0123456789ABCDEF" : "0123456789abcdef"; unsigned char c; int nib0, nib1; for (; inlen; inlen--) { c = *(in++); nib0 = (c & 0x0F) >> 0; nib1 = (c & 0xF0) >> 4; // printf("inlen=%zu, c=%u, nibs={%i, %i}\n", inlen, (unsigned)c, nib1, nib0); *(out++) = tab[nib1]; *(out++) = tab[nib0]; } *out = 0; } int hash_password (void) { char * pw = NULL; char salt[8]; char digest[24]; char out[2*(8+24)+3+5+1] = "tiger:"; if ( roar_passwd_simple_ask_pw(&pw, "Password to hash?", NULL) == -1 ) return -1; roar_random_gen_nonce(salt, sizeof(salt)); roar_hash_salted_buffer(digest, pw, roar_mm_strlen(pw), ROAR_HT_TIGER, salt, sizeof(salt)); roar_mm_free(pw); _bin2hex(out+6, salt, sizeof(salt), 0); out[6+16] = ':'; _bin2hex(out+6+16+1, digest, sizeof(digest), 0); out[sizeof(out)-1] = 0; printf("Password: %s\n", out); return 0; } int enum_servers (void) { struct roar_server * list; struct roar_server * c; int flags = ROAR_ENUM_FLAG_DESC|ROAR_ENUM_FLAG_LOCATION; int dir = -1; int socktype = -1; int i; if ( (list = roar_enum_servers(flags, dir, socktype)) == NULL ) return -1; printf("Server Location Description\n"); printf("----------------------------------------------------------------------\n"); for (i = 0; ; i++) { c = &(list[i]); printf("%-16s %-16s %s\n", c->server == NULL ? "(default)" : c->server, c->location == NULL ? "" : c->location, c->description == NULL ? "" : c->description ); if ( c->server == NULL ) break; } roar_enum_servers_free(list); return 0; } #ifdef ROAR_HAVE_GETTIMEOFDAY int ping (struct roar_connection * con, int num) { struct timeval try, ans; struct roar_message m; register int ret; int i; double cur, min = 3600*1000, max = 0, sum = 0; if ( num == 0 ) return 0; for (i = 0; i < num; i++) { memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_NOOP; m.stream = -1; m.datalen = 0; // we use roar_req() directly here because of speed. // roar_noop() does basicly the same but is a bit slower. gettimeofday(&try, NULL); ret = roar_req(con, &m, NULL); gettimeofday(&ans, NULL); if ( ret == -1 ) return -1; while (ans.tv_sec > try.tv_sec) { ans.tv_sec--; ans.tv_usec += 1000000; } ans.tv_usec -= try.tv_usec; cur = ans.tv_usec/1000.0; printf("Pong from server: seq=%i time=%.3f%cs\n", i, cur < 0.5 ? cur*1000.0 : cur, cur < 0.5 ? 'u' : 'm'); sum += cur; if ( min > cur ) min = cur; if ( cur > max ) max = cur; if ( i != (num - 1) ) roar_sleep(1); } printf("\n--- ping statistics ---\n"); printf("%i packets transmitted\n", i); printf("rtt min/avg/max = %.3f/%.3f/%.3f ms\n", min, sum/(double)i, max); return 0; } #endif #define _pm(m,n) if ( info->m != NULL ) printf(con != NULL ? "Server %-15s: %s\n" : "Library %-14s: %s\n", (n), (info->m)); void server_info (struct roar_connection * con) { struct roar_server_info * info = con != NULL ? roar_server_info(con) : roar_library_info(); long hostid; if ( info == NULL ) { fprintf(stderr, "Error: can not get server info\n"); return; } _pm(version, "Version"); _pm(location, "Location"); _pm(description, "Description"); _pm(contact, "Contact"); _pm(serial, "Serial"); _pm(address, "Address"); _pm(uiurl, "UI URL"); _pm(license, "License"); // _pm(hostid, "HostID"); if ( info->hostid != NULL ) { if ( sscanf(info->hostid, "0x%lx", &hostid) != 1 ) hostid = 0; if ( hostid ) { printf(con != NULL ? "Server %-15s: %s (%li.%li.%li.%li)\n" : "Library %-14s: %s (%li.%li.%li.%li)\n", "HostID", info->hostid, ((hostid & 0x00FF0000UL) >> 16UL), ((hostid & 0xFF000000UL) >> 24UL), ((hostid & 0x000000FFUL) >> 0UL), ((hostid & 0x0000FF00UL) >> 8UL) ); } else { _pm(hostid, "HostID"); } } _pm(build, "Build"); _pm(un.sysname, "System sysname"); _pm(un.release, "System release"); _pm(un.nodename, "System nodename"); _pm(un.machine, "System machine"); roar_server_info_free(info); } #undef _pm void server_time (struct roar_connection * con) { struct roar_time time; #ifdef ROAR_HAVE_CTIME_R time_t server_time; char server_time_buf[32]; #endif if ( roar_get_time(con, &time) == -1 ) { fprintf(stderr, "Error: can not get server time: %s\n", roar_vs_strerr(roar_error)); return; } #ifdef ROAR_HAVE_CTIME_R server_time = time.t_sec; if ( ctime_r(&server_time, server_time_buf) == NULL ) server_time_buf[0] = 0; if ( server_time_buf[0] ) if ( server_time_buf[strlen(server_time_buf)-1] == '\n' ) server_time_buf[strlen(server_time_buf)-1] = 0; #endif if ( g_verbose ) { printf("Server time : %s%s%s%" LIBROAR__ll "u.%06" LIBROAR__ll "u [+%" LIBROAR__ll "u/2^64] sec\n", #ifdef ROAR_HAVE_CTIME_R "\"", server_time_buf, "\" ", #else "", "", "", #endif (LIBROAR__longlong unsigned int)time.t_sec, (LIBROAR__longlong unsigned int) time.t_ssec / (LIBROAR__longlong unsigned int)18446744073709LLU, (LIBROAR__longlong unsigned int) time.t_ssec); } else { if ( time.c_freq == 1000000000LL && time.t_ssec == 0 ) { printf("Server time : %s%s%s%" LIBROAR__ll "u sec\n", #ifdef ROAR_HAVE_CTIME_R "\"", server_time_buf, "\" ", #else "", "", "", #endif (LIBROAR__longlong unsigned int)time.t_sec); } else { printf("Server time : %s%s%s%" LIBROAR__ll "u.%06" LIBROAR__ll"u sec\n", #ifdef ROAR_HAVE_CTIME_R "\"", server_time_buf, "\" ", #else "", "", "", #endif (LIBROAR__longlong unsigned int)time.t_sec, (LIBROAR__longlong unsigned int) time.t_ssec / (LIBROAR__longlong unsigned int)18446744073709LLU); } } if ( time.c_freq ) printf("Server clock frequency: %f Hz\n", (float)((double)time.c_freq / (double)1000000000.)); if ( time.c_drift ) { #ifdef ROAR_HAVE_LIBM printf("Server clock drift : %" LIBROAR__ll "u:2^64 (~10^%f)\n", (LIBROAR__longlong unsigned int)time.c_drift, logf((float)time.c_drift)/2.302585f); #else printf("Server clock drift : %" LIBROAR__ll "u:2^64\n", (LIBROAR__longlong unsigned int)time.c_drift); #endif } } void server_oinfo (struct roar_connection * con, int dir) { struct roar_stream s; if ( roar_server_oinfo(con, &s, dir) == -1 ) { fprintf(stderr, "Error: can not get server output info\n"); return; } printf("Stream direction : %s\n", roar_dir2str(s.dir)); printf("Server Output rate : %i Hz\n", s.info.rate); printf("Server Output bits : %i\n", s.info.bits); printf("Server Output channels: %i\n", s.info.channels); printf("Server Output codec : %i (%s%s)\n", s.info.codec, roar_codec2str(s.info.codec), s.info.codec == ROAR_CODEC_DEFAULT ? " native" : ""); // printf("Server Output rate: %i", s.info.rate); if ( g_verbose > 1 && s.pos != (uint32_t)-1 ) { if ( s.info.rate && s.info.channels ) { printf("Server Position : %lu S (%.3fs)\n", (unsigned long int) s.pos, (float)s.pos/(s.info.rate*s.info.channels)); } else { printf("Server Position : %lu S\n", (unsigned long int) s.pos); } } } static void print_stds (const struct roar_stds * stds) { size_t i; int vendor, standard, version; char numbuf[2][8]; const char * vendor_name; for (i = 0; i < stds->stds_len; i++) { vendor = ROAR_STD_VENDOR(stds->stds[i]); standard = ROAR_STD_STD(stds->stds[i]); version = ROAR_STD_VERSION(stds->stds[i]); if ( (vendor_name = roar_stds_vendor2str(vendor)) == NULL ) { snprintf(numbuf[0], sizeof(numbuf[0]), "%i", vendor); numbuf[0][sizeof(numbuf[0])-1] = 0; vendor_name = numbuf[0]; } if ( version == 0 ) { numbuf[1][0] = 0; } else { snprintf(numbuf[1], sizeof(numbuf[1]), "-%i", version); numbuf[1][sizeof(numbuf[1])-1] = 0; } printf("Server standard : %s-%i%s\n", vendor_name, standard, numbuf[1]); } } void server_standards (struct roar_connection * con) { struct roar_stds * stds; if ( roar_caps_stds(con, &stds, NULL, -1) == -1 ) { fprintf(stderr, "Error: can not get server standards\n"); return; } print_stds(stds); roar_stds_free(stds); } void lib_standards (void) { print_stds(libroar_libstds()); } const char * proc_name (pid_t pid) { static char ret[80] = "?"; #ifdef __linux__ char file[80], buf[80], *r; int i; snprintf(file, sizeof(file)-1, "/proc/%i/exe", pid); file[sizeof(file)-1] = 0; ret[0] = '?'; ret[1] = 0; if ( (i = readlink(file, buf, sizeof(buf)-1)) != -1 ) { buf[i] = 0; if ( (r = strrchr(buf, '/')) != NULL ) { r++; if ( *r != 0 ) { strncpy(ret, r, sizeof(ret)-1); ret[sizeof(ret)-1] = 0; } } } #else (void)pid; #endif return ret; } void list_clients (struct roar_connection * con) { int i; int num; int id[ROAR_CLIENTS_MAX]; if ( (num = roar_list_clients(con, id, ROAR_CLIENTS_MAX)) == -1 ) { fprintf(stderr, "Error: can not get client list\n"); return; } for (i = 0; i < num; i++) { display_client(con, id[i]); } } void display_client (struct roar_connection * con, int id) { static int self_id = -1; static struct roar_client self_client_store; static struct roar_client * self_client = NULL; struct roar_client c; char tmp[80]; int h; #ifdef _POSIX_USERS struct group * grp = NULL; struct passwd * pwd = NULL; #endif if ( self_id == -1 ) { if ( (self_id = roar_get_clientid(con)) != -1 ) { if ( roar_get_client(con, &self_client_store, self_id) == -1 ) { self_id = -1; } else { self_client = &self_client_store; } } } printf("client %i:\n", id); if ( roar_get_client(con, &c, id) == -1 ) { fprintf(stderr, "Error: can not get client info\n"); return; } if ( c.name[0] != '\0' ) printf("Client name : %s\n", c.name); if ( roar_nnode_get_socktype(&(c.nnode)) != ROAR_SOCKET_TYPE_UNKNOWN ) { if ( roar_nnode_to_str(&(c.nnode), tmp, sizeof(tmp)) == 0 ) { printf("Client network node : %s\n", tmp); } } if ( c.pid != -1 ) { if ( self_id != -1 && roar_nnode_cmp(&(self_client->nnode), &(c.nnode)) == 0 ) { printf("Client PID : %i(%s)\n", c.pid, proc_name(c.pid)); } else { printf("Client PID : %i\n", c.pid); } } if ( c.uid != -1 ) { #ifdef _POSIX_USERS if ( self_id != -1 && roar_nnode_cmp(&(self_client->nnode), &(c.nnode)) == 0 ) { pwd = getpwuid(c.uid); grp = getgrgid(c.gid); printf("Client UID/GID : %i(%s)/%i(%s)\n", c.uid, pwd ? pwd->pw_name : "?", c.gid, grp ? grp->gr_name : "?"); } else { #else if ( 1 ) { #endif printf("Client UID/GID : %i/%i\n", c.uid, c.gid); } } if ( g_verbose && c.proto != ROAR_PROTO_NONE ) { printf("Client Protocol : %s\n", roar_proto2str(c.proto)); } if ( g_verbose && c.byteorder != ROAR_BYTEORDER_UNKNOWN ) { if ( c.byteorder == ROAR_BYTEORDER_NETWORK ) { roar_mm_strscpy(tmp, " (network byteorder"); } else { *tmp = 0; } if ( c.byteorder == ROAR_BYTEORDER_NATIVE ) { if ( *tmp ) { roar_mm_strscat(tmp, ", native"); } else { roar_mm_strscpy(tmp, " (native"); } } if ( *tmp ) roar_mm_strscat(tmp, ")"); printf("Client Byteorder : %s%s\n", roar_byteorder2str(c.byteorder), tmp); } if ( c.execed != -1 ) printf("Execed stream : %i\n", c.execed); for (h = 0; h < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; h++) if ( c.streams[h] != -1 ) printf("stream : %i\n", c.streams[h]); } void list_streams (struct roar_connection * con) { int i; int num; int id[ROAR_STREAMS_MAX]; if ( (num = roar_list_streams(con, id, ROAR_STREAMS_MAX)) == -1 ) { fprintf(stderr, "Error: can not get stream list\n"); return; } for (i = 0; i < num; i++) { display_stream(con, id[i]); } } void display_stream (struct roar_connection * con, int id) { char chanmap[ROAR_MAX_CHANNELS]; struct roar_stream s; struct roar_stream_info info; char buffer[1024]; char * flags = buffer; char * name = buffer; char * infotext; const char * mime; size_t len; printf("stream %i:\n", id); if ( roar_get_stream(con, &s, id) == -1 ) { fprintf(stderr, "Error: can not get stream info\n"); return; } printf("Stream direction : %s\n", roar_dir2str(s.dir)); if ( roar_stream_get_name(con, &s, name, sizeof(buffer)) == 0 ) printf("Stream name : %s\n", name); if ( (int)s.pos_rel_id == -1 ) { printf("Relativ position id : none (stream not synchronized)\n"); } else if ( (int)s.pos_rel_id == id ) { printf("Relativ position id : %i (self synchronized)\n", s.pos_rel_id); } else { printf("Relativ position id : %i (synchronized)\n", s.pos_rel_id); } if ( g_verbose > 1 && s.pos != (uint32_t)-1 ) { if ( s.info.rate && s.info.channels ) { printf("Position : %lu S (%.3fs)\n", (unsigned long int) s.pos, (float)s.pos/(s.info.rate*s.info.channels)); } else { printf("Position : %lu S\n", (unsigned long int) s.pos); } } switch (s.dir) { case ROAR_DIR_MIDI_IN: case ROAR_DIR_MIDI_OUT: infotext = " ticks/s"; break; case ROAR_DIR_LIGHT_IN: case ROAR_DIR_LIGHT_OUT: infotext = " updates/s"; break; default: infotext = " Hz"; } if ( s.info.rate ) printf("Stream sample rate : %i%s\n", s.info.rate, infotext); if ( s.info.bits ) printf("Stream bits : %i\n", s.info.bits); if ( s.info.channels ) printf("Stream channels : %i\n", s.info.channels); mime = roar_codec2mime(s.info.codec); printf("Stream codec : %2i (%s%s%s%s)\n", s.info.codec, roar_codec2str(s.info.codec), s.info.codec == ROAR_CODEC_DEFAULT ? " native" : "", mime == NULL ? "" : " mimetype:", mime == NULL ? "" : mime ); if ( roar_stream_get_info(con, &s, &info) != -1 ) { if ( info.codec != s.info.codec ) { mime = roar_codec2mime(info.codec); printf("Streamed codec : %2i (%s%s%s%s)\n", info.codec, roar_codec2str(info.codec), info.codec == ROAR_CODEC_DEFAULT ? " native" : "", mime == NULL ? "" : " mimetype:", mime == NULL ? "" : mime ); } if ( g_verbose ) { if ( info.block_size ) printf("Stream block size : %i Byte\n", info.block_size); printf("Underruns pre/post : %i/%i\n", info.pre_underruns, info.post_underruns); if ( g_verbose > 1 ) printf("Stream delay : %ims (%.2fm)\n", (int)info.delay/1000, (info.delay*(float)_SPEED_OF_SOUND)); if ( g_verbose > 1 ) printf("Stream mixer : %i\n", info.mixer); if ( g_verbose > 1 ) printf("Stream state : %s\n", roar_streamstate2str(info.state)); if ( g_verbose > 1 ) printf("Stream role : %s\n", roar_role2str(info.role)); *flags = 0; #define _strcat(dst,src) roar_mm_strlcat((dst),(src), sizeof(buffer)) if ( info.flags & ROAR_FLAG_PRIMARY ) _strcat(flags, "primary "); if ( info.flags & ROAR_FLAG_SYNC ) _strcat(flags, "sync "); if ( info.flags & ROAR_FLAG_OUTPUT ) _strcat(flags, "output "); if ( info.flags & ROAR_FLAG_SOURCE ) _strcat(flags, "source "); if ( info.flags & ROAR_FLAG_META ) _strcat(flags, "meta "); if ( info.flags & ROAR_FLAG_AUTOCONF ) _strcat(flags, "autoconf "); if ( info.flags & ROAR_FLAG_CLEANMETA ) _strcat(flags, "cleanmeta "); if ( info.flags & ROAR_FLAG_HWMIXER ) _strcat(flags, "hwmixer "); if ( info.flags & ROAR_FLAG_PAUSE ) _strcat(flags, "pause "); if ( info.flags & ROAR_FLAG_MUTE ) _strcat(flags, "mute "); if ( info.flags & ROAR_FLAG_MMAP ) _strcat(flags, "mmap "); if ( info.flags & ROAR_FLAG_ANTIECHO ) _strcat(flags, "antiecho "); if ( info.flags & ROAR_FLAG_VIRTUAL ) _strcat(flags, "virtual "); if ( info.flags & ROAR_FLAG_RECSOURCE ) _strcat(flags, "recsource "); if ( info.flags & ROAR_FLAG_PASSMIXER ) _strcat(flags, "passmixer "); if ( info.flags & ROAR_FLAG_PRETHRU ) _strcat(flags, "prethru "); if ( info.flags & ROAR_FLAG_IMMUTABLE ) _strcat(flags, "immutable "); if ( info.flags & ROAR_FLAG_ENHANCE ) _strcat(flags, "enhance "); if ( info.flags & ROAR_FLAG_SINGLESINK ) _strcat(flags, "singlesink "); #undef _strcat printf("Flags : %s\n", flags); } } if ( g_verbose && (s.info.channels != 0 && s.info.channels <= ROAR_MAX_CHANNELS) ) { len = ROAR_MAX_CHANNELS; if ( roar_stream_get_chanmap(con, &s, chanmap, &len) == -1 ) { fprintf(stderr, "Error: can not get stream channel map\n"); } else { if ( roardsp_chanlist2str(chanmap, len, buffer, 1024) == -1 ) { fprintf(stderr, "Error: can not convert channel map into string\n"); } else { printf("Channel Map : %s\n", buffer); } } } if ( s.dir != ROAR_DIR_THRU ) { if ( s.info.channels != 0 && s.info.channels <= ROAR_MAX_CHANNELS ) { display_mixer(con, id); } show_meta_all(con, id); } } int display_mixer (struct roar_connection * con, int stream) { struct roar_stream_rpg rpg; struct roar_mixer_settings mixer; struct roar_stream s; int channels; int i; float fs; if ( roar_get_vol(con, stream, &mixer, &channels) == -1 ) { fprintf(stderr, "Error: can not get stream mixer info for stream %i\n", stream); return -1; } roar_stream_new_by_id(&s, stream); if ( roar_stream_get_rpg(con, &s, &rpg) != -1 ) { printf("ReplayGain Mode : %s\n", roar_rpgmode2str(rpg.mode)); } #ifdef ROAR_HAVE_LIBM #define _DB ", %.2fdB" #else #define _DB "" #endif fs = (float)mixer.scale / 100.; if ( channels ) { // we hide RPG info for zero-channel streams printf("Mixer ReplayGain : %i/%i (%.2f%%" _DB ")\n", mixer.rpg_mul, mixer.rpg_div, 100.*(float)mixer.rpg_mul/((float)mixer.rpg_div) #ifdef ROAR_HAVE_LIBM , 20*log10f((float)mixer.rpg_mul/(float)mixer.rpg_div) #endif ); } for (i = 0; i < channels; i++) printf("Mixer volume chan %2i : %i/%i (%.2f%%" _DB ")\n", i, mixer.mixer[i], mixer.scale, (float)mixer.mixer[i]/fs #ifdef ROAR_HAVE_LIBM , 20*log10f((float)mixer.mixer[i]/(float)mixer.scale) #endif ); return 0; } static unsigned int set_mixer_parse_volume (char * k, int len, uint16_t scale) { float fs = scale; switch (k[len - 1]) { case '%': k[len - 1] = 0; return (atof(k)*fs)/100.; break; #ifdef ROAR_HAVE_LIBM case 'b': case 'B': // TODO: can we hanle the error better? if ( len < 2 ) return 0; k[len - 2] = 0; return powf(10, atof(k)/20.f)*fs; break; #endif } return atoi(k); } int set_mixer (struct roar_connection * con, int * cur, int max, char * arg[]) { uint16_t scale = 65535; int chans = 0; int id; int i; int len; int old_chans; char * k; struct roar_mixer_settings mixer; struct roar_mixer_settings old_mixer; int mode = ROAR_SET_VOL_ALL; if (*cur + 2 > max) return -1; id = atoi(arg[++(*cur)]); k = arg[++(*cur)]; if ( !strcmp(arg[*cur + 1], "scale") ) { (*cur)++; // 'scale' (*cur)++; scale = set_mixer_parse_volume(arg[*cur], strlen(arg[*cur]), 65535); } mixer.scale = scale; if ( roar_get_vol(con, id, &old_mixer, &old_chans) == -1 ) { fprintf(stderr, "Error: can not get stream mixer info for stream %i\n", id); return -1; } if ( strcmp(k, "mono") == 0 ) { chans = 1; mode = ROAR_SET_VOL_UNMAPPED; } else if ( strcmp(k, "stereo") == 0 ) { chans = 2; mode = ROAR_SET_VOL_UNMAPPED; } else { chans = atoi(k); } // ensure most simple mode: if ( old_chans == chans && mode == ROAR_SET_VOL_UNMAPPED ) mode = ROAR_SET_VOL_ALL; if ( *cur + chans > max ) return -1; for (i = 0; i < chans; i++) { k = arg[++(*cur)]; len = strlen(k); mixer.mixer[i] = set_mixer_parse_volume(k, len, scale); } if ( roar_set_vol(con, id, &mixer, chans, mode) == 0 ) return 0; // no fallback if already using ROAR_SET_VOL_ALL: if ( mode == ROAR_SET_VOL_ALL ) return -1; if ( roar_conv_volume(&mixer, &mixer, old_chans, chans) == -1 ) return -1; chans = old_chans; mode = ROAR_SET_VOL_ALL; if ( roar_set_vol(con, id, &mixer, chans, mode) == 0 ) return 0; return -1; } int newvirtual (struct roar_connection * con, char *p_s, char *d_s, char *e_s, char *r_s, char *b_s, char *c_s) { struct roar_stream s; int dir = roar_str2dir(d_s); int parent = atoi(p_s); ROAR_DBG("newvirtual(*): dir=%i, parent=%i", dir, parent); if ( roar_stream_new(&s, roar_str2rate(r_s), roar_str2channels(c_s), roar_str2bits(b_s), roar_str2codec(e_s)) == -1 ) return -1; return roar_simple_connect_virtual(con, &s, parent, dir); } int set_meta (struct roar_connection * con, int id, char * mode, char * type, char * val) { struct roar_meta meta; struct roar_stream s; int mode_i = ROAR_META_MODE_SET; if ( roar_stream_new_by_id(&s, id) == -1 ) return -1; // printf("set_meta(*): mode='%s', type='%s', val='%s'\n", mode, type, val); if ( strcmp(mode, "add") == 0 ) { mode_i = ROAR_META_MODE_ADD; } meta.type = roar_meta_inttype(type); meta.value = val; meta.key[0] = 0; if ( meta.type == -1 ) { fprintf(stderr, "Error: unknown type: %s\n", type); return -1; } // printf("D: type=%i, mode=%i\n", meta.type, mode_i); if ( roar_stream_meta_set(con, &s, mode_i, &meta) == -1 ) return -1; meta.type = ROAR_META_TYPE_NONE; meta.value = NULL; return roar_stream_meta_set(con, &s, ROAR_META_MODE_FINALIZE, &meta); } int load_meta (struct roar_connection * con, int id, char * file) { struct roar_meta meta; struct roar_stream s; int mode_i = ROAR_META_MODE_SET; FILE * in; char lion[1024]; char * v; if ( roar_stream_new_by_id(&s, id) == -1 ) return -1; if ( (in = fopen(file, "r")) == NULL ) return -1; while (fgets(lion, 1024, in) != NULL) { if ( (v = strtok(lion, "\r\n")) != NULL ) if ( (v = strtok(NULL, "\r\n")) != NULL ) *(v-1) = 0; if ( (v = strstr(lion, "=")) == NULL ) { fprintf(stderr, "Error: can not parse meta data lion: %s\n", lion); continue; } *v++ = 0; meta.type = roar_meta_inttype(lion); meta.value = v; meta.key[0] = 0; if ( meta.type == -1 ) { fprintf(stderr, "Error: unknown type: %s\n", lion); continue; } if ( roar_stream_meta_set(con, &s, mode_i, &meta) == -1 ) { fclose(in); return -1; } } fclose(in); meta.type = ROAR_META_TYPE_NONE; meta.value = NULL; return roar_stream_meta_set(con, &s, ROAR_META_MODE_FINALIZE, &meta); } int show_meta_type (struct roar_connection * con, int id, const char * type) { struct roar_meta meta; struct roar_stream s; if ( roar_stream_new_by_id(&s, id) == -1 ) return -1; meta.type = roar_meta_inttype(type); if ( meta.type == -1 ) { fprintf(stderr, "Error: unknown type: %s\n", type); return -1; } if ( roar_stream_meta_get(con, &s, &meta) == -1 ) return -1; printf("Meta %-17s: %s\n", roar_meta_strtype(meta.type), meta.value); roar_meta_free(&meta); return 0; } int show_meta_all (struct roar_connection * con, int id) { struct roar_stream s; int types[ROAR_META_MAX_PER_STREAM]; int i; int len; if ( roar_stream_new_by_id(&s, id) == -1 ) return -1; if ( (len = roar_stream_meta_list(con, &s, types, ROAR_META_MAX_PER_STREAM)) == -1 ) return -1; for (i = 0; i < len; i++) show_meta_type(con, id, roar_meta_strtype(types[i])); return 0; } int save_meta (struct roar_connection * con, int id, char * file) { struct roar_stream s; struct roar_meta meta; int types[ROAR_META_MAX_PER_STREAM]; int i; int len; FILE * out; if ( roar_stream_new_by_id(&s, id) == -1 ) return -1; if ( (len = roar_stream_meta_list(con, &s, types, ROAR_META_MAX_PER_STREAM)) == -1 ) return -1; if ( (out = fopen(file, "w")) == NULL ) return -1; for (i = 0; i < len; i++) { /* show_meta_type(con, id, roar_meta_strtype(types[i])); */ meta.type = types[i]; if ( roar_stream_meta_get(con, &s, &meta) == -1 ) continue; // printf("Meta %-17s: %s\n", roar_meta_strtype(meta.type), meta.value); fprintf(out, "%s=%s\n", roar_meta_strtype(meta.type), meta.value); roar_meta_free(&meta); } fclose(out); return 0; } int set_flags (struct roar_connection * con, int id, int action, char * flags) { uint32_t f = ROAR_FLAG_NONE; char * c; struct roar_stream s[1]; if ( roar_stream_new_by_id(s, id) == -1 ) return -1; c = strtok(flags, ","); while (c != NULL) { if ( !strcmp(c, "meta") ) { f |= ROAR_FLAG_META; } else if ( !strcmp(c, "primary") ) { f |= ROAR_FLAG_PRIMARY; } else if ( !strcmp(c, "sync") ) { f |= ROAR_FLAG_SYNC; } else if ( !strcmp(c, "cleanmeta") ) { f |= ROAR_FLAG_CLEANMETA; } else if ( !strcmp(c, "hwmixer") ) { f |= ROAR_FLAG_HWMIXER; } else if ( !strcmp(c, "pause") ) { f |= ROAR_FLAG_PAUSE; } else if ( !strcmp(c, "mute") ) { f |= ROAR_FLAG_MUTE; } else if ( !strcmp(c, "mmap") ) { f |= ROAR_FLAG_MMAP; } else if ( !strcmp(c, "antiecho") ) { f |= ROAR_FLAG_ANTIECHO; } else if ( !strcmp(c, "recsource") ) { f |= ROAR_FLAG_RECSOURCE; } else if ( !strcmp(c, "passmixer") ) { f |= ROAR_FLAG_PASSMIXER; } else if ( !strcmp(c, "virtual") ) { f |= ROAR_FLAG_VIRTUAL; } else if ( !strcmp(c, "prethru") ) { f |= ROAR_FLAG_PRETHRU; } else if ( !strcmp(c, "immutable") ) { f |= ROAR_FLAG_IMMUTABLE; } else if ( !strcmp(c, "enhance") ) { f |= ROAR_FLAG_ENHANCE; } else if ( !strcmp(c, "singlesink") ) { f |= ROAR_FLAG_SINGLESINK; } else { fprintf(stderr, "Error: unknown flag: %s\n", c); return -1; } c = strtok(NULL, ","); } return roar_stream_set_flags(con, s, f, action); } int set_role (struct roar_connection * con, int id, int role) { struct roar_stream s; if ( id == -1 ) return -1; if ( roar_stream_new_by_id(&s, id) == -1 ) return -1; if ( roar_stream_set_role(con, &s, role) == -1 ) return -1; return 0; } int show_aiprofile (const char * profile) { struct roar_audio_info info; const char * mime; if ( roar_profile2info(&info, profile) == -1 ) { fprintf(stderr, "Error: unknown profile: %s\n", profile); return -1; } mime = roar_codec2mime(info.codec); printf("Profile Name : %s\n", profile); if ( info.rate ) printf("Profile sample rate : %i\n", info.rate); if ( info.bits ) printf("Profile bits : %i\n", info.bits); if ( info.channels ) printf("Profile channels : %i\n", info.channels); printf("Profile codec : %2i (%s%s%s%s)\n", info.codec, roar_codec2str(info.codec), info.codec == ROAR_CODEC_DEFAULT ? " native" : "", mime == NULL ? "" : " mimetype:", mime == NULL ? "" : mime); return 0; } int list_aiprofiles (void) { const char * list[1024]; ssize_t ret; ssize_t i; ret = roar_profiles_list(list, 1024, 0); if ( ret == -1 ) { fprintf(stderr, "Error: can not read list of profiles\n"); return -1; } for (i = 0; i < ret; i++) { printf("profile %" LIBROAR__ll "i:\n", (LIBROAR__longlong signed int)i); show_aiprofile(list[i]); } return 0; } int main (int argc, char * argv[]) { struct roar_connection con; const char * server = NULL; const char * k = NULL; int i; int t = 0; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "-v") == 0 || strcmp(k, "--verbose") == 0 ) { g_verbose++; } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( strcmp(k, "--list-aiprofiles") == 0 ) { list_aiprofiles(); return 0; } else if ( strcmp(k, "--list-libstandards") == 0 ) { lib_standards(); return 0; } else if ( strcmp(k, "--enum-servers") == 0 ) { enum_servers(); return 0; } else if ( strcmp(k, "--hash-password") == 0 ) { hash_password(); return 0; } else if ( *k == '-' ) { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } else { break; } } // connect if ( roar_simple_connect(&con, server, "roarctl") == -1 ) { fprintf(stderr, "Error: Can not connect to server: %s: %s(%i)\n", server == NULL ? "(default)" : server, roar_vs_strerr(roar_error), roar_error); return 1; } if ( i == argc ) { fprintf(stderr, "Error: No Commands given\n"); return 0; // this is not a fatal error... } for (; i < argc; i++) { k = argv[i]; // cmd is in k printf("--- [ %s ] ---\n", k); if ( !strcmp(k, "help") ) { usage(); } else if ( !strcmp(k, "sleep") ) { ROAR_CKHAVEARGS(1); roar_sleep(atoi(argv[++i])); } else if ( !strcmp(k, "ping") ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_HAVE_GETTIMEOFDAY if ( ping(&con, atoi(argv[++i])) == -1 ) { fprintf(stderr, "Error: can not ping\n"); } #else fprintf(stderr, "Error: ping not supported.\n"); i++; #endif } else if ( !strcmp(k, "servername") ) { printf("Server Name : %s\n", roar_get_connection_server(&con)); } else if ( !strcmp(k, "standby") || !strcmp(k, "off") ) { if ( roar_set_standby(&con, ROAR_STANDBY_ACTIVE) == -1 ) { fprintf(stderr, "Error: can not set mode to standby\n"); } else { printf("going into standby\n"); } } else if ( !strcmp(k, "resume") || !strcmp(k, "on") ) { if ( roar_set_standby(&con, ROAR_STANDBY_INACTIVE) == -1 ) { fprintf(stderr, "Error: can not set mode to active\n"); } else { printf("going into active mode\n"); } } else if ( !strcmp(k, "exit") ) { if ( roar_terminate(&con, 0) == -1 ) { fprintf(stderr, "Error: can not quit server\n"); } else { printf("Server quited\n"); break; } } else if ( !strcmp(k, "terminate") ) { if ( roar_terminate(&con, 1) == -1 ) { fprintf(stderr, "Error: can not terminate server\n"); } else { printf("Server got asked to quited\n"); break; } } else if ( !strcmp(k, "standbymode") ) { t = roar_get_standby(&con); if ( t == -1 ) { fprintf(stderr, "Error: can not get stanby mode\n"); } else if ( t == ROAR_STANDBY_ACTIVE ) { printf("Server is in standby\n"); } else if ( t == ROAR_STANDBY_INACTIVE ) { printf("Server is active\n"); } else { fprintf(stderr, "Error: unknown standby mode: %i\n", t); } } else if ( !strcmp(k, "whoami") ) { printf("My client ID is: %i\n", roar_get_clientid(&con)); } else if ( !strcmp(k, "beep") ) { roar_beep(&con, NULL); } else if ( !strcmp(k, "serverinfo") ) { server_info(&con); } else if ( !strcmp(k, "libinfo") ) { server_info(NULL); } else if ( !strcmp(k, "servertime") ) { server_time(&con); } else if ( !strcmp(k, "serveroinfo") ) { server_oinfo(&con, -1); } else if ( !strcmp(k, "serveroinfo2") ) { t = roar_str2dir(argv[++i]); if ( t == -1 ) { fprintf(stderr, "Error: unknown stream direction: %s\n", argv[i]); } else { server_oinfo(&con, t); } } else if ( !strcmp(k, "serverstandards") ) { server_standards(&con); } else if ( !strcmp(k, "libstandards") ) { lib_standards(); } else if ( !strcmp(k, "listclients") ) { list_clients(&con); } else if ( !strcmp(k, "clientinfo") ) { ROAR_CKHAVEARGS(1); display_client(&con, atoi(argv[++i])); } else if ( !strcmp(k, "liststreams") ) { list_streams(&con); } else if ( !strcmp(k, "streaminfo") ) { ROAR_CKHAVEARGS(1); display_stream(&con, atoi(argv[++i])); } else if ( !strcmp(k, "allinfo") ) { server_info(&con); printf("\n"); server_time(&con); printf("\n"); server_standards(&con); printf("\n"); server_oinfo(&con, -1); printf("\n"); list_clients(&con); printf("\n"); list_streams(&con); } else if ( !strcmp(k, "kick") ) { ROAR_CKHAVEARGS(2); t = roar_str2ot((k = argv[++i])); if ( t == -1 ) { fprintf(stderr, "Error: unknown type: %s\n", k); continue; } //t = atoi(argv[i++]); if ( roar_kick(&con, t, atoi(argv[++i])) == -1 ) { fprintf(stderr, "Error: can not kick %s\n", k); } else { printf("%s kicked\n", k); } } else if ( !strcmp(k, "newvirtual") ) { ROAR_CKHAVEARGS(6); if ( newvirtual(&con, argv[i+1], argv[i+2], argv[i+3], argv[i+4], argv[i+5], argv[i+6]) == -1 ) { fprintf(stderr, "Error: can not create new virtual stream\n"); } else { printf("virtual stream created\n"); } i += 6; } else if ( !strcmp(k, "volume") ) { ROAR_CKHAVEARGS(2); /* we may need more, but this is the minimum */ if ( set_mixer(&con, &i, argc, argv) == -1 ) { fprintf(stderr, "Error: can not set volume\n"); } else { printf("volume changed\n"); } } else if ( !strcmp(k, "flag") ) { ROAR_CKHAVEARGS(2); i++; if ( set_flags(&con, atoi(argv[i]), ROAR_SET_FLAG, argv[i+1]) == -1 ) { fprintf(stderr, "Error: can not set flags\n"); } else { printf("flags changed\n"); } i++; } else if ( !strcmp(k, "unflag") ) { ROAR_CKHAVEARGS(2); i++; if ( set_flags(&con, atoi(argv[i]), ROAR_RESET_FLAG, argv[i+1]) == -1 ) { fprintf(stderr, "Error: can not reset flags\n"); } else { printf("flags changed\n"); } i++; } else if ( !strcmp(k, "toggleflag") ) { ROAR_CKHAVEARGS(2); i++; if ( set_flags(&con, atoi(argv[i]), ROAR_TOGGLE_FLAG, argv[i+1]) == -1 ) { fprintf(stderr, "Error: can not toggle flags\n"); } else { printf("flags changed\n"); } i++; } else if ( !strcmp(k, "protectflag") ) { ROAR_CKHAVEARGS(2); i++; if ( set_flags(&con, atoi(argv[i]), ROAR_NOOP_FLAG|ROAR_PROTECT_FLAG, argv[i+1]) == -1 ) { fprintf(stderr, "Error: can not protect flags\n"); } else { printf("flags protected\n"); } i++; } else if ( !strcmp(k, "role") ) { ROAR_CKHAVEARGS(2); i++; if ( set_role(&con, atoi(argv[i]), roar_str2role(argv[i+1])) == -1 ) { fprintf(stderr, "Error: can not set stream role\n"); } else { printf("stream role set\n"); } i++; } else if ( !strcmp(k, "metaset") ) { ROAR_CKHAVEARGS(4); i++; if ( set_meta(&con, atoi(argv[i]), argv[i+1], argv[i+2], argv[i+3]) == -1 ) { fprintf(stderr, "Error: can not set meta data\n"); } else { printf("meta data changed\n"); } i += 3; } else if ( !strcmp(k, "metaget") ) { ROAR_CKHAVEARGS(2); i++; if ( show_meta_type(&con, atoi(argv[i]), argv[i+1]) == -1 ) { fprintf(stderr, "Error: can not get meta data\n"); } i++; } else if ( !strcmp(k, "metasave") ) { ROAR_CKHAVEARGS(2); i++; if ( save_meta(&con, atoi(argv[i]), argv[i+1]) == -1 ) { fprintf(stderr, "Error: can not get meta data\n"); } else { printf("meta data saved\n"); } i++; } else if ( !strcmp(k, "metaload") ) { ROAR_CKHAVEARGS(2); i++; if ( load_meta(&con, atoi(argv[i]), argv[i+1]) == -1 ) { fprintf(stderr, "Error: can not set meta data\n"); } else { printf("meta data saved\n"); } i++; } else if ( !strcmp(k, "listaiprofiles") || !strcmp(k, "listprofiles") ) { if ( list_aiprofiles() == -1 ) { fprintf(stderr, "Error: can not list profiles\n"); } } else if ( !strcmp(k, "aiprofileget") || !strcmp(k, "profileget") ) { ROAR_CKHAVEARGS(1); i++; if ( show_aiprofile(argv[i]) == -1 ) { fprintf(stderr, "Error: can not get profile data\n"); } } else { fprintf(stderr, "Error: invalid command: %s\n", k); } } roar_disconnect(&con); return 0; } //ll roaraudio-1.0beta11/roarclients/roardtmf.c0000644000175000017500000001013112264733645016776 0ustar phiphi//roardtmf.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #ifdef ROAR_HAVE_LIBM #include // in ms: #if 0 #define ON_TIME (180) #define OFF_TIME ( 80) #else #define ON_TIME (180) #define OFF_TIME ( 80) #endif #define SUM_TIME (ON_TIME+OFF_TIME) void usage (void) { printf("roardtmf [OPTIONS]... PHONE NUMBER\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --help - Show this help\n" " --mode-dtmf - Use standard DTMF (default)\n" " --mode-roar - Use RoarAudio extended DTMF\n" ); } int main (int argc, char * argv[]) { enum { MODE_DTMF, MODE_ROAR } mode = MODE_DTMF; int rate = ROAR_RATE_DEFAULT; const char * server = NULL; const char * k; int i; const char * name = "roardtmf"; roar_vs_t * vss = NULL; const char * tones = NULL; void * buf; size_t len_break; size_t len_tone; size_t samples; size_t len; uint16_t c; int err; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "--server") || !strcmp(k, "-s") ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( !strcmp(k, "--rate") || !strcmp(k, "-r") || !strcmp(k, "-R") ) { ROAR_CKHAVEARGS(1); rate = roar_str2rate(argv[++i]); } else if ( !strcmp(k, "--mode-dtmf") ) { mode = MODE_DTMF; } else if ( !strcmp(k, "--mode-roar") ) { mode = MODE_ROAR; } else if ( !strcmp(k, "--help") ) { usage(); return 0; } else if ( tones == NULL ) { tones = argv[i++]; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( tones == NULL ) { return 1; } len_break = roar_dtmf_mus2samples(OFF_TIME * 1000, rate); len_tone = roar_dtmf_mus2samples(ON_TIME * 1000, rate); samples = len_break + len_tone; /* printf("samples=%llu\n", (long long unsigned int)samples); return 0; */ if ( (buf = roar_mm_malloc((len = 16*samples/8))) == NULL ) return 4; if ( (vss = roar_vs_new_playback(server, name, rate, 1, ROAR_CODEC_DEFAULT, 16, &err)) == NULL ) { fprintf(stderr, "Error: can not start playback: %s\n", roar_vs_strerr(err)); roar_mm_free(buf); return 1; } while ( (c = *tones) != 0 ) { tones++; if ( mode == MODE_DTMF ) { if ( c == '+' || c == '.' || c == '_' ) continue; } else if ( mode == MODE_ROAR ) { c = ROAR_DTMF_CHAR_ROAR(c); } if ( mode == MODE_DTMF && c == ' ' ) { roar_dtmf_break(buf, len_tone, rate, ROAR_DTMF_OPTIONS_NONE); } else { if ( roar_dtmf_tone(buf, len_tone, rate, ROAR_DTMF_OPTIONS_NONE, c) == -1 ) { roar_mm_free(buf); return 5; } } roar_dtmf_tone(buf+len_tone*sizeof(int16_t), len_break, rate, ROAR_DTMF_OPTIONS_NONE, mode == MODE_DTMF ? ROAR_DTMF_CHAR_BREAK : ROAR_DTMF_CHAR_NOOP); if ( roar_vs_write(vss, buf, len, &err) != (ssize_t)len ) { fprintf(stderr, "Error: can not write data: %s\n", roar_vs_strerr(err)); roar_mm_free(buf); return 5; } } roar_vs_sync(vss, ROAR_VS_WAIT, NULL); roar_vs_close(vss, ROAR_VS_FALSE, 0); roar_mm_free(buf); return 0; } #else int main (void) { fprintf(stderr, "Error: No Math library support compiled in.\n"); return 1; } #endif //ll roaraudio-1.0beta11/roarclients/roarfilt.c0000644000175000017500000001674312264733646017022 0ustar phiphi//roarfilt.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #ifdef ROAR_HAVE_LIBM #include #endif #define BUFFERSIZE 1024 void usage (void) { printf("roarfilt [OPTIONS]...\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --aiprofile PROFILE - Set audio profile\n" " --help - Show this help\n" "\n" " --half - half the volume\n" " --double - double the volume\n" " --amp VAL - Set amplification\n" " --mul VAL - Set mul\n" " --div VAL - Set div\n" " --filter name - add filter name\n" " --ffreq freq - set filter freq\n" " --fmul mult - set filter multiplier\n" " --fdiv div - set filter divider\n" " --fn N - set filter N parameter\n" " --flimit limit - set filter limit parameter\n" " --fmode mode - set filter mode parameter\n" " --fq Q - set filter quality\n" ); } #define _volX(bits,twobits,sf) \ void vol##bits (void * data, int32_t mul, int32_t div, size_t len) { \ int##bits##_t * samples = (int##bits##_t *) data; \ size_t i; \ \ len /= sf; \ \ for (i = 0; i < len; i++) \ samples[i] = ((int##twobits##_t) samples[i] * mul) / div; \ } _volX( 8,16,1) _volX(16,32,2) _volX(32,64,4) int main (int argc, char * argv[]) { struct roar_audio_info info; const char * server = NULL; const char * k; int i; int32_t mul = 1, div = 1; int filter_id; int32_t tmp; float tmpfp; char buf[BUFFERSIZE]; struct roardsp_filterchain fc; struct roardsp_filter filter_real[8]; struct roardsp_filter * filter = filter_real - 1; struct roar_stream stream; struct roar_vio_calls svio; _LIBROAR_IGNORE_RET(roar_profile2info(&info, "default-server")); info.codec = ROAR_CODEC_DEFAULT; roardsp_fchain_init(&fc); for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 || strcmp(k, "-s") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 || strcmp(k, "-r") == 0 ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( strcmp(k, "-b") == 0 ) { info.bits = 8; } else if ( strcmp(k, "-m") == 0 ) { info.channels = 1; } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } info.codec = ROAR_CODEC_DEFAULT; } else if ( strcmp(k, "--half") == 0 || strcmp(k, "-half") == 0 ) { div *= 2; } else if ( strcmp(k, "--double") == 0 || strcmp(k, "-double") == 0 ) { mul *= 2; } else if ( strcmp(k, "--amp") == 0 ) { ROAR_CKHAVEARGS(1); mul *= atoi(argv[++i]); } else if ( strcmp(k, "--mul") == 0 ) { ROAR_CKHAVEARGS(1); mul = atoi(argv[++i]); } else if ( strcmp(k, "--div") == 0 ) { ROAR_CKHAVEARGS(1); div = atoi(argv[++i]); } else if ( strcmp(k, "--filter") == 0 ) { ROAR_CKHAVEARGS(1); stream.info = info; filter_id = roardsp_filter_str2id(argv[++i]); if ( filter_id == -1 ) { ROAR_WARN("Can not add filter as filter ID is unknown: %s: %s", argv[i], roar_error2str(roar_error)); } else { filter++; if ( roardsp_filter_init(filter, &stream, filter_id) == -1 ) { ROAR_WARN("Can not add filter: %s: %s", argv[i], roar_error2str(roar_error)); filter--; } else { roardsp_fchain_add(&fc, filter); } } } else if ( strcmp(k, "--ffreq") == 0 ) { ROAR_CKHAVEARGS(1); tmpfp = atof(argv[++i]); roardsp_filter_ctl(filter, ROARDSP_FCTL_FREQ, &tmpfp); } else if ( strcmp(k, "--fmul") == 0 ) { ROAR_CKHAVEARGS(1); tmp = atoi(argv[++i]); roardsp_filter_ctl(filter, ROARDSP_FCTL_MUL, &tmp); } else if ( strcmp(k, "--fdiv") == 0 ) { ROAR_CKHAVEARGS(1); tmp = atoi(argv[++i]); roardsp_filter_ctl(filter, ROARDSP_FCTL_DIV, &tmp); } else if ( strcmp(k, "--fn") == 0 ) { ROAR_CKHAVEARGS(1); tmp = atoi(argv[++i]); roardsp_filter_ctl(filter, ROARDSP_FCTL_N, &tmp); } else if ( strcmp(k, "--fq") == 0 ) { ROAR_CKHAVEARGS(1); tmp = atoi(argv[++i]); roardsp_filter_ctl(filter, ROARDSP_FCTL_Q, &tmp); } else if ( strcmp(k, "--flimit") == 0 ) { ROAR_CKHAVEARGS(1); tmp = atoi(argv[++i]); roardsp_filter_ctl(filter, ROARDSP_FCTL_LIMIT, &tmp); } else if ( strcmp(k, "--fmode") == 0 ) { ROAR_CKHAVEARGS(1); tmp = atoi(argv[++i]); roardsp_filter_ctl(filter, ROARDSP_FCTL_MODE, &tmp); } else if ( strcmp(k, "--help") == 0 || strcmp(k, "-h") == 0 ) { usage(); return 0; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( roar_vio_simple_stream(&svio, info.rate, info.channels, info.bits, info.codec, server, ROAR_DIR_FILTER, "roarfilt", -1) == -1 ) { fprintf(stderr, "Error: can not start playback\n"); return 1; } if ( mul == div && roardsp_fchain_num(&fc) == 0 ) { fprintf(stderr, "Error: filter is useless!\n"); return 0; } switch (info.bits) { case 8: while((i = roar_vio_read(&svio, buf, sizeof(buf)))) { vol8((void*)buf, mul, div, i); roardsp_fchain_calc(&fc, (void*)buf, (8*i)/info.bits); if (roar_vio_write(&svio, buf, i) != i) break; } break; case 16: while((i = roar_vio_read(&svio, buf, sizeof(buf)))) { if ( mul != div ) vol16((void*)buf, mul, div, i); roardsp_fchain_calc(&fc, (void*)buf, (8*i)/info.bits); if (roar_vio_write(&svio, buf, i) != i) break; } break; case 32: while((i = roar_vio_read(&svio, buf, sizeof(buf)))) { vol32((void*)buf, mul, div, i); roardsp_fchain_calc(&fc, (void*)buf, (8*i)/info.bits); if (roar_vio_write(&svio, buf, i) != i) break; } break; default: fprintf(stderr, "Error: %i bits per sample is not supported!\n", (int)info.bits); return 1; } roar_vio_close(&svio); roardsp_fchain_uninit(&fc); return 0; } //ll roaraudio-1.0beta11/roarclients/roarify.sht0000644000175000017500000000411111450446043017175 0ustar phiphi#!/bin/sh usage() { echo "Usage: $0 program ..." echo "or:" echo "Usage: $0 [OPTIONS] -- program ..." echo "or:" echo "Usage: $0 --help" echo echo "Options:" echo " --help - This help" echo " --print-env-bash - Print needed ENVs in bash mode" echo " --server SERVER - Sets server to SERVER" echo " --load MODULE - Force loading of MODULE" echo " --no-load-roar - Do not preload libroar" echo " --no-load-oss - Do not preload libroaross (OSS Emulation)" } CMD=false print_env=false print_mode=none preload_libroar='%%%PREFIX_LIB%%%/libroar.so.%%%VERSION%%% ' preload_libroaross='%%%PREFIX_LIB%%%/libroaross.so.%%%VERSION%%% ' while [ "$1" != '' ] do k="$1" shift; case "$k" in '--') CMD="$1" shift; break; ;; '--server') export ROAR_SERVER="$1" shift; ;; '--load') LD_PRELOAD="%%%PREFIX_COMP_LIBS%%%/lib$1.so $LD_PRELOAD" shift; ;; '--no-load-roar') preload_libroar='' ;; '--no-load-oss') preload_libroaross='' ;; '--help'|'-h') usage; exit 0; ;; '--print-env-bash') print_env=true print_mode=bash ;; '-'*) echo "$0: Error: Unknown option: $k" >&2 usage >&2; exit 1 ;; *) CMD="$k" break; ;; esac done # spaces are included in $preload_* LD_PRELOAD="$preload_libroar$preload_libroaross$LD_PRELOAD" if [ "$LD_PRELOAD" = '' ] then unset LD_PRELOAD else export LD_PRELOAD fi if [ "$LD_LIBRARY_PATH" = '' ] then export LD_LIBRARY_PATH='%%%PREFIX_COMP_LIBS%%%' else export LD_LIBRARY_PATH='%%%PREFIX_COMP_LIBS%%%'":$LD_LIBRARY_PATH" fi export PATH='%%%PREFIX_COMP_BINS%%%'":$PATH" if $print_env then case "$print_mode" in 'bash') [ "$ROAR_SERVER" != '' ] && echo "ROAR_SERVER='$ROAR_SERVER'; export ROAR_SERVER;" [ "$LD_PRELOAD" != '' ] && echo "LD_PRELOAD='$LD_PRELOAD'; export LD_PRELOAD;" echo "LD_LIBRARY_PATH='$LD_LIBRARY_PATH'; export LD_LIBRARY_PATH;" echo "PATH='$PATH'; export PATH;" ;; *) echo "Error: unknown print env mode: $print_mode" >&2 exit 1; ;; esac exit 0; fi exec $(exec -- echo -- 2>/dev/null) "$CMD" "$@" #ll roaraudio-1.0beta11/roarclients/roarinterconnect.c0000644000175000017500000003620112264733647020547 0ustar phiphi//roarinterconnect.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * ckport: ignore-symbol: roar_cdriver_oss of target libroareio0 -- For OSS streams */ // configure ROAR_INFO() int g_verbose = 0; #define ROAR_DBG_INFOVAR g_verbose #include #include #ifdef ROAR_HAVE_ESD #include #endif #ifdef ROAR_HAVE_LIBRSOUND #include #ifdef RSD_EXEC #define _HAVE_RSOUND #endif #endif #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) #define _HAVE_OSS #endif #define CLIENT_NAME "roarinterconnect" #define MT_NONE 0x00 #define MT_MASK 0xF0 #define MT_ROAR 0x10 #define MT_ESD 0x20 #define MT_SIMPLE 0x30 #define MT_OSS 0x40 #define MT_RSOUND 0x50 #define MT_DEFAULT MT_ROAR #define ST_NONE 0x00 #define ST_MASK 0x0F #define ST_BIDIR 0x01 #define ST_FILTER 0x02 #define ST_TRANSMIT 0x03 #define ST_RECEIVE 0x04 #define ST_RECPLAY 0x05 #define ST_RECORD 0x06 // no default here as the default depend on the server type void usage (void) { printf("roarinterconnect [OPTIONS]...\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --remote SERVER - Set remote server\n" " --type TYPE - Set type of remote server\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --help - Show this help\n" " --verbose -v - Be verbose\n" ); printf("\nPossible Types:\n\n"); printf(" roar - RoarAudio Server\n" #ifdef ROAR_HAVE_ESD " esd - EsounD Server\n" #endif " simple - PulseAudio using simple protocol\n" #ifdef _HAVE_OSS " oss - Open Sound System (OSS) device\n" #endif #ifdef _HAVE_RSOUND " rsound - RSound server\n" #endif "\n" " bidir - Connect bidirectional\n" " filter - Use local server as filter for remote server\n" " transmit - Transmit data from local server to remote server\n" " receive - Receive data from remote server\n" " recplay - Record from and play data to remote server\n" " record - Record data from remote server\n" ); } int parse_type (char * type) { int ret = MT_NONE|ST_NONE; char * colon; if ( type != NULL ) { while (type != NULL && *type) { if ( (colon = strstr(type, ":")) != NULL ) { *colon = 0; colon++; } if ( !strcmp(type, "roar") ) { ret -= ret & MT_MASK; ret += MT_ROAR; } else if ( !strcmp(type, "esd") ) { ret -= ret & MT_MASK; ret += MT_ESD; } else if ( !strcmp(type, "simple") ) { ret -= ret & MT_MASK; ret += MT_SIMPLE; } else if ( !strcmp(type, "oss") ) { ret -= ret & MT_MASK; ret += MT_OSS; } else if ( !strcmp(type, "rsound") ) { ret -= ret & MT_MASK; ret += MT_RSOUND; } else if ( !strcmp(type, "bidir") ) { ret -= ret & ST_MASK; ret += ST_BIDIR; } else if ( !strcmp(type, "filter") ) { ret -= ret & ST_MASK; ret += ST_FILTER; } else if ( !strcmp(type, "transmit") ) { ret -= ret & ST_MASK; ret += ST_TRANSMIT; } else if ( !strcmp(type, "receive") ) { ret -= ret & ST_MASK; ret += ST_RECEIVE; } else if ( !strcmp(type, "recplay") ) { ret -= ret & ST_MASK; ret += ST_RECPLAY; } else if ( !strcmp(type, "record") ) { ret -= ret & ST_MASK; ret += ST_RECORD; } else { return MT_NONE|ST_NONE; } type = colon; } } if ( (ret & MT_MASK) == MT_NONE ) ret |= MT_DEFAULT; if ( (ret & ST_MASK) == ST_NONE ) { switch (ret & MT_MASK) { case MT_ROAR: ret |= ST_BIDIR; break; case MT_ESD: ret |= ST_FILTER; break; case MT_SIMPLE: ret |= ST_TRANSMIT; break; // we use ST_TRANSMIT because ST_BIDIR is // very unlike to be configured at the server side. case MT_OSS: ret |= ST_BIDIR; break; case MT_RSOUND: ret |= ST_TRANSMIT; break; // RSound does only handle playback streams. default: return MT_NONE|ST_NONE; // error case break; } } return ret; } #ifdef _HAVE_RSOUND // RSound format helper function: enum rsd_format para2rsdfmt (uint32_t bits, uint32_t codec) { switch (codec) { case ROAR_CODEC_PCM_S_LE: switch (bits) { #ifdef RSD_S8 case 8: return RSD_S8; break; #endif #ifdef RSD_S16_LE case 16: return RSD_S16_LE; break; #endif #ifdef RSD_S32_LE case 32: return RSD_S32_LE; break; #endif } break; case ROAR_CODEC_PCM_S_BE: switch (bits) { #ifdef RSD_S8 case 8: return RSD_S8; break; #endif #ifdef RSD_S16_BE case 16: return RSD_S16_BE; break; #endif #ifdef RSD_S32_BE case 32: return RSD_S32_BE; break; #endif } break; case ROAR_CODEC_PCM_U_LE: switch (bits) { #ifdef RSD_U8 case 8: return RSD_U8; break; #endif #ifdef RSD_U16_LE case 16: return RSD_U16_LE; break; #endif #ifdef RSD_U32_LE case 32: return RSD_U32_LE; break; #endif } break; case ROAR_CODEC_PCM_U_BE: switch (bits) { #ifdef RSD_U8 case 8: return RSD_U8; break; #endif #ifdef RSD_U16_BE case 16: return RSD_U16_BE; break; #endif #ifdef RSD_U32_BE case 32: return RSD_U32_BE; break; #endif } break; #ifdef RSD_ALAW case ROAR_CODEC_ALAW: return RSD_ALAW; break; #endif #ifdef RSD_MULAW case ROAR_CODEC_MULAW: return RSD_MULAW; break; #endif } return 0; } #endif int main (int argc, char * argv[]) { struct roar_connection con[1]; struct roar_stream stream[1]; struct roar_vio_calls vio; struct roar_audio_info info; #ifdef _HAVE_RSOUND rsound_t *rd; enum rsd_format fmt = 0; #endif int type = parse_type(NULL); int tmp; const char * server = NULL; char * remote = "+slp"; // we hope SLP located server is not local one char * k; int rfh; int i; int localdir = ROAR_DIR_BIDIR; int rport; if ( roar_profile2info(&info, "default") == -1 ) return 1; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--remote") == 0 ) { ROAR_CKHAVEARGS(1); remote = argv[++i]; } else if ( strcmp(k, "--type") == 0 ) { ROAR_CKHAVEARGS(1); type = parse_type(argv[++i]); } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) { ROAR_CKHAVEARGS(1); info.codec = roar_str2codec(argv[++i]); } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( strcmp(k, "--verbose") == 0 || strcmp(k, "-v") == 0 ) { g_verbose++; } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( server != NULL && !strcmp(server, "+invalid") ) { return 0; } switch (type & MT_MASK) { case MT_ROAR: switch (type & ST_MASK) { case ST_BIDIR: tmp = ROAR_DIR_BIDIR; break; case ST_FILTER: tmp = ROAR_DIR_FILTER; break; case ST_TRANSMIT: tmp = ROAR_DIR_PLAY; localdir = ROAR_DIR_MONITOR; break; case ST_RECEIVE: tmp = ROAR_DIR_MONITOR; localdir = ROAR_DIR_PLAY; break; case ST_RECPLAY: tmp = ROAR_DIR_RECPLAY; break; case ST_RECORD: tmp = ROAR_DIR_RECORD; localdir = ROAR_DIR_PLAY; break; default: fprintf(stderr, "Error: unknown stream type\n"); return 2; } if ( roar_vio_simple_stream(&vio, info.rate, info.channels, info.bits, info.codec, remote, tmp, CLIENT_NAME, -1) == -1 ) { fprintf(stderr, "Error: can not open RoarAudio stream to %s: %s\n", remote, roar_error2str(roar_error)); return 2; } if ( roar_vio_ctl(&vio, ROAR_VIO_CTL_GET_FH, &rfh) == -1 ) { fprintf(stderr, "Error: can not get filehandle for RoarAudio stream: %s\n", roar_error2str(roar_error)); roar_vio_close(&vio); return 2; } break; #ifdef _HAVE_OSS case MT_OSS: switch (type & ST_MASK) { case ST_BIDIR: tmp = ROAR_DIR_BIDIR; break; case ST_TRANSMIT: tmp = ROAR_DIR_PLAY; localdir = ROAR_DIR_MONITOR; break; case ST_RECEIVE: tmp = ROAR_DIR_MONITOR; localdir = ROAR_DIR_PLAY; break; case ST_RECPLAY: tmp = ROAR_DIR_RECPLAY; break; case ST_RECORD: tmp = ROAR_DIR_RECORD; localdir = ROAR_DIR_PLAY; break; default: fprintf(stderr, "Error: unknown stream type\n"); return 2; } if ( roar_cdriver_oss(&vio, "OSS", remote, &info, tmp) == -1 ) { fprintf(stderr, "Error: can not open OSS device %s: %s\n", remote, roar_error2str(roar_error)); return 2; } if ( roar_vio_ctl(&vio, ROAR_VIO_CTL_GET_FH, &rfh) == -1 ) { fprintf(stderr, "Error: can not get filehandle for OSS device %s: %s\n", remote, roar_error2str(roar_error)); roar_vio_close(&vio); return 2; } break; #endif #ifdef ROAR_HAVE_ESD case MT_ESD: tmp = ESD_STREAM|ESD_PLAY; switch (info.bits) { case 8: tmp |= ESD_BITS8; break; case 16: tmp |= ESD_BITS16; break; default: fprintf(stderr, "Error: EsounD only supports 8 and 16 bit streams\n"); return 2; } switch (info.channels) { case 1: tmp |= ESD_MONO; break; case 2: tmp |= ESD_STEREO; break; default: fprintf(stderr, "Error: EsounD only supports mono and stereo streams\n"); return 2; } // TODO: FIXME: this is only true if the esd runs on a LE system,... if ( info.bits == 8 && info.codec != ROAR_CODEC_PCM_U_LE ) { fprintf(stderr, "Error: EsounD only supports unsigned PCM in 8 bit mode\n"); return 2; } else if ( info.bits == 16 && info.codec != ROAR_CODEC_DEFAULT ) { fprintf(stderr, "Error: EsounD only supports signed PCM in 16 bit mode\n"); return 2; } switch (type & ST_MASK) { case ST_FILTER: rfh = esd_filter_stream(tmp, info.rate, remote, CLIENT_NAME); break; case ST_TRANSMIT: rfh = esd_play_stream(tmp, info.rate, remote, CLIENT_NAME); localdir = ROAR_DIR_MONITOR; break; case ST_RECEIVE: rfh = esd_monitor_stream(tmp, info.rate, remote, CLIENT_NAME); localdir = ROAR_DIR_PLAY; break; default: fprintf(stderr, "Error: this type is not supported by EsounD\n"); return 2; break; } break; #endif #ifdef _HAVE_RSOUND case MT_RSOUND: fmt = para2rsdfmt(info.bits, info.codec); if ( fmt == 0 ) { fprintf(stderr, "Error: Bits/Codec not supported by RSound\n"); return 2; } switch (type & ST_MASK) { case ST_TRANSMIT: localdir = ROAR_DIR_MONITOR; rsd_init(&rd); rsd_set_param(rd, RSD_HOST, remote); tmp = info.channels; rsd_set_param(rd, RSD_CHANNELS, &tmp); tmp = info.rate; rsd_set_param(rd, RSD_SAMPLERATE, &tmp); rsd_set_param(rd, RSD_FORMAT, &fmt); #ifdef RSD_IDENTITY rsd_set_param(rd, RSD_IDENTITY, CLIENT_NAME); #endif rfh = rsd_exec(rd); if ( rfh == -1 ) { rsd_stop(rd); rsd_free(rd); } break; default: fprintf(stderr, "Error: this type is not supported by RSound\n"); return 2; break; } break; #endif case MT_SIMPLE: switch (type & ST_MASK) { case ST_BIDIR: tmp = -1; localdir = ROAR_DIR_BIDIR; break; case ST_TRANSMIT: tmp = SHUT_RD; localdir = ROAR_DIR_MONITOR; break; case ST_RECEIVE: tmp = SHUT_WR; localdir = ROAR_DIR_PLAY; break; default: fprintf(stderr, "Error: this type is not supported by PulseAudio\n"); return 2; } // we guess INET here... if ( strstr(remote, "/") == NULL && (k = strstr(remote, ":")) != NULL ) { *k = 0; k++; rport = atoi(k); } else { rport = ROAR_DEFAULT_PA_PORT; } if ( roar_vio_open_socket(&vio, remote, rport) == -1 ) { fprintf(stderr, "Error: can not open socket for Simple stream: %s\n", roar_error2str(roar_error)); return 2; } roar_vio_shutdown(&vio, tmp); if ( roar_vio_ctl(&vio, ROAR_VIO_CTL_GET_FH, &rfh) == -1 ) { fprintf(stderr, "Error: can not get filehandle for Simple stream: %s\n", roar_error2str(roar_error)); roar_vio_close(&vio); return 2; } break; default: fprintf(stderr, "Error: unknown/not supported server type\n"); return 2; } if ( rfh == -1 ) { fprintf(stderr, "Error: can not connect to remote server\n"); return 10; } if ( roar_simple_connect(con, server, CLIENT_NAME) == -1 ) { fprintf(stderr, "Can not connect to local server\n"); return 20; } if ( roar_stream_new_by_info(stream, &info) == -1 ) { roar_disconnect(con); return 21; } if ( roar_stream_connect(con, stream, localdir, -1) == -1 ) { roar_disconnect(con); return 22; } if ( roar_stream_passfh(con, stream, rfh) == -1 ) { roar_disconnect(con); return 23; } switch (type & MT_MASK) { case MT_ESD: close(rfh); break; case MT_RSOUND: roar_vio_open_fh_socket(&vio, rfh); case MT_ROAR: case MT_OSS: case MT_SIMPLE: roar_vio_close(&vio); break; default: close(rfh); } if ( roar_stream_attach_simple(con, stream, 0) == -1 ) { fprintf(stderr, "Can not attach remote stream to local server\n"); } roar_disconnect(con); ROAR_INFO("Stream ID: %i", 1, stream->id); return 0; } //ll roaraudio-1.0beta11/roarclients/roarlight.c0000644000175000017500000001465612264733647017175 0ustar phiphi//roarlight.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include #define CONVAR struct roar_connection * con static struct roar_connection * g_connection; static struct roar_vio_calls * g_stream; static int __run_argv(int argc, char * argv[]); static int __open_and_run_file(const char * file); void usage (void) { printf("roarlight [OPTIONS]... command [command...]\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --mixer MIXERID - ID of the light mixer to use\n" " --help - Show this help\n" ); printf("\nCommands:\n\n"); printf( " help - Show this help\n" " sleep TIME - Sleeps for TIME seconds\n" " sset chan=val - Set a DMX Channel\n" " set chan=val - Same as sset\n" " event EVENT - Send event EVENT\n" " @FILE - Read commands from FILE or stdin in case of @-\n" ); } static int cmd_sset (char * arg) { char * next = arg; char * k, * v; int32_t chan, val; struct roar_roardmx_message mes; roar_roardmx_message_new_sset(&mes); while (next != NULL) { arg = next; next = strstr(next, ","); if ( next != NULL ) { *next = 0; next++; } k = arg; v = strstr(arg, "="); if ( v == NULL ) return -1; *v = 0; v++; chan = atoi(k); val = atoi(v); // printf("k='%s'(%i), v='%s'(%i)\n", k, chan, v, val); if ( roar_roardmx_message_add_chanval(&mes, chan, val) == -1 ) return -1; } if ( roar_roardmx_message_send(&mes, g_stream) == -1 ) { return -1; } return 0; } static int cmd_event (char * arg) { struct roar_roardmx_message mes; int event; char * p; if ( roar_roardmx_message_new_event(&mes) == -1 ) return -1; while (arg != NULL) { p = strstr(arg, ","); if ( p != NULL ) { *p = 0; p++; } event = roar_roardmx_str2event(arg); if ( event == -1 ) return -1; roar_roardmx_message_add_event(&mes, event); arg = p; } if ( roar_roardmx_message_send(&mes, g_stream) == -1 ) return -1; return 0; } static int __run_argv(int argc, char * argv[]) { char * k; int i; for (i = 0; i < argc; i++) { k = argv[i]; // cmd is in k printf("--- [ %s ] ---\n", k); if ( !strcmp(k, "help") ) { usage(); } else if ( !strcmp(k, "sleep") ) { ROAR_CKHAVEARGS(1); roar_sleep(atoi(argv[++i])); } else if ( !strcmp(k, "sset") || !strcmp(k, "set") ) { ROAR_CKHAVEARGS(1); i++; if ( cmd_sset(argv[i]) == -1 ) { fprintf(stderr, "Error: can not set channels\n"); } else { printf("channels changed\n"); } } else if ( !strcmp(k, "event") ) { ROAR_CKHAVEARGS(1); i++; if ( cmd_event(argv[i]) == -1 ) { fprintf(stderr, "Error: can not send event\n"); } else { printf("event send\n"); } } else if ( *k == '@' ) { __open_and_run_file(k); } else { fprintf(stderr, "Error: invalid command: %s\n", k); return 1; } } return 0; } static inline void __strip_space(char ** str) { for (; **str == ' '; (*str)++); } static int __parse_line_and_run(char * line) { #define MAX_ARGS 16 int argc = 0; char * argv[MAX_ARGS]; char * p; while (line != NULL) { if ( argc == MAX_ARGS ) { fprintf(stderr, "Error: too many arguments.\n"); return 1; } p = strstr(line, " "); if ( p != NULL ) { *p = 0; p++; __strip_space(&p); } argv[argc++] = line; line = p; } return __run_argv(argc, argv); } static int __run_file(FILE * file) { char buffer[1024]; ssize_t len; int ret; while (fgets(buffer, sizeof(buffer), file) != NULL) { len = roar_mm_strlen(buffer); if ( len > 0 && buffer[len-1] == '\n' ) buffer[len-1] = 0; if ( !len || buffer[0] == 0 ) continue; ret = __parse_line_and_run(buffer); if ( ret != 0 ) return ret; } return 0; } static int __open_and_run_file(const char * file) { FILE * input; int ret; if ( !strcmp(file, "@-") ) { return __run_file(stdin); } else { input = fopen(file+1, "r"); if ( input == NULL ) { fprintf(stderr, "Error: can not open input file: %s\n", file+1); return 1; } ret = __run_file(input); fclose(input); return ret; } } int main (int argc, char * argv[]) { struct roar_connection con; struct roar_vio_calls vio; int mixer = -1; // -1 = Default const char * server = NULL; const char * k; int i; int ret; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "--server") || !strcmp(k, "-s") ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( !strcmp(k, "--mixer") ) { ROAR_CKHAVEARGS(1); mixer = atoi(argv[++i]); } else if ( !strcmp(k, "--help") || !strcmp(k, "-h") ) { usage(); return 0; } else if ( *k == '-' ) { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } else { break; } } if ( i == argc ) { fprintf(stderr, "Error: No Commands given\n"); return 0; // this is not a fatal error... } if ( roar_simple_connect(&con, server, "roarlight") == -1 ) { fprintf(stderr, "Error: Can not connect to server\n"); return 1; } if ( roar_vio_simple_new_stream_obj(&vio, &con, NULL, ROAR_RATE_DEFAULT, ROAR_CHANNELS_DEFAULT, ROAR_BITS_DEFAULT, ROAR_CODEC_ROARDMX, ROAR_DIR_LIGHT_IN, mixer) == -1 ) { } g_connection = &con; g_stream = &vio; ret = __run_argv(argc - i, argv + i); // try to flush all data: roar_vio_sync(&vio); roar_vio_close(&vio); roar_usleep(100); roar_disconnect(&con); return ret; } //ll roaraudio-1.0beta11/roarclients/roarmon.c0000644000175000017500000002137712264733650016647 0ustar phiphi//roarmon.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUFSIZE 1024 void usage (void) { printf("roarmon [OPTIONS]... [FILE]\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --record - Run in record mode (Wave Audio only)\n" " --wave - Output Wave Audio (PCM)\n" " --midi - Output MIDI Audio\n" " --light - Output light control\n" " --raw - Output raw data\n" " --complex - Output complex data\n" " --rdtcs - Output Radio Data and Transmitter Control System data\n" " --thru - Output copy of other stream\n" " --prethru - Sets prethru flag on stream\n" " --rel-id ID - Set ID of relative stream\n" " --help - Show this help\n" ); } int main (int argc, char * argv[]) { struct roar_audio_info info = { .rate = ROAR_AUDIO_INFO_INVALID, .bits = ROAR_AUDIO_INFO_INVALID, .channels = ROAR_AUDIO_INFO_INVALID, .codec = ROAR_AUDIO_INFO_INVALID}; int dir = ROAR_DIR_MONITOR; int rel_id = -1; const char * server = NULL; const char * k; int i; int prethru = 0; struct roar_connection con; struct roar_stream s; struct roar_vio_calls file, * stream; struct roar_vio_defaults def; int file_opened = 0; if ( roar_vio_open_fh(&file, ROAR_STDOUT) == -1 ) return 1; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_CREAT|O_TRUNC|O_WRONLY, 0644) == -1 ) return 1; for (i = 1; i < argc; i++) { k = argv[i]; // esdmon [-s server ][-b] [-m] [-r freq] < file if ( !strcmp(k, "--server") || !strcmp(k, "-s") ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( !strcmp(k, "--rate") || !strcmp(k, "-r") || !strcmp(k, "-R") ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( !strcmp(k, "--bits") || !strcmp(k, "-B") ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( !strcmp(k, "-b") ) { info.bits = 8; } else if ( !strcmp(k, "--channels") || !strcmp(k, "--chans") || !strcmp(k, "-C") ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( !strcmp(k, "-m") ) { info.channels = 1; } else if ( !strcmp(k, "--codec") || !strcmp(k, "-E") ) { ROAR_CKHAVEARGS(1); if ( (info.codec = roar_str2codec(argv[++i])) == ROAR_AUDIO_INFO_INVALID ) { fprintf(stderr, "Error: Unknown codec: %s\n", argv[i]); return 1; } } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( !strcmp(k, "--wave") ) { dir = ROAR_DIR_MONITOR; } else if ( !strcmp(k, "--record") ) { dir = ROAR_DIR_RECORD; } else if ( !strcmp(k, "--midi") ) { dir = ROAR_DIR_MIDI_OUT; } else if ( !strcmp(k, "--light") ) { dir = ROAR_DIR_LIGHT_OUT; } else if ( !strcmp(k, "--raw") ) { dir = ROAR_DIR_RAW_OUT; } else if ( !strcmp(k, "--complex") ) { dir = ROAR_DIR_COMPLEX_OUT; } else if ( !strcmp(k, "--rdtcs") ) { dir = ROAR_DIR_RDTCS_OUT; } else if ( !strcmp(k, "--thru") ) { dir = ROAR_DIR_THRU; } else if ( !strcmp(k, "--rel-id") ) { ROAR_CKHAVEARGS(1); rel_id = atoi(argv[++i]); } else if ( !strcmp(k, "--prethru") ) { prethru = 1; } else if ( !strcmp(k, "--help") || !strcmp(k, "-h") ) { usage(); return 0; } else if ( !file_opened ) { file_opened = 1; if ( roar_vio_open_dstr(&file, k, &def, 1) == -1 ) { fprintf(stderr, "Error: can not open file: %s: %s\n", k, strerror(errno)); return 1; } } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } switch (dir) { case ROAR_DIR_MONITOR: case ROAR_DIR_RECORD: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = ROAR_RATE_DEFAULT; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_BITS_DEFAULT; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_CHANNELS_DEFAULT; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DEFAULT; break; case ROAR_DIR_MIDI_OUT: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = 0; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_MIDI_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_MIDI_CHANNELS_DEFAULT; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_MIDI; break; case ROAR_DIR_LIGHT_OUT: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = 0; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_LIGHT_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = 0; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DMX512; break; case ROAR_DIR_COMPLEX_OUT: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = ROAR_COMPLEX_RATE; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_COMPLEX_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_COMPLEX_CHANNELS; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_COMPLEX_CODEC; break; case ROAR_DIR_RDTCS_OUT: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = ROAR_RDTCS_RATE; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = ROAR_RDTCS_BITS; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = ROAR_RDTCS_CHANNELS; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_RDTCS_CODEC; break; case ROAR_DIR_RAW_OUT: case ROAR_DIR_THRU: default: if ( info.rate == ROAR_AUDIO_INFO_INVALID ) info.rate = 0; if ( info.bits == ROAR_AUDIO_INFO_INVALID ) info.bits = 0; if ( info.channels == ROAR_AUDIO_INFO_INVALID ) info.channels = 0; if ( info.codec == ROAR_AUDIO_INFO_INVALID ) info.codec = ROAR_CODEC_DEFAULT; break; } if ( roar_simple_connect(&con, server, "roarmon") == -1 ) { fprintf(stderr, "Error: can not connect to server\n"); return 10; } if ( roar_stream_new_by_info(&s, &info) == -1 ) { fprintf(stderr, "Error: can not create stream\n"); roar_disconnect(&con); return 20; } if ( rel_id != -1 ) { if ( roar_stream_set_rel_id(&s, rel_id) ) { fprintf(stderr, "Error: can not set id or realative stream\n"); roar_disconnect(&con); return 21; } } if ( roar_stream_connect(&con, &s, dir, -1) == -1 ) { fprintf(stderr, "Error: can not connect stream to server\n"); roar_disconnect(&con); return 11; } if ( prethru ) { if ( roar_stream_set_flags(&con, &s, ROAR_FLAG_PRETHRU, ROAR_SET_FLAG) == -1 ) { fprintf(stderr, "Error: can not set prethru flag on stream\n"); roar_disconnect(&con); return 14; } } if ( roar_stream_exec(&con, &s) == -1 ) { fprintf(stderr, "Error: can not exec stream\n"); roar_disconnect(&con); return 12; } if ( (stream = roar_get_connection_vio2(&con)) == NULL ) { fprintf(stderr, "Error: can not get stream vio\n"); roar_disconnect(&con); return 13; } // TODO: FIXME: // ROAR_SHUTDOWN(fh, SHUT_WR); // we need to have something do do shutdowns here... if ( roar_vio_copy_data(&file, stream) == -1 ) { fprintf(stderr, "Error: can not copy data from stream to destination\n"); roar_vio_close(stream); roar_vio_close(&file); return 14; } roar_vio_close(stream); roar_vio_close(&file); return 0; } //ll roaraudio-1.0beta11/roarclients/roarmonhttp.c0000644000175000017500000002342612264733650017544 0ustar phiphi//roarmonhttp.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * ckport: ignore-symbol: alarm of target win32 * checked by configure. Needed to clear timeout some small HTTPds implement * to avoid problems with bad CGI scripts. */ #include #if defined(ROAR_HAVE_SETENV) || defined(ROAR_HAVE_PUTENV) #define _CAN_SET_ENV #endif #define BUFSIZE 1024 void usage (void) { printf("roarmonhttp [OPTIONS]...\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --rel-id ID - Set ID of relative stream\n" " --inetd - Start in inetd mode (STDIN and STDOUT connected to socket)\n" " --help - Show this help\n" ); } void print_header (int codec, int rate, int channels) { const char * mime; mime = roar_codec2mime(codec); if ( mime == NULL ) mime = "application/octet-stream"; printf("Content-type: %s\r\n", mime); printf("ice-audio-info: ice-samplerate=%i;ice-channels=%i\r\n", rate, channels); printf("icy-pub:0\r\n"); printf("Server: RoarAudio (roarmonhttp $Revision: 1.42 $)\r\n"); printf("\r\n"); fflush(stdout); } int stream (struct roar_vio_calls * dest, struct roar_vio_calls * src) { struct roar_vio_select vios[2]; struct roar_buffer *ring = NULL, *cur; ssize_t len; size_t todo; int alive = 1; void * data; int ret; if ( roar_vio_nonblock(src, ROAR_SOCKET_NONBLOCK) == -1 ) { ROAR_WARN("stream(dest=%p, src=%p): Can not set source stream non-blocking: %s", dest, src, roar_error2str(roar_error)); } if ( roar_vio_nonblock(dest, ROAR_SOCKET_NONBLOCK) == -1 ) { ROAR_WARN("stream(dest=%p, src=%p): Can not set destination stream non-blocking: %s", dest, src, roar_error2str(roar_error)); } ROAR_VIO_SELECT_SETVIO(&(vios[0]), src, ROAR_VIO_SELECT_READ); ROAR_VIO_SELECT_SETVIO(&(vios[1]), dest, ROAR_VIO_SELECT_WRITE); while (alive) { ret = roar_vio_select(vios, ring != NULL ? 2 : 1, NULL, NULL); if ( ret == -1 ) { alive = 0; } else if ( ret == 0 ) { // nothing happend. } else { if ( vios[0].eventsa & ROAR_VIO_SELECT_READ ) { // we can read! if ( roar_buffer_new_data(&cur, BUFSIZE, &data) == -1 ) return -1; len = roar_vio_read(src, data, BUFSIZE); switch (len) { case 0: case -1: roar_buffer_free(cur); cur = NULL; if ( ring != NULL ) roar_buffer_free(ring); ring = NULL; return -1; break; } if ( cur != NULL ) { if ( roar_buffer_set_len(cur, len) == -1 ) return -1; if ( ring == NULL ) { ring = cur; } else { if ( roar_buffer_moveinto(ring, &cur) == -1 ) { ROAR_ERR("stream(dest=%p, src=%p): Can not append buffer to ring: %s", dest, src, roar_error2str(roar_error)); roar_buffer_free(ring); roar_buffer_free(cur); return -1; } } } } else if ( (vios[1].eventsa & ROAR_VIO_SELECT_WRITE) && ring != NULL ) { // we can write! if ( roar_buffer_get_data(ring, &data) == -1 ) return -1; if ( roar_buffer_get_len(ring, &todo) == -1 ) return -1; len = roar_vio_write(dest, data, todo); if ( len < 1 ) { if ( roar_error != ROAR_ERROR_AGAIN ) { roar_buffer_free(ring); return -1; } } if ( (ssize_t)todo == len ) { // we wrote all of the pkg if ( roar_buffer_next(&ring) == -1 ) return -1; } else { if ( roar_buffer_set_offset(ring, len) == -1 ) return -1; } } } } return 0; } #ifdef _CAN_SET_ENV int parse_http (int * gopher) { struct roar_keyval kv; char buf[1024]; char * qs = buf, *str; ssize_t len; int dir = ROAR_DIR_MONITOR; if ( (len = read(ROAR_STDIN, buf, 1023)) == -1 ) return -1; buf[len] = 0; if ( strncmp(buf, "GET /", 5) ) { if ( strncmp(buf, "SOURCE /", 8) ) { if ( buf[0] != '/' ) { return -1; } else { *gopher = 1; } } else { dir = ROAR_DIR_PLAY; qs += 3; } } if ( !*gopher ) { qs += 5; if ( (str = strstr(qs, " ")) == NULL ) return -1; *str = 0; } else { if ( (str = strstr(qs, "\r")) != NULL ) *str = 0; if ( (str = strstr(qs, "\n")) != NULL ) *str = 0; } for (; *qs != '?'; qs++) if ( !*qs ) break; if ( *qs == '?' ) qs++; if ( !*gopher ) printf("HTTP/1.0 200 OK\r\n"); // printf("QS: %s\r\n", qs); fflush(stdout); kv.key = "QUERY_STRING"; kv.value = qs; roar_env_set(&kv); return dir; } #endif int main (int argc, char * argv[]) { struct roar_audio_info info; int rel_id = -1; int sflags = ROAR_FLAG_NONE; // int codec = ROAR_CODEC_DEFAULT; const char * server = NULL; int i; const char * k, * v; const char * qs; char * qs_buf; char * c; char * sp0 = NULL, * sp1 = NULL; int dir = ROAR_DIR_MONITOR; int gopher = 0; struct roar_connection con; struct roar_stream s; struct roar_vio_calls * vio; #ifdef ROAR_HAVE_ALARM alarm(0); // reset alarm timers from httpd #endif if ( roar_profile2info(&info, "default") == -1 ) return 1; info.codec = ROAR_CODEC_OGG_VORBIS; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "--inetd") ) { #ifdef _CAN_SET_ENV if ( (dir = parse_http(&gopher)) == -1 ) return 1; #else return 1; #endif } else if ( !strcmp(k, "--server") ) { ROAR_CKHAVEARGS(1); roar_libroar_set_server(argv[++i]); } else if ( !strcmp(k, "--codec") || !strcmp(k, "-E") ) { ROAR_CKHAVEARGS(1); info.codec = roar_str2codec(argv[++i]); } else if ( !strcmp(k, "--rate") || !strcmp(k, "-r") || !strcmp(k, "-R") ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( !strcmp(k, "--bits") || !strcmp(k, "-B") ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( !strcmp(k, "--channels") || !strcmp(k, "--chans") || !strcmp(k, "-C") ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( !strcmp(k, "--rel-id") ) { ROAR_CKHAVEARGS(1); rel_id = atoi(argv[++i]); } else if ( !strcmp(k, "--help") && !strcmp(k, "-h") ) { usage(); return 0; } else { ROAR_ERR("Unknown parameter: %s", k); usage(); return 1; } } qs = roar_env_get("QUERY_STRING"); if ( qs == NULL ) qs = ""; c = qs_buf = roar_mm_strdup(qs); if ( c == NULL ) return 1; c = roar_mm_strtok_r(c, "&", &sp0); while (c != NULL) { k = roar_mm_strtok_r(c, "=", &sp1); v = roar_mm_strtok_r(NULL, "=", &sp1); if ( !strcmp(k, "codec") ) { if ( (info.codec = roar_str2codec(v)) == ROAR_AUDIO_INFO_INVALID ) return 1; } else if ( !strcmp(k, "channels") ) { info.channels = roar_str2channels(v); } else if ( !strcmp(k, "rate") ) { info.rate = roar_str2rate(v); } else if ( !strcmp(k, "bits") ) { info.bits = roar_str2bits(v); } else if ( !strcmp(k, "aiprofile") ) { if ( roar_profile2info(&info, v) == -1 ) return 1; } else if ( !strcmp(k, "rel-id") || !strcmp(k, "relid") ) { rel_id = atoi(v); } else if ( !strcmp(k, "set-flag") ) { if ( !strcmp(v, "meta") ) { sflags |= ROAR_FLAG_META; } else if ( !strcmp(v, "cleanmeta") ) { sflags |= ROAR_FLAG_CLEANMETA; } else if ( !strcmp(v, "prethru") ) { sflags |= ROAR_FLAG_PRETHRU; } else { return 1; } } else if ( !strcmp(k, "dir") ) { if ( (dir = roar_str2dir(v)) == -1 ) return 1; } else { return 1; } c = roar_mm_strtok_r(NULL, "&", &sp0); } roar_mm_free(qs_buf); if ( roar_simple_connect(&con, server, "roarmonhttp") == -1 ) { return 10; } if ( roar_stream_new_by_info(&s, &info) == -1 ) { roar_disconnect(&con); return 20; } if ( rel_id != -1 ) { if ( roar_stream_set_rel_id(&s, rel_id) ) { roar_disconnect(&con); return 21; } } if ( roar_stream_connect(&con, &s, dir, -1) == -1 ) { roar_disconnect(&con); return 11; } if ( sflags != ROAR_FLAG_NONE ) { if ( roar_stream_set_flags(&con, &s, sflags, ROAR_SET_FLAG) == -1 ) { roar_disconnect(&con); return 14; } } if ( roar_stream_exec(&con, &s) == -1 ) { roar_disconnect(&con); return 12; } if ( (vio = roar_get_connection_vio2(&con)) == NULL ) return 1; if ( !gopher ) print_header(info.codec, info.rate, info.channels); /* while((i = read(fh, buf, BUFSIZE))) if (write(out, buf, i) != i) break; */ switch (dir) { case ROAR_DIR_PLAY: stream(vio, roar_stdin); break; case ROAR_DIR_MONITOR: case ROAR_DIR_THRU: stream(roar_stdout, vio); break; } roar_vio_close(vio); return 0; } //ll roaraudio-1.0beta11/roarclients/roarphone.c0000644000175000017500000004422312264733650017162 0ustar phiphi//roarphone.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include #if defined(ROAR_HAVE_LIBSPEEX) && !defined(ROAR_HAVE_LIBSPEEXDSP) #define _SPEEX_API_OLD #elif defined(ROAR_HAVE_LIBSPEEX) && defined(ROAR_HAVE_LIBSPEEXDSP) #define _SPEEX_API_NEW #endif #ifdef _SPEEX_API_OLD #include #endif #define TIMEDIV 100 #define DRIVER "oss" // anti echo: #define AE_NONE 0 #define AE_SIMPLE 1 #define AE_SPEEX 2 #define AE_ROARD 3 #define DTX_F 25 #define CON_NONE 0x00 #define CON_CON 0x01 #define CON_STREAM 0x02 struct { int antiecho; int samples; int transcode; int64_t dtx_threshold; size_t jumbo_mtu; int ioflush_interval; struct { struct { int downmix; float lowp_freq; int speex_prep; int speex_prep_denoise; int speex_prep_agc; int speex_prep_vad; } in; } filter; } g_conf; int dtx_counter = 0; struct { int state; struct roar_connection con; struct roar_stream stream; struct roar_vio_calls * svio; } g_cons; struct roar_bixcoder transcoder[1]; struct { struct roardsp_filterchain input; struct roardsp_filterchain output; } g_filterchains; struct { struct { char key[ROAR_META_MAX_NAMELEN]; char value[LIBROAR_BUFFER_MSGDATA]; } tmp; char * rn; char * nick; char * org; char * email; char * hp; char * loc; char * thumbnail; } g_meta; void usage (void) { printf("roarphone [OPTIONS]...\n"); printf("\nServer Options:\n\n"); printf(" --server SERVER - Set server hostname\n" " --jumbo-mtu MTU - Sets the MTU for Jumbo Packets\n" " --io-flush INTERVAL - Flushs output every INTERVAL packets\n" ); printf("\nAudio Options:\n\n"); printf(" --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --aiprofile PROFILE - Set audio profile\n" ); printf("\nAudio Filter Options:\n\n"); printf(" --afi-downmix - Enable input downmixing\n" " --afi-lowpass FREQ - Enable input lowpass at FREQ (in Hz)\n" " --afi-speex-prep - Enable speex preprocessor\n" " --afi-speex-denoise - Enable speex denoiser\n" " --afi-speex-agc - Enable speex AGC\n" " --afi-speex-vad - Enable speex VAD\n" ); printf("\nCodec Options:\n\n"); printf(" --codec -E CODEC - Set the codec\n" " --transcode - Use local transcodeing\n" ); printf("\nDriver Options:\n\n"); printf(" --driver DRIVER - Set the driver\n" " --device DEVICE - Set the device\n" ); printf("\nGeneral Options:\n\n"); printf(" --antiecho AEMODE - Set the anti echo mode\n" " --threshold DTXTHRES - Set the DTX threshold, disabled by default\n" " --help - Show this help\n" ); printf("\nMeta Data Options:\n\n"); printf(" --m-rn REALNAME - Sets the real name\n" " --m-nick NICK - Sets the nick name\n" " --m-email EMAIL - Sets the email address\n" " --m-hp HOMEPAGE - Sets the homepage URL\n" " --m-thumbn THUMBNAIL - Sets a URL to a thumbnail\n" " --m-loc LOCATION - Sets the location (room number)\n" " --m-org ORGANIZATION - Sets the organization/company name\n" ); } int open_stream (struct roar_vio_calls * vio, const char * server, struct roar_audio_info * info) { int fh; g_cons.svio = vio; if ( !(g_cons.state & CON_CON) ) if ( roar_simple_connect(&(g_cons.con), server, "roarphone") == -1 ) return -1; g_cons.state |= CON_CON; if ( (fh = roar_vio_simple_new_stream_obj(vio, &(g_cons.con), &(g_cons.stream), info->rate, info->channels, info->bits, info->codec, ROAR_DIR_BIDIR, -1 )) == -1 ) return -1; g_cons.state |= CON_STREAM; return 0; } #define _SET_META(ivar,itype) if ( (ivar) != NULL ) { \ meta.value = (ivar); \ meta.type = (itype); \ roar_stream_meta_set(&(g_cons.con), &(g_cons.stream), ROAR_META_MODE_SET, &meta); \ } int set_meta (void) { struct roar_meta meta; meta.value = g_meta.tmp.value; meta.key[0] = 0; meta.type = ROAR_META_TYPE_NONE; roar_stream_meta_set(&(g_cons.con), &(g_cons.stream), ROAR_META_MODE_CLEAR, &meta); _SET_META(g_meta.thumbnail, ROAR_META_TYPE_THUMBNAIL); _SET_META(g_meta.loc, ROAR_META_TYPE_LOCATION); _SET_META(g_meta.hp, ROAR_META_TYPE_HOMEPAGE); _SET_META(g_meta.org, ROAR_META_TYPE_ORGANIZATION); if ( g_meta.nick != NULL ) { if ( g_meta.rn != NULL ) { snprintf(g_meta.tmp.value, LIBROAR_BUFFER_MSGDATA-1, "%s (%s)", g_meta.rn, g_meta.nick); g_meta.tmp.value[LIBROAR_BUFFER_MSGDATA-1] = 0; _SET_META(g_meta.tmp.value, ROAR_META_TYPE_AUTHOR); } else { _SET_META(g_meta.nick, ROAR_META_TYPE_AUTHOR); } } else { if ( g_meta.rn != NULL ) { _SET_META(g_meta.rn, ROAR_META_TYPE_AUTHOR); } } // TODO: make this more nice... if ( g_meta.email != NULL ) { if ( g_meta.nick != NULL ) { if ( g_meta.rn != NULL ) { snprintf(g_meta.tmp.value, LIBROAR_BUFFER_MSGDATA-1, "%s (%s) <%s>", g_meta.rn, g_meta.nick, g_meta.email); } else { snprintf(g_meta.tmp.value, LIBROAR_BUFFER_MSGDATA-1, "%s <%s>", g_meta.nick, g_meta.email); } } else { if ( g_meta.rn != NULL ) { snprintf(g_meta.tmp.value, LIBROAR_BUFFER_MSGDATA-1, "%s <%s>", g_meta.rn, g_meta.email); } else { snprintf(g_meta.tmp.value, LIBROAR_BUFFER_MSGDATA-1, "<%s>", g_meta.email); } } g_meta.tmp.value[LIBROAR_BUFFER_MSGDATA-1] = 0; _SET_META(g_meta.tmp.value, ROAR_META_TYPE_CONTACT); } return 0; } #ifdef _SPEEX_API_OLD int anti_echo_speex16(int16_t * buf, int16_t * aebuf, size_t len, struct roar_audio_info * info) { static SpeexEchoState * state = NULL; size_t samples = info->rate / TIMEDIV; static int16_t * obuf = NULL; if ( info->channels != 1 ) return -1; if (len != samples) return -1; ROAR_DBG("anti_echo_speex16(*) = ?"); if ( state == NULL ) { if ( (state = speex_echo_state_init(samples, 100*samples)) == NULL ) return -1; // todo: set sample rate. } ROAR_DBG("anti_echo_speex16(*) = ?"); if ( obuf == NULL ) { if ( (obuf = roar_mm_malloc(2*samples)) == NULL ) return -1; } ROAR_DBG("anti_echo_speex16(*) = ?"); /* speex_echo_cancellation(state, buf, aebuf, obuf); */ speex_echo_cancel(state, buf, aebuf, obuf, NULL); memcpy(buf, obuf, 2*samples); ROAR_DBG("anti_echo_speex16(*) = 0"); return 0; } #endif int anti_echo16(int16_t * buf, int16_t * aebuf, size_t len, struct roar_audio_info * info) { size_t i; (void)info; switch (g_conf.antiecho) { case AE_NONE: return 0; break; case AE_SIMPLE: for (i = 0; i < len; i++) buf[i] -= aebuf[i]; return 0; break; #ifdef _SPEEX_API_OLD case AE_SPEEX: return anti_echo_speex16(buf, aebuf, len, info); break; #endif case AE_ROARD: return 0; break; default: return -1; break; } return -1; } int zero_if_noise16 (int16_t * data, size_t samples) { int64_t rms = roar_rms2_1_16(data, samples); if ( rms < g_conf.dtx_threshold ) { if ( dtx_counter ) { dtx_counter--; } else { memset(data, 0, samples*2); } } else { dtx_counter = DTX_F; } return 0; } int run_stream (struct roar_vio_calls * s0, struct roar_vio_calls * s1, struct roar_audio_info * info) { size_t len; void * outbuf, * micbuf; ssize_t outlen, miclen; unsigned long int pkg_count = 0; ROAR_DBG("run_stream(*): g_conf.samples = %i, info->bits = %i", g_conf.samples, info->bits); len = g_conf.samples * info->bits / 8; ROAR_DBG("run_stream(*): len=%lu", (unsigned long) len); if ( (outbuf = roar_mm_malloc(2*len)) == NULL ) return -1; micbuf = outbuf + len; while (1) { if ( (miclen = roar_vio_read(s0, micbuf, len)) <= 0 ) break; if ( roardsp_fchain_num(&(g_filterchains.input)) ) { if ( roardsp_fchain_calc(&(g_filterchains.input), micbuf, len) == -1 ) break; } if ( g_conf.dtx_threshold > 0 ) if ( info->bits == 16 ) zero_if_noise16(micbuf, miclen/2); if ( g_conf.transcode ) { if ( roar_bixcoder_write_packet(transcoder, micbuf, miclen) == -1 ) break; } else { if ( roar_vio_write(s1, micbuf, miclen) != miclen ) break; } if ( g_conf.ioflush_interval != -1 ) { if ( !(pkg_count % g_conf.ioflush_interval) ) roar_vio_sync(s1); } if ( g_conf.transcode ) { ROAR_DBG("run_stream(*): outbuf=%p, len=%lu", outbuf, (unsigned long) len); if ( roar_bixcoder_read_packet(transcoder, outbuf, len) == -1 ) break; outlen = len; } else { if ( (outlen = roar_vio_read(s1, outbuf, len)) <= 0 ) break; } if ( g_conf.antiecho != AE_NONE && info->bits == 16 ) anti_echo16(outbuf, micbuf, ROAR_MIN(miclen, outlen)/2, info); if ( roardsp_fchain_num(&(g_filterchains.output)) ) { if ( roardsp_fchain_calc(&(g_filterchains.output), outbuf, outlen) == -1 ) break; } if ( roar_vio_write(s0, outbuf, outlen) != outlen ) break; pkg_count++; } roar_mm_free(outbuf); return 0; } int main (int argc, char * argv[]) { struct roar_audio_info info = {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_CODEC_DEFAULT }; struct roar_audio_info dinfo; struct roar_vio_calls dvio, svio, svio_jumbo, svio_real; struct roar_vio_calls * svio_p; struct roardsp_filter * filter; const char * driver = DRIVER; const char * device = NULL; const char * server = NULL; const char * k; int i; union { int32_t i32; size_t size; } tmp; memset(&g_conf, 0, sizeof(g_conf)); g_conf.antiecho = AE_ROARD; g_conf.dtx_threshold = -1; g_conf.ioflush_interval = -1; memset(&g_cons, 0, sizeof(g_cons)); g_cons.state = CON_NONE; memset(&g_meta, 0, sizeof(g_meta)); roardsp_fchain_init(&(g_filterchains.input)); roardsp_fchain_init(&(g_filterchains.output)); for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--jumbo-mtu") == 0 ) { ROAR_CKHAVEARGS(1); g_conf.jumbo_mtu = atoi(argv[++i]); } else if ( strcmp(k, "--io-flush") == 0 ) { ROAR_CKHAVEARGS(1); g_conf.ioflush_interval = atoi(argv[++i]); } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( strcmp(k, "--afi-downmix") == 0 ) { g_conf.filter.in.downmix = 1; } else if ( strcmp(k, "--afi-lowpass") == 0 ) { g_conf.filter.in.lowp_freq = atof(argv[++i]); } else if ( strcmp(k, "--afi-speex-prep") == 0 ) { g_conf.filter.in.speex_prep = 1; } else if ( strcmp(k, "--afi-speex-denoise") == 0 ) { g_conf.filter.in.speex_prep = 1; g_conf.filter.in.speex_prep_denoise = 1; } else if ( strcmp(k, "--afi-speex-agc") == 0 ) { g_conf.filter.in.speex_prep = 1; g_conf.filter.in.speex_prep_agc = 1; } else if ( strcmp(k, "--afi-speex-vad") == 0 ) { g_conf.filter.in.speex_prep = 1; g_conf.filter.in.speex_prep_vad = 1; } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) { ROAR_CKHAVEARGS(1); info.codec = roar_str2codec(argv[++i]); } else if ( strcmp(k, "--driver") == 0 ) { ROAR_CKHAVEARGS(1); driver = argv[++i]; } else if ( strcmp(k, "--device") == 0 ) { ROAR_CKHAVEARGS(1); device = argv[++i]; } else if ( strcmp(k, "--antiecho") == 0 ) { ROAR_CKHAVEARGS(1); k = argv[++i]; if ( !strcmp(k, "none") ) { g_conf.antiecho = AE_NONE; } else if ( !strcmp(k, "simple") ) { g_conf.antiecho = AE_SIMPLE; } else if ( !strcmp(k, "speex") ) { g_conf.antiecho = AE_SPEEX; } else if ( !strcmp(k, "roard") ) { g_conf.antiecho = AE_ROARD; } else { fprintf(stderr, "Error: unknown mode: %s\n", k); return 1; } } else if ( strcmp(k, "--threshold") == 0 ) { ROAR_CKHAVEARGS(1); g_conf.dtx_threshold = atol(argv[++i]); // use threshold^2 or threshold < 0 for not using DTX if ( g_conf.dtx_threshold > 0 ) g_conf.dtx_threshold *= g_conf.dtx_threshold; } else if ( strcmp(k, "--transcode") == 0 ) { g_conf.transcode = 1; // META DATA: } else if ( strcmp(k, "--m-rn") == 0 ) { ROAR_CKHAVEARGS(1); g_meta.rn = argv[++i]; } else if ( strcmp(k, "--m-nick") == 0 ) { ROAR_CKHAVEARGS(1); g_meta.nick = argv[++i]; } else if ( strcmp(k, "--m-email") == 0 ) { ROAR_CKHAVEARGS(1); g_meta.email = argv[++i]; } else if ( strcmp(k, "--m-hp") == 0 ) { ROAR_CKHAVEARGS(1); g_meta.hp = argv[++i]; } else if ( strcmp(k, "--m-thumbn") == 0 ) { ROAR_CKHAVEARGS(1); g_meta.thumbnail = argv[++i]; } else if ( strcmp(k, "--m-loc") == 0 ) { ROAR_CKHAVEARGS(1); g_meta.loc = argv[++i]; } else if ( strcmp(k, "--m-org") == 0 ) { ROAR_CKHAVEARGS(1); g_meta.org = argv[++i]; } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } // ignore errors, maybe it will work even if this fails // (btw. it will never fail without crashing the rest of the app ;) roar_libroar_set_server(server); if ( g_conf.antiecho == AE_SPEEX ) { ROAR_WARN("Speex Antiecho is obsolete and may be removed in future versions. Use --antiecho roard"); } g_conf.samples = info.channels * info.rate / TIMEDIV; memcpy(&dinfo, &info, sizeof(dinfo)); if ( g_conf.transcode ) { dinfo.bits = 16; dinfo.codec = ROAR_CODEC_DEFAULT; switch (info.codec) { case ROAR_CODEC_ALAW: case ROAR_CODEC_MULAW: info.bits = 8; break; case ROAR_CODEC_ROAR_CELT: info.bits = 16; break; case ROAR_CODEC_ROAR_SPEEX: info.bits = 16; break; } } if ( roar_cdriver_open(&dvio, driver, device, &dinfo, ROAR_DIR_RECPLAY) == -1 ) { ROAR_ERR("Can not open sound card."); return 1; } ROAR_DBG("main(*): CALL open_stream(&svio, server, &info)"); if ( open_stream(&svio_real, server, &info) == -1 ) { ROAR_ERR("Can not open connection to server."); roar_vio_close(&dvio); return 2; } ROAR_DBG("main(*): RET"); if ( roar_vio_open_re(&svio, &svio_real) == -1 ) { ROAR_ERR("Can not open connection to server (RE VIO)."); roar_vio_close(&dvio); return 2; } if ( g_conf.jumbo_mtu ) { if ( roar_vio_open_jumbo(&svio_jumbo, &svio, g_conf.jumbo_mtu) == -1 ) { roar_vio_close(&dvio); roar_vio_close(&svio); return 2; } svio_p = &svio_jumbo; } else { svio_p = &svio; } set_meta(); if ( g_conf.transcode ) { dinfo.codec = info.codec; if ( roar_bixcoder_init(transcoder, &dinfo, svio_p) == -1 ) { roar_vio_close(&svio); roar_vio_close(&dvio); return 10; } // ignore errors as it may also work if this fails roar_bixcoder_write_header(transcoder); roar_bixcoder_read_header(transcoder); g_conf.samples = 8 * roar_bixcoder_packet_size(transcoder, -1) / dinfo.bits; } #define _err(x) roar_vio_close(&dvio); roar_vio_close(&svio); return (x) if ( g_conf.filter.in.downmix ) { if ( roardsp_filter_new(&filter, &(g_cons.stream), ROARDSP_FILTER_DOWNMIX) == -1 ) { _err(2); } if ( roardsp_fchain_add(&(g_filterchains.input), filter) == -1 ) { _err(2); } } if ( g_conf.filter.in.lowp_freq > 1 ) { if ( roardsp_filter_new(&filter, &(g_cons.stream), ROARDSP_FILTER_LOWP) == -1 ) { _err(2); } if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_FREQ, &(g_conf.filter.in.lowp_freq)) == -1 ) { _err(2); } if ( roardsp_fchain_add(&(g_filterchains.input), filter) == -1 ) { _err(2); } } if ( g_conf.filter.in.speex_prep ) { if ( roardsp_filter_new(&filter, &(g_cons.stream), ROARDSP_FILTER_SPEEX_PREP) == -1 ) { _err(2); } tmp.size = g_conf.samples; if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_PACKET_SIZE, &tmp) == -1 ) { _err(2); } tmp.i32 = 0; if ( g_conf.filter.in.speex_prep_denoise ) tmp.i32 |= ROARDSP_SPEEX_PREP_DENOISE_ON; if ( g_conf.filter.in.speex_prep_agc ) tmp.i32 |= ROARDSP_SPEEX_PREP_AGC_ON; if ( g_conf.filter.in.speex_prep_vad ) tmp.i32 |= ROARDSP_SPEEX_PREP_VAD_ON; if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_MODE, &tmp) == -1 ) { _err(2); } if ( roardsp_fchain_add(&(g_filterchains.input), filter) == -1 ) { _err(2); } } #undef _err ROAR_DBG("main(*): CALL run_stream(&dvio, &svio, &info);"); run_stream(&dvio, svio_p, &info); ROAR_DBG("main(*): RET"); roar_bixcoder_close(transcoder); roar_vio_close(svio_p); roar_vio_close(&dvio); roardsp_fchain_uninit(&(g_filterchains.input)); roardsp_fchain_uninit(&(g_filterchains.output)); roar_disconnect(&(g_cons.con)); return 0; } //ll roaraudio-1.0beta11/roarclients/roarpluginapplication.sht0000755000175000017500000000036311745726133022150 0ustar phiphi#!/bin/sh _plugin=`basename "$0"` if [ "$_plugin" = 'roarpluginapplication' ] then echo "$0: This script should not be run like this, see $_plugin(1) for details." exit 1 fi exec roarpluginrunner --run-as-application "$_plugin" "$@" #ll roaraudio-1.0beta11/roarclients/roarpluginrunner.c0000644000175000017500000005345512264733651020611 0ustar phiphi//roarpluginrunner.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ int g_verbose = 0; #define ROAR_DBG_INFOVAR g_verbose #include enum action { RUN, RUN_AS_APPLICATION, EXPLAIN }; #define OPTION_NONE 0x0000 #define OPTION_TOUCH 0x0001 #define OPTION_ABOUT 0x0100 #define OPTION_HELP 0x0200 #define OPTION_PREFERENCES 0x0400 static struct roar_dl_librarypara * g_para = NULL; static struct roar_scheduler * g_sched = NULL; static struct roar_scheduler_source g_s_service = {.type = ROAR_SCHEDULER_CPI_SERVICE}; static void usage (const char * progname) { fprintf(stderr, "Usage: %s [OPTIONS]... PLUGIN\n", progname); fprintf(stderr, "\nOptions:\n\n"); fprintf(stderr, " -h --help - This help.\n" " -v --verbose - Be verbose. Can be used multiple times.\n" " --server SERVER - Set default server to SERVER.\n" " --run - Run plugin.\n" " --run-as-application - Same as --run except all tailing arguments are\n" " passed to the plugin.\n" " --explain - Explain plugin.\n" " --appname NAME - Sets the appname.\n" " --abiversion ABI - Set the ABI version.\n" " --args ARGS - Set plugin arguments.\n" ); fprintf(stderr, "\nRunner Options:\n\n"); fprintf(stderr, " --option-touch - Do not keep the plugin running:\n" " Do a single UPDATE cycle.\n" " --option-no-touch - Disable touch option.\n" " --option-about - Show an about dialog after startup.\n" " --option-no-about - Disable about option.\n" " --option-help - Show onlion help after startup.\n" " --option-no-help - Disable help option.\n" " --option-preferences - Show preferences dialog after startup.\n" " --option-no-preferences\n" " - Disable preferences option.\n" ); fprintf(stderr, "\nCPI Options:\n\n"); fprintf(stderr, " -t --tcp - Use TCP listen socket\n" " -u --unix - Use UNIX Domain listen socket (default)\n" " -n --decnet - use DECnet listen socket\n" " --port PORT - TCP Port to bind to\n" " --bind ADDR - Node/Hostname/Path to bind to\n" " --proto PROTO - Use PROTO as protocol on Socket\n" " --new-sock - Parameters for new socket follow\n" " --client-fh FH - Comunicate with a client over this handle\n" "\n" ); } static int do_run(const char * name, int options) { struct roar_scheduler_source s_container; struct roar_plugincontainer * cont = roar_plugincontainer_new(g_para); int err; if ( cont == NULL ) return -1; memset(&s_container, 0, sizeof(s_container)); s_container.type = ROAR_SCHEDULER_PLUGINCONTAINER; s_container.handle.container = cont; roar_scheduler_source_add(g_sched, &s_container); if ( roar_plugincontainer_load(cont, name, NULL) == -1 ) { err = roar_error; roar_scheduler_source_del(g_sched, &s_container); roar_plugincontainer_unref(cont); roar_error = err; return -1; } roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_INIT); if ( options & OPTION_ABOUT ) { if ( roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_ABOUT) == -1 ) { ROAR_WARN("Can not call ABOUT trigger: %s", roar_errorstring); } } if ( options & OPTION_HELP ) { if ( roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_HELP) == -1 ) { ROAR_WARN("Can not call HELP trigger: %s", roar_errorstring); } } if ( options & OPTION_PREFERENCES ) { if ( roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_PREFERENCES) == -1 ) { ROAR_WARN("Can not call PREFERENCES trigger: %s", roar_errorstring); } } if ( !(options & OPTION_TOUCH) ) roar_scheduler_run(g_sched); roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_UPDATE); roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_FREE); roar_scheduler_source_del(g_sched, &s_container); roar_plugincontainer_unref(cont); return 0; } static const char * _ptr2str(const void * p) { #if defined(ROAR_HAVE_H_DLFCN) && defined(ROAR_HAVE_DLADDR) static char buf[80]; Dl_info info; #else static char buf[24]; #endif if ( p == NULL ) return ""; #if defined(ROAR_HAVE_H_DLFCN) && defined(ROAR_HAVE_DLADDR) if ( dladdr(p, &info) != 0 ) { if ( p == info.dli_saddr ) { snprintf(buf, sizeof(buf), "%p <%s in \"%s\">", p, info.dli_sname, info.dli_fname); return buf; } } #endif snprintf(buf, sizeof(buf), "%p", p); return buf; } static const char * _ptrrange2str(const void * p, size_t len) { static char buf[80]; if ( p == NULL ) return ""; if ( len == 0 ) return _ptr2str(p); snprintf(buf, sizeof(buf), "%p-%p", p, p + len); return buf; } static int do_explain(const char * name) { struct roar_dl_lhandle * lhandle = roar_dl_open(name, ROAR_DL_FLAG_LAZY|ROAR_DL_FLAG_PLUGINPATH, 0, g_para); struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para); struct roar_dl_libraryinst * lib; int libok = 0, libnameok = 0, libdepok = 0; int tmp; int i; size_t iter; char c; if ( lhandle == NULL ) return -1; func = roar_dl_getsym(lhandle, "_roaraudio_library_init", -1); if ( func == NULL ) { fprintf(stderr, "Warning: Not a RA lib: %s\n", name); roar_dl_unref(lhandle); return 0; } lib = func(g_para); if ( lib == NULL ) { fprintf(stderr, "Warning: Can not RA init: %s: %s\n", name, roar_error2str(roar_error)); roar_dl_unref(lhandle); return 0; } if ( lib->version == ROAR_DL_LIBINST_VERSION && lib->len == sizeof(*lib) ) { libok = 1; } printf("lib = %s\n", _ptr2str(lib)); if ( g_verbose || !libok ) { printf("|-> version = %i (%smatch)\n", lib->version, lib->version == ROAR_DL_LIBINST_VERSION ? "" : "no "); printf("%c-> len = %zu (%smatch)\n", libok ? '|' : '\\', lib->len, lib->len == sizeof(*lib) ? "" : "no "); } if ( libok ) { if ( g_verbose || lib->unload != NULL ) printf("|-> unload = %s\n", _ptr2str(lib->unload)); printf("|-> func = {"); i = 0; while (i < ROAR_DL_FN_MAX) { for (tmp = 0; i < ROAR_DL_FN_MAX; i++) { if ( lib->func[i] != NULL ) { break; } tmp++; } if (tmp) printf("%i x %s", tmp, i < (ROAR_DL_FN_MAX-1) ? ", " : ""); if ( i < ROAR_DL_FN_MAX ) { printf("[%i] = %s%s", i, _ptr2str(lib->func[i]), i < (ROAR_DL_FN_MAX-1) ? ", " : ""); i++; } } printf("}\n"); printf("|-> libname = %s\n", _ptr2str(lib->libname)); if ( lib->libname != NULL ) { if ( lib->libname->version == ROAR_DL_LIBNAME_VERSION && lib->libname->len == sizeof(*(lib->libname)) ) { libnameok = 1; } if ( g_verbose || !libnameok ) { printf("| |-> version = %i (%smatch)\n", lib->libname->version, lib->libname->version == ROAR_DL_LIBNAME_VERSION ? "" : "no "); printf("| %c-> len = %zu (%smatch)\n", libnameok ? '|' : '\\', lib->libname->len, lib->libname->len == sizeof(*(lib->libname)) ? "" : "no "); } if ( libnameok ) { #define _ps(k,name) \ tmp = (lib->libname->name) != NULL; \ if ( tmp || g_verbose || (k) == '\\' ) \ printf("| %c-> %-15s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \ tmp ? (lib->libname->name) : "", tmp ? "\"" : ""); _ps('|', name); _ps('|', libname); _ps('|', libversion); _ps('|', abiversion); _ps('|', description); _ps('|', contact); _ps('|', authors); _ps('\\', license); #undef _ps } } if ( g_verbose || lib->global_data_pointer != NULL ) printf("|-> global_data_len = %zu\n", lib->global_data_len); if ( g_verbose || lib->global_data_init != NULL ) printf("|-> global_data_init = %s\n", _ptrrange2str(lib->global_data_init, lib->global_data_len)); if ( g_verbose || lib->global_data_pointer != NULL ) printf("|-> global_data_pointer = %s\n", _ptr2str(lib->global_data_pointer)); if ( lib->libdep != NULL && lib->libdep_len ) { printf("|-> libdep = %s\n", _ptr2str(lib->libdep)); for (iter = 0; iter < lib->libdep_len; iter++) { printf("| %c-> Table entry %zu = %p\n", iter == (lib->libdep_len-1) ? '\\' : '|', iter, &(lib->libdep[iter])); c = iter == (lib->libdep_len-1) ? ' ' : '|'; if ( lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION && lib->libdep[iter].len == sizeof(struct roar_dl_librarydep) ) { libdepok = 1; } else { libdepok = 0; } if ( g_verbose || !libdepok ) { printf("| %c |-> version = %i (%smatch)\n", c, lib->libdep[iter].version, lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION ? "" : "no "); printf("| %c %c-> len = %zu (%smatch)\n", c, libdepok ? '|' : '\\', lib->libdep[iter].len, lib->libdep[iter].len == sizeof(struct roar_dl_librarydep) ? "" : "no "); } if ( libdepok ) { printf("| %c |-> flags = 0x%.8lX\n", c, (unsigned long int)lib->libdep[iter].flags); #define _ps(k,name) \ tmp = (lib->libdep[iter].name) != NULL; \ if ( tmp || g_verbose || (k) == '\\' ) \ printf("| %c %c-> %-11s = %s%s%s\n", c, (k), #name, tmp ? "\"" : "", \ tmp ? (lib->libdep[iter].name) : "", tmp ? "\"" : ""); _ps('|', name); _ps('|', libname); _ps('\\', abiversion); #undef _ps } } printf("|-> libdep_len = %zu\n", lib->libdep_len); } else if ( (lib->libdep == NULL && lib->libdep_len) || (lib->libdep != NULL && !lib->libdep_len) ) { printf("|-> libdep = %s (invalid)\n", _ptr2str(lib->libdep)); printf("|-> libdep_len = %zu (invalid)\n", lib->libdep_len); } if ( g_verbose || lib->appsched != NULL ) { printf("|-> appsched = %s\n", _ptr2str(lib->appsched)); if ( lib->appsched != NULL ) { if ( g_verbose || lib->appsched->init != NULL ) printf("| |-> init = %s\n", _ptr2str(lib->appsched->init)); if ( g_verbose || lib->appsched->free != NULL ) printf("| |-> free = %s\n", _ptr2str(lib->appsched->free)); if ( g_verbose || lib->appsched->update != NULL ) printf("| |-> update = %s\n", _ptr2str(lib->appsched->update)); if ( g_verbose || lib->appsched->tick != NULL ) printf("| |-> tick = %s\n", _ptr2str(lib->appsched->tick)); printf("| \\-> wait = %s\n", _ptr2str(lib->appsched->wait)); } } #define _ps(k,name) \ tmp = (lib->name) != NULL; \ if ( tmp || g_verbose || (k) == '\\' ) \ printf("%c-> %-19s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \ tmp ? (lib->name) : "", tmp ? "\"" : ""); _ps('|', host_appname); _ps('\\', host_abiversion); #undef _ps } roar_dl_unref(lhandle); return 0; } static int do_plugin(enum action action, const char * name, int options) { switch (action) { case EXPLAIN: return do_explain(name); break; case RUN: case RUN_AS_APPLICATION: return do_run(name, options); break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } } static inline void _clear_para(void) { if ( g_para == NULL ) return; roar_dl_para_unref(g_para); g_para = NULL; } static inline int _add_para(struct roar_dl_librarypara * para, const char * pluginargs, size_t argc, char * argv[]) { struct roar_keyval * kv; ssize_t argslen, argvlen; ssize_t arglen; ssize_t pluginargc; size_t argv_phys = argc; size_t i; int error; char * sp, * c; int after_parser_end; if ( pluginargs == NULL ) pluginargs = ""; argslen = roar_mm_strlen(pluginargs) + 1 /* tailing '\0' */; after_parser_end = 0; argvlen = 0; for (i = 0; i < argv_phys; i++) { arglen = roar_mm_strlen(argv[i]); argvlen += arglen; if ( !after_parser_end ) { if ( !strcmp(argv[i], "--") ) { after_parser_end = 1; argc--; } else if ( arglen > 1 && argv[i][0] == '-' && !(arglen > 2 && argv[i][1] == '-') ) { argc += arglen - 2; } } } argvlen += argc; // the '\0's. para->args_store = roar_mm_malloc(argslen+argvlen); if ( para == NULL ) return -1; memcpy(para->args_store, pluginargs, argslen); pluginargc = roar_keyval_split(&kv, para->args_store, NULL, NULL, 1); if ( pluginargc == -1 ) { error = roar_error; roar_mm_free(para->args_store); para->args_store = NULL; roar_error = error; return -1; } para->argv = roar_mm_malloc((pluginargc+argc)*sizeof(struct roar_keyval)); if ( para->argv == NULL ) { error = roar_error; roar_mm_free(kv); roar_mm_free(para->args_store); para->args_store = NULL; roar_error = error; return -1; } para->argc = pluginargc + argc; memcpy(para->argv, kv, pluginargc*sizeof(struct roar_keyval)); roar_mm_free(kv); sp = para->args_store + argslen; kv = para->argv + pluginargc; after_parser_end = 0; for (i = 0; i < argv_phys; i++) { arglen = roar_mm_strlen(argv[i]) + 1; if ( after_parser_end || !(arglen > 2 && argv[i][0] == '-' && !(arglen > 3 && argv[i][1] == '-')) ) memcpy(sp, argv[i], arglen); if ( !after_parser_end && !strcmp(argv[i], "--") ) { after_parser_end = 1; continue; } else if ( !after_parser_end && arglen > 3 && sp[0] == '-' && sp[1] == '-' ) { kv->key = sp + 2; kv->value = NULL; for (c = sp + 2; *c; c++) { if (*c == '=') { *c = 0; c++; kv->value = c; break; } } } else if ( !after_parser_end && arglen > 2 && argv[i][0] == '-' ) { for (c = argv[i] + 1; *c; c++) { sp[0] = *c; sp[1] = 0; kv->key = sp; kv->value = NULL; sp += 2; kv++; } continue; } else { kv->key = NULL; kv->value = sp; } sp += arglen; kv++; } return 0; } static struct roar_scheduler_source * add_cpi_common(int proto) { struct roar_scheduler_source * source; int err; if ( proto == -1 ) { roar_err_set(ROAR_ERROR_INVAL); return NULL; } source = roar_mm_malloc(sizeof(struct roar_scheduler_source)); if ( source == NULL ) return NULL; memset(source, 0, sizeof(struct roar_scheduler_source)); source->vio = roar_mm_malloc(sizeof(struct roar_vio_calls)); if ( source->vio == NULL ) { err = roar_error; roar_mm_free(source); roar_error = err; return NULL; } source->flags = ROAR_SCHEDULER_FLAG_FREE; source->handle.cpi.proto = proto; return source; } static int add_cpi_listen(int proto, int type, const char * host, int port) { struct roar_scheduler_source * source = add_cpi_common(proto); int err; if ( source == NULL ) return -1; if ( roar_vio_open_socket_listen(source->vio, type, host, port) == -1 ) { err = roar_error; roar_mm_free(source->vio); roar_mm_free(source); roar_error = err; return -1; } source->type = ROAR_SCHEDULER_CPI_LISTEN; source->vio->flags |= ROAR_VIO_FLAGS_FREESELF; if ( roar_scheduler_source_add(g_sched, source) == -1 ) { err = roar_error; roar_vio_close(source->vio); roar_mm_free(source); roar_error = err; return -1; } return 0; } static int add_cpi_client(int proto, int fh) { struct roar_scheduler_source * source = add_cpi_common(proto); struct roar_dl_librarypara * para; int err; if ( source == NULL ) return -1; if ( roar_vio_open_fh(source->vio, fh) == -1 ) { err = roar_error; roar_mm_free(source->vio); roar_mm_free(source); roar_error = err; return -1; } source->type = ROAR_SCHEDULER_CPI_CLIENT; source->vio->flags |= ROAR_VIO_FLAGS_FREESELF; if ( roar_scheduler_source_add(g_sched, source) == -1 ) { err = roar_error; roar_vio_close(source->vio); roar_mm_free(source); roar_error = err; return -1; } if ( source->flags & ROAR_SCHEDULER_FLAG_STUB ) { ROAR_ERR("Can not handle proto STUB clients. Try to use --client-fh as last argument."); roar_scheduler_source_del(g_sched, source); return -1; } if ( source->handle.cpi.impl->set_proto != NULL ) { para = roar_dl_getpara(source->lhandle); if ( source->lhandle != NULL ) roar_dl_context_restore(source->lhandle); source->handle.cpi.impl->set_proto(source->handle.cpi.client, source->vio, &(source->handle.cpi.obuffer), &(source->handle.cpi.userdata), source->handle.cpi.protopara, source->handle.cpi.protoparalen, para); if ( source->lhandle != NULL ) roar_dl_context_store(source->lhandle); if ( para != NULL ) roar_dl_para_unref(para); } return 0; } int main (int argc, char * argv[]) { const char * appname = "roarpluginrunner " ROAR_VSTR_ROARAUDIO; const char * abiversion = "1.0beta0"; const char * pluginargs = NULL; enum action action = RUN; int ret = 0; int i; const char * k; int cpi_type = ROAR_SOCKET_TYPE_UNKNOWN; int cpi_proto = -1; int cpi_port = 0; int cpi_touched = 0; const char * cpi_host = NULL; int options = OPTION_NONE; g_sched = roar_scheduler_new(ROAR_SCHEDULER_FLAG_NONE, ROAR_SCHEDULER_STRATEGY_DEFAULT); if ( g_sched == NULL ) { fprintf(stderr, "Error creating scheduler object: %s\n", roar_error2str(roar_error)); return 1; } roar_scheduler_source_add(g_sched, &g_s_service); for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "-h") || !strcmp(k, "--help") ) { usage(argv[0]); roar_scheduler_unref(g_sched); return 0; } else if ( !strcmp(k, "--run") ) { action = RUN; } else if ( !strcmp(k, "--run-as-application") ) { action = RUN_AS_APPLICATION; } else if ( !strcmp(k, "--explain") ) { action = EXPLAIN; } else if ( !strcmp(k, "-v") || !strcmp(k, "--verbose") ) { g_verbose++; } else if ( !strcmp(k, "--server") ) { ROAR_CKHAVEARGS(1); roar_libroar_set_server(argv[++i]); } else if ( !strcmp(k, "--tcp") || !strcmp(k, "-t") ) { cpi_type = ROAR_SOCKET_TYPE_TCP; cpi_touched++; } else if ( !strcmp(k, "--unix") || !strcmp(k, "-u") ) { cpi_type = ROAR_SOCKET_TYPE_UNIX; cpi_touched++; } else if ( !strcmp(k, "--decnet") || !strcmp(k, "-n") ) { cpi_type = ROAR_SOCKET_TYPE_DECNET; cpi_touched++; } else if ( !strcmp(k, "--port") ) { ROAR_CKHAVEARGS(1); cpi_port = atoi(argv[++i]); cpi_touched++; } else if ( !strcmp(k, "--bind") ) { ROAR_CKHAVEARGS(1); cpi_host = argv[++i]; cpi_touched++; } else if ( !strcmp(k, "--proto") ) { ROAR_CKHAVEARGS(1); cpi_proto = roar_str2proto(argv[++i]); if ( cpi_proto == -1 ) { fprintf(stderr, "Unknown protocol: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( !strcmp(k, "--new-sock") ) { if ( cpi_touched && add_cpi_listen(cpi_proto, cpi_type, cpi_host, cpi_port) == -1 ) { fprintf(stderr, "Can not open socket for CPI: %s\n", roar_error2str(roar_error)); return 1; } cpi_touched = 0; } else if ( !strcmp(k, "--client-fh") ) { ROAR_CKHAVEARGS(1); if ( add_cpi_client(cpi_proto, atoi(argv[++i])) == -1 ) { fprintf(stderr, "Can not add CPI client: %s\n", roar_error2str(roar_error)); return 1; } #define _option(name) \ } else if ( !strcasecmp(k, "--option-" #name) ) { \ options |= OPTION_ ## name; \ } else if ( !strcasecmp(k, "--option-no-" #name) ) { \ options |= OPTION_ ## name; \ options -= OPTION_ ## name; #define __fix_vim_syntax_highlight } _option(TOUCH) _option(ABOUT) _option(HELP) _option(PREFERENCES) } else if ( !strcmp(k, "--appname") ) { ROAR_CKHAVEARGS(1); appname = argv[++i]; _clear_para(); } else if ( !strcmp(k, "--abiversion") ) { ROAR_CKHAVEARGS(1); abiversion = argv[++i]; _clear_para(); } else if ( !strcmp(k, "--args") ) { ROAR_CKHAVEARGS(1); pluginargs = argv[++i]; _clear_para(); } else { if ( cpi_touched && add_cpi_listen(cpi_proto, cpi_type, cpi_host, cpi_port) == -1 ) { fprintf(stderr, "Can not open socket for CPI: %s\n", roar_error2str(roar_error)); return 1; } cpi_touched = 0; if ( g_para == NULL ) g_para = roar_dl_para_new(action == RUN_AS_APPLICATION ? NULL : pluginargs, NULL, appname, abiversion); if ( action == RUN_AS_APPLICATION && _add_para(g_para, pluginargs, argc - i - 1, &(argv[i+1])) == -1 ) { fprintf(stderr, "Error parsing plugin arguments: %s\n", roar_error2str(roar_error)); } else { roar_err_set(ROAR_ERROR_NONE); if ( do_plugin(action, k, options) == -1 ) { fprintf(stderr, "Error loading plugin: %s\n", roar_error != ROAR_ERROR_NONE ? roar_error2str(roar_error) : roar_dl_errstr(NULL)); ret = 1; } } if ( action == RUN_AS_APPLICATION ) break; // end looping over arguments } } _clear_para(); roar_scheduler_unref(g_sched); return ret; } //ll roaraudio-1.0beta11/roarclients/roarradio.c0000644000175000017500000001470112264733651017146 0ustar phiphi//roarradio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define P_UNKNOWN 0 #define P_HTTP 1 #define P_GOPHER 2 void usage (void) { printf("roarradio [OPTIONS]... [FILE|URL]\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANNELS - Set number of channels\n" " --codec -E CODEC - Set the codec\n" " --aiprofile PROFILE - Set audio profile\n" " --help - Show this help\n" ); } static void die(const char * msg) { fprintf(stderr, "Fatal error: %s\n", msg); abort(); } int main (int argc, char * argv[]) { struct roar_audio_info info; const char * server = NULL; const char * k; int i; int in = -1; char * file = NULL; char * host; int port; FILE * http; struct roar_connection con[1]; struct roar_stream stream[1]; char buf0[80], buf1[80]; int proto = P_UNKNOWN; ssize_t slen; if ( roar_profile2info(&info, "default") == -1 ) return 1; info.codec = ROAR_CODEC_OGG_VORBIS; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) { ROAR_CKHAVEARGS(1); info.codec = roar_str2codec(argv[++i]); } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( file == NULL ) { file = argv[i]; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( file == NULL ) { file = "/dev/stdin"; in = ROAR_STDIN; } else { if ( strncmp(file, "http://", 7) == 0 ) { proto = P_HTTP; host = file+7; port = 80; } else if ( strncmp(file, "gopher://", 9) == 0 ) { proto = P_GOPHER; host = file+9; port = 70; } else { fprintf(stderr, "Error: unknown protocol: %s\n", file); return 20; } if ( proto == P_HTTP || proto == P_GOPHER ) { for (i = 0; host[i] != 0; i++) { if ( host[i] == ':' ) { port = atoi(host+i+1); // atoi() ignores the rest after '/' host[i] = 0; } else if ( host[i] == '/' ) { file = host+i; break; } } if ( !*file ) { file = "/"; if ( (in = roar_socket_connect(ROAR_SOCKET_TYPE_UNKNOWN, host, port)) == -1 ) { ROAR_ERR("can not connect to remote server %s (port %i): %s", host, port, strerror(errno)); return 0; } } else { *file = 0; if ( (in = roar_socket_connect(ROAR_SOCKET_TYPE_UNKNOWN, host, port)) == -1 ) { ROAR_ERR("can not connect to remote server %s (port %i): %s", host, port, strerror(errno)); return 0; } *file = '/'; } switch (proto) { case P_HTTP: if ( (http = fdopen(in, "r+")) == NULL ) { ROAR_ERR("can not create FILE* object: %s", strerror(errno)); return 0; } fprintf(http, "GET %s HTTP/1.1\r\n", file); fprintf(http, "Host: %s\r\n", host); fprintf(http, "User-Agent: roarradio $Revision: 1.22 $\r\n"); fprintf(http, "Connection: close\r\n"); fprintf(http, "\r\n"); fflush(http); if ( fscanf(http, "%79s %i %79s\n", buf0, &port, buf1) != 3 ) { ROAR_ERR("HTTP protocol error!, no initial HTTP/1.x-line!"); return 1; } if ( port != 200 ) { // 200 = HTTP OK ROAR_ERR("HTTP Error: %i - %s", port, buf1); return 1; } *buf0 = 0; while (*buf0 != '\r' && *buf0 != '\n') { if ( fgets(buf0, 80, http) == NULL ) die("Can not read header lion"); } fflush(http); break; case P_GOPHER: if ( file[0] == 0 ) { file[0] = '/'; file[1] = 0; } else if ( file[0] == '/' && file[1] != 0 && file[2] == '/' ) { // strip the type prefix file += 2; } // TODO: do some error checks here slen = strlen(file); if ( write(in, file, slen) != slen ) die("Can not write selector"); if ( write(in, "\r\n", 2) != 2 ) die("Can not write selector terminator"); ROAR_SHUTDOWN(in, SHUT_WR); break; } } else { if ( (in = open(file, O_RDONLY, 0644)) == -1 ) { ROAR_ERR("can not open file: %s: %s", file, strerror(errno)); return 1; } } } if ( in == -1 ) { ROAR_ERR("No open file, bad. This should not happen"); return 1; } if ( roar_simple_connect(con, server, "roarradio") == -1 ) { ROAR_ERR("Can not connect to server"); return 1; } if ( roar_stream_new_by_info(stream, &info) == -1 ) { roar_disconnect(con); return 1; } if ( roar_stream_connect(con, stream, ROAR_DIR_PLAY, -1) == -1 ) { roar_disconnect(con); return 1; } if ( roar_stream_passfh(con, stream, in) == -1 ) { roar_disconnect(con); return 1; } close(in); if ( roar_stream_attach_simple(con, stream, 0) == -1 ) { ROAR_ERR("Can not attach stream to server"); } roar_disconnect(con); return 0; } //ll roaraudio-1.0beta11/roarclients/roarshout.c0000644000175000017500000002100712264733651017207 0ustar phiphi//roarshout.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #ifdef ROAR_HAVE_LIBSHOUT #include #define BUFSIZE 2048 void usage (void) { printf("roarshout [OPTIONS]... [address [port [password [mountpoint]]]\n"); printf("\nRoarAudio Options:\n\n"); printf(" --server SERVER - Set server hostname\n" " -R --rate RATE - Set sample rate\n" " -B --bits BITS - Set bits per sample\n" " -C --chans CHANNELS - Set number of channels\n" " -E --codec CODEC - Set the codec\n" " --aiprofile PROFILE\n" " - Set audio profile\n" " -h --help - Show this help\n" " --pw-arg - Password is supplied as argument (default).\n" " --pw-ask - Ask user for password interactively.\n" " --pw-dstr - Read password from file. Filename is supplied\n" " as normal password argument.\n" ); printf("\nlibshout Options:\n\n"); printf(" -p --public - Allow listing in stream directory\n" " -d DESC - Set stream description\n" " -g GENRE - Set stream genre\n" " -n NAME - Set stream name\n" " -u URL - Set stream URL/homepage\n" ); } char * read_pw_from_file(char * filename, char * buffer, size_t bufferlen) { struct roar_vio_defaults def; struct roar_vio_calls file; ssize_t len; if (filename == NULL || buffer == NULL) return NULL; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 ) return NULL; if ( roar_vio_open_dstr(&file, filename, &def, 1) == -1 ) return NULL; len = roar_vio_read(&file, buffer, bufferlen - 1); if ( len == -1 ) return NULL; // strip newlions. for (; buffer[len-1] == '\r' || buffer[len-1] == '\n'; len--); buffer[len] = 0; roar_vio_close(&file); return buffer; } int main (int argc, char * argv[]) { enum { ARG, ASK, DSTR } pw_source = ARG; struct roar_audio_info info; const char * server = NULL; const char * k; const char * s_server = NULL; const char * s_mount = NULL; char * s_pw = NULL; int s_port = -1; const char * s_desc = NULL; const char * s_genre = NULL; const char * s_name = NULL; const char * s_url = NULL; int s_public = 0; roar_vs_t * vss; int err; ssize_t ret; int i; char buf[BUFSIZE]; shout_t * shout; char password_buf[128]; if ( roar_profile2info(&info, "default") == -1 ) return 1; info.codec = ROAR_CODEC_OGG_VORBIS; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) { ROAR_CKHAVEARGS(1); info.codec = roar_str2codec(argv[++i]); } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( strcmp(k, "--pw-arg") == 0 ) { pw_source = ARG; } else if ( strcmp(k, "--pw-ask") == 0 ) { pw_source = ASK; } else if ( strcmp(k, "--pw-dstr") == 0 ) { pw_source = DSTR; } else if ( strcmp(k, "-p") == 0 || strcmp(k, "--public") == 0 ) { s_public = 1; } else if ( strcmp(k, "-d") == 0 ) { ROAR_CKHAVEARGS(1); s_desc = argv[++i]; } else if ( strcmp(k, "-g") == 0 ) { ROAR_CKHAVEARGS(1); s_genre = argv[++i]; } else if ( strcmp(k, "-n") == 0 ) { ROAR_CKHAVEARGS(1); s_name = argv[++i]; } else if ( strcmp(k, "-u") == 0 ) { ROAR_CKHAVEARGS(1); s_url = argv[++i]; } else if ( strcmp(k, "-h") == 0 || strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( s_server == NULL ) { ROAR_CKHAVEARGS(1); s_server = k; } else if ( s_port == -1 ) { ROAR_CKHAVEARGS(1); s_port = atoi(k); } else if ( s_pw == NULL ) { ROAR_CKHAVEARGS(1); s_pw = argv[i]; // do not use k here so k can be const. } else if ( s_mount == NULL ) { ROAR_CKHAVEARGS(1); s_mount = k; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } switch (pw_source) { case ARG: // nothing to do break; case ASK: if ( roar_passwd_simple_ask_pw(&s_pw, "Password for icecast server?", NULL) == -1 ) { fprintf(stderr, "Error: unabled to read password from user.\n"); return 1; } strncpy(password_buf, s_pw, sizeof(password_buf)-1); roar_mm_free(s_pw); password_buf[sizeof(password_buf)-2] = 0; s_pw = password_buf; break; case DSTR: if ( (s_pw = read_pw_from_file(s_pw, password_buf, sizeof(password_buf))) == NULL ) { fprintf(stderr, "Error: unabled to read password from file.\n"); return 1; } break; } if ( s_server == NULL ) s_server = "localhost"; if ( s_mount == NULL ) s_mount = "/roar.ogg"; if ( s_pw == NULL ) s_pw = "hackme"; if ( s_port == -1 ) s_port = 8000; if ( !strcasecmp(s_pw, "hackme") ) { fprintf(stderr, "Warning: Your password is very weak. Change it!\n"); } shout_init(); if (!(shout = shout_new())) { ROAR_ERR("Can not create shout object"); return 1; } if (shout_set_host(shout, s_server) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting hostname: %s", shout_get_error(shout)); return 1; } if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting protocol: %s", shout_get_error(shout)); return 1; } if (shout_set_port(shout, s_port) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting port: %s", shout_get_error(shout)); return 1; } if (shout_set_password(shout, s_pw) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting password: %s", shout_get_error(shout)); return 1; } if (shout_set_mount(shout, s_mount) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting mount: %s", shout_get_error(shout)); return 1; } if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting user: %s", shout_get_error(shout)); return 1; } if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting format: %s", shout_get_error(shout)); return 1; } shout_set_public(shout, s_public); if (s_desc != NULL) shout_set_description(shout, s_desc); if (s_genre != NULL) shout_set_genre(shout, s_genre); if (s_name != NULL) shout_set_name(shout, s_name); if (s_url != NULL) shout_set_url(shout, s_url); if ( (vss = roar_vs_new_simple(server, "roarshout", info.rate, info.channels, info.codec, info.bits, ROAR_DIR_MONITOR, &err)) == NULL ) { fprintf(stderr, "Error: can not start monitoring: %s\n", roar_vs_strerr(err)); return 1; } if (shout_open(shout) != SHOUTERR_SUCCESS) { ROAR_ERR("Can not open connection via libshout!"); return -1; } while((ret = roar_vs_read(vss, buf, BUFSIZE, NULL))) if (shout_send(shout, (unsigned char*)buf, i) != SHOUTERR_SUCCESS) break; roar_vs_close(vss, ROAR_VS_TRUE, NULL); shout_sync(shout); shout_close(shout); shout_shutdown(); return 0; } #else int main (void) { fprintf(stderr, "No libshout support compiled in!\n"); return 1; } #endif //ll roaraudio-1.0beta11/roarclients/roarsin.c0000644000175000017500000001143412264733651016641 0ustar phiphi//roarsin.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include /* libroar */ #ifdef ROAR_HAVE_LIBM #include /* sin() */ #include /* *printf*() */ double rect (double x) { x /= 2*M_PI; x -= (int)x; if ( x < 0.5 ) return 1; else return -1; } double saw (double x) { x /= 2*M_PI; x -= (int)x; return 2*x - 1; } double tri (double x) { x /= 2*M_PI; x -= (int)x; if ( x < 0.5 ) return 4* x - 1; else return -4*(x-0.5) + 1; } double trap (double x) { x /= 2*M_PI; x -= (int)x; if ( x < 0.125 || x > 0.875 ) { return -1; } else if ( x < 0.625 && x > 0.375 ) { return 1; } else if ( x < 0.5 ) { return 8*(x-0.375) + 1; } else { return -8*(x-0.625) + 1; } } static void usage(const char * progname) { fprintf(stderr, "Usage: %s [OPTIONS] [FUNCTION]\n", progname); fprintf(stderr, "\nOptions:\n\n"); fprintf(stderr, " --help - Show this help\n" " --server SERVER - Set server address\n" " --rate -R RATE - Set sample rate to use\n" " --freq FREQ - Set frequency (in Hz)\n" " --time TIME - Set time (in sec)\n" " --volume VOL - Set volume\n" ); fprintf(stderr, "\nFunctions:\n\n"); fprintf(stderr, " --sin - Use Sinus\n" " --rect - Use Rectangle\n" " --saw - Use Saw\n" " --tri - Use Triangle\n" " --trap - Use Trap\n" ); } int main (int argc, char * argv[]) { const char * k; const char * server = NULL; int rate = ROAR_RATE_DEFAULT; float freq = 523.2; /* middle C */ float t = 0; /* current time */ float tcalc = 0; /* current time for calculation */ float length = 5; /* 5 sec */ float step; /* how much time per sample we have to encode ... */ roar_vs_t * vss; int err; int i; int16_t out[1024]; double (*func)(double x) = sin; double volume = 1; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "--freq") ) { ROAR_CKHAVEARGS(1); freq = atof(argv[++i]); } else if ( !strcmp(k, "--time") ) { ROAR_CKHAVEARGS(1); length = atof(argv[++i]); } else if ( !strcmp(k, "--server") ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( !strcmp(k, "--rate") || !strcmp(k, "-R") ) { ROAR_CKHAVEARGS(1); rate = roar_str2rate(argv[++i]); } else if ( !strcmp(k, "--volume") ) { ROAR_CKHAVEARGS(1); volume = atof(argv[++i]); } else if ( !strcmp(k, "--sin") ) { func = sin; } else if ( !strcmp(k, "--rect") ) { func = rect; } else if ( !strcmp(k, "--saw") ) { func = saw; } else if ( !strcmp(k, "--tri") ) { func = tri; } else if ( !strcmp(k, "--trap") ) { func = trap; } else if ( !strcmp(k, "--help") ) { usage(argv[0]); return 0; } else { usage(argv[0]); return 2; } } step = M_PI*2*freq/rate; if ( (vss = roar_vs_new_playback(server, "sine gen", rate, 1, ROAR_CODEC_DEFAULT, 16, &err)) == NULL ) { fprintf(stderr, "Error: can not open playback: %s\n", roar_vs_strerr(err)); exit(1); } if ( roar_vs_volume_mono(vss, volume, NULL) == 0 ) { // If setting server volume successed set local volume to one. volume = 1; } while (t < 2*M_PI*freq*length) { for (i = 0; i < 1024; i++) { out[i] = 32767.*volume*func(tcalc); t += step; tcalc += step; } if ( roar_vs_write(vss, out, 2048, &err) != (ssize_t)2048 ) { fprintf(stderr, "Error: can not write data: %s\n", roar_vs_strerr(err)); break; } // this code enables us to generate the same signal for a long periode of time // without loosing accuracy of the float type. while (tcalc > 2*M_PI) tcalc -= 2*M_PI; } roar_vs_close(vss, ROAR_VS_FALSE, NULL); return 0; } #else int main (void) { fprintf(stderr, "Error: No Math library support compiled in.\n"); return 1; } #endif //ll roaraudio-1.0beta11/roarclients/roarsockconnect.c0000644000175000017500000000305612264733651020362 0ustar phiphi//roarsockconnect.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include void usage (void) { fprintf(stderr, "Usage: roarsockconnect HOST PORT\n"); exit(1); } int main (int argc, char * argv[]) { char buf[1024]; int fh; int port; int len; roar_debug_bin_obsolete(argv[0], NULL, NULL); if ( argc != 3 ) usage(); port = atoi(argv[2]); if ( (fh = roar_socket_connect(ROAR_SOCKET_TYPE_UNKNOWN, argv[1], port)) == -1 ) { ROAR_ERR("Error: can not connect!"); return 1; } while ((len = read(ROAR_STDIN, buf, 1024))) write(fh, buf, len); while ((len = read(fh, buf, 1024))) write(ROAR_STDOUT, buf, len); return 0; } //ll roaraudio-1.0beta11/roarclients/roarsocktypes.c0000644000175000017500000000345712264733652020103 0ustar phiphi//roarsocktypes.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include static const struct { const char * name; int (*func)(void); } tests[] = { {"TCPv4" , roar_socket_new_tcp }, {"UDPv4" , roar_socket_new_udp }, {"TCPv6" , roar_socket_new_tcp6}, {"UDPv6" , roar_socket_new_udp6}, {"UNIX" , roar_socket_new_unix}, {"DECnet seqpacket", roar_socket_new_decnet_seqpacket}, {"DECnet stream" , roar_socket_new_decnet_stream}, {"IPX" , roar_socket_new_ipx}, {"IPX/SPX" , roar_socket_new_ipxspx}, {NULL, NULL} }; int main (int argc, char * argv[]) { int i, fh; roar_debug_bin_obsolete(argv[0], NULL, NULL); for (i = 0; tests[i].func; i++) { printf("Type %-16s ", tests[i].name); errno = 0; fh = tests[i].func(); if ( fh == -1 ) { printf("not working: %s\n", strerror(errno)); } else { close(fh); printf("working\n"); } } return 0; } //ll roaraudio-1.0beta11/roarclients/roartypes.c0000644000175000017500000000524612264733652017221 0ustar phiphi//roartypes.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #undef ROAR_DBG_PREFIX #include "../roard/include/roard.h" #undef ROAR_DBG_PREFIX #define ROAR_DBG_PREFIX "roartypes" int main (int argc, char * argv[]) { struct { const char * name; int len; } types[] = { // { "roar_buffer", sizeof(struct roar_buffer) }, { "roar_stack", sizeof(struct roar_stack) }, { "roar_message", sizeof(struct roar_message) }, { "roar_stream", sizeof(struct roar_stream) }, { "roar_stream_server", sizeof(struct roar_stream_server) }, { "roar_mixer_settings", sizeof(struct roar_mixer_settings) }, { "roar_sample", sizeof(struct roar_sample) }, { "roar_client", sizeof(struct roar_client) }, { "roar_client_server", sizeof(struct roar_client_server) }, { "roard_config", sizeof(struct roard_config) }, { "roar_connection", sizeof(struct roar_connection) }, { "roar_audio_info", sizeof(struct roar_audio_info) }, { "roar_meta", sizeof(struct roar_meta) }, { "roar_vio_calls", sizeof(struct roar_vio_calls) }, { "roar_stack", sizeof(struct roar_stack) }, { "roar_vio_defaults", sizeof(struct roar_vio_defaults) }, { "roar_vio_dstr_chain", sizeof(struct roar_vio_dstr_chain) }, #ifndef ROAR_WITHOUT_DCOMP_MIDI { "midi_message", sizeof(struct midi_message) }, #endif { "roar_note_octave", sizeof(struct roar_note_octave) }, { "roar_libroar_config", sizeof(struct roar_libroar_config) }, { NULL, 0 } }, * c = types - 1; (void)argc; roar_debug_bin_obsolete(argv[0], NULL, NULL); while ((++c)->name != NULL) printf("%-20s = %5i Bytes = %6i Bits\n", c->name, c->len, c->len * 8); return 0; } //ll roaraudio-1.0beta11/roarclients/roarvio.c0000644000175000017500000001515412264733652016651 0ustar phiphi//roarvio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ int g_verbose = 0; #define ROAR_DBG_INFOVAR g_verbose #include #include #include #include enum action { READ, WRITE, PASS, EXPLAIN }; void usage (const char * progname) { fprintf(stderr, "Usage: %s [OPTIONS]... FILE [FILE]\n", progname); fprintf(stderr, "\nOptions:\n\n"); fprintf(stderr, " -h --help - This help.\n" " --verbose - Be verbose. Can be used multiple times.\n" " --read - Reading mode (like 'cat file').\n" " --write - Writing mode (like 'cat > file').\n" " --pass - Passing mode (like 'cat infile > outfile').\n" " --explain - Explain VIO object.\n"); } ssize_t do_explain (struct roar_vio_calls * cur) { struct roar_sockname sockname; int have_sockname; int need_space, need_space2; int level = 0; int fh; const char * name; const char * codec; const char * content_type; while (cur != NULL) { if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_NAME, &name) == -1 ) name = "UNKNOWN"; if ( g_verbose ) { if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_MIMETYPE, &content_type) == -1 ) content_type = "UNKNOWN"; codec = roar_codec2str(roar_mime2codec(content_type)); if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_FH, &fh) == -1 ) fh = -1; if ( g_verbose > 1 ) { if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_PEERNAME, &sockname) == -1 ) { have_sockname = 0; } else { have_sockname = 1; } } else { have_sockname = 0; } } else { content_type = "UNKNOWN"; codec = "UNKNOWN"; fh = -1; have_sockname = 0; } printf("%i: %s", level, name); if ( fh != -1 || !!strcasecmp(codec, "UNKNOWN") || !!strcasecmp(content_type, "UNKNOWN") || have_sockname ) { need_space = 0; printf(" ("); if ( fh != -1 ) { printf("fh=%i", fh); need_space = 1; } if ( have_sockname ) { need_space2 = 0; printf("%ssocket={", need_space ? ", " : ""); need_space2 = 1; switch (sockname.type) { case ROAR_SOCKET_TYPE_UNIX: printf("af=UNIX"); break; case ROAR_SOCKET_TYPE_DECNET: printf("af=DECnet"); break; case ROAR_SOCKET_TYPE_INET: printf("af=INET"); break; case ROAR_SOCKET_TYPE_INET6: printf("af=INET6"); break; default: need_space2 = 0; break; } if ( sockname.addr != NULL ) { printf("%saddr=\"%s\"", need_space2 ? ", " : "", sockname.addr); need_space2 = 1; } if ( sockname.port ) { printf("%sport=%i", need_space2 ? ", " : "", sockname.port); need_space2 = 1; } printf("}"); need_space = 1; } if ( !!strcasecmp(codec, "UNKNOWN") ) { printf("%scodec=%s", need_space ? ", " : "", codec); need_space = 1; } if ( !!strcmp(content_type, "UNKNOWN") ) { printf("%scontent-type=\"%s\"", need_space ? ", " : "", content_type); need_space = 1; } printf(")"); } printf("\n"); level++; if ( have_sockname ) if ( sockname.addr != NULL ) roar_mm_free(sockname.addr); if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_NEXT, &cur) == -1 ) cur = NULL; } roar_error = ROAR_ERROR_NONE; return 0; } int main (int argc, char * argv[]) { struct roar_vio_defaults def; struct roar_vio_calls vio0, vio1; enum action action = READ; ssize_t written = -1; int i; const char * k; const char * file0 = NULL; const char * file1 = NULL; int o_flags = -1; int ret = 0; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "-h") || !strcmp(k, "--help") ) { usage(argv[0]); return 0; } else if ( !strcmp(k, "--read") ) { action = READ; } else if ( !strcmp(k, "--write") ) { action = WRITE; } else if ( !strcmp(k, "--pass") ) { action = PASS; } else if ( !strcmp(k, "--explain") ) { action = EXPLAIN; } else if ( !strcmp(k, "--verbose") ) { g_verbose++; } else if ( file0 == NULL ) { file0 = k; } else if ( file1 == NULL ) { file1 = k; } else { ROAR_ERR("Too many parameters or unknown parameter: %s", k); usage(argv[0]); return 1; } } if ( file0 == NULL ) { usage(argv[0]); return 1; } if ( (file1 != NULL && action != PASS) || (action == PASS && file1 == NULL) ) { usage(argv[0]); return 1; } switch (action) { case READ: case PASS: case EXPLAIN: o_flags = O_RDONLY; break; case WRITE: o_flags = O_WRONLY|O_CREAT|O_TRUNC; break; } if ( o_flags == -1 ) { ROAR_ERR("o_flags unset, very bad. This should never happen."); return 1; } if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, o_flags, 0644) == -1 ) { ROAR_ERR("Can not init DSTR defaults. Bad."); return 1; } if ( roar_vio_open_dstr(&vio0, file0, &def, 1) == -1 ) { ROAR_ERR("Can not open file: %s: %s", file0, roar_error2str(roar_error)); return 1; } if ( action == PASS ) { if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY|O_CREAT|O_TRUNC, 0644) == -1 ) { ROAR_ERR("Can not init DSTR defaults. Bad."); roar_vio_close(&vio0); return 1; } if ( roar_vio_open_dstr(&vio1, file1, &def, 1) == -1 ) { ROAR_ERR("Can not open file: %s: %s", file1, roar_error2str(roar_error)); roar_vio_close(&vio0); return 1; } } switch (action) { case READ: written = roar_vio_copy_data(roar_stdout, &vio0); break; case WRITE: written = roar_vio_copy_data(&vio0, roar_stdin); break; case PASS: written = roar_vio_copy_data(&vio1, &vio0); break; case EXPLAIN: if ( (written = do_explain(&vio0)) == -1 ) ret = 4; break; } if ( written == -1 ) { ROAR_ERR("Can not push data: %s", roar_error2str(roar_error)); } roar_vio_close(&vio0); if ( file1 != NULL ) roar_vio_close(&vio1); return ret; } //ll roaraudio-1.0beta11/roarclients/roarvorbis.c0000644000175000017500000002441012264733652017353 0ustar phiphi//roarvorbis.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include #include #ifdef ROAR_HAVE_LIBVORBISFILE #include #include #endif #ifdef _WIN32 #include #include #endif #define BUFSIZE 1024 void usage (void) { printf("roarvorbis [OPTIONS]... FILE\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --help - Show this help\n" " --vclt-out FILE - Writes VCLT file\n" ); } #ifdef ROAR_HAVE_LIBVORBISFILE int _g_cf_vorbis_vfvio_return_err (void) { return -1; } size_t cf_vorbis_vfvio_read (void *ptr, size_t size, size_t nmemb, void *datasource) { ssize_t r; r = roar_vio_read(datasource, ptr, size*nmemb); ROAR_DBG("cf_vorbis_vfvio_read(ptr=%p, size=%lu, nmemb=%lu, datasource=%p): r=%i", ptr, (unsigned long int)size, (unsigned long int)nmemb, datasource, r); if ( r == -1 ) return 0; if ( r > 0 ) errno = 0; r /= size; ROAR_DBG("cf_vorbis_vfvio_read(ptr=%p, size=%lu, nmemb=%lu, datasource=%p) = %i", ptr, (unsigned long int)size, (unsigned long int)nmemb, datasource, r); return r; } int cf_vorbis_vfvio_seek (void *datasource, ogg_int64_t offset, int whence) { return roar_vio_lseek(datasource, offset, whence); } long cf_vorbis_vfvio_tell (void *datasource) { return roar_vio_lseek(datasource, 0, SEEK_CUR); } ov_callbacks _g_cf_vorbis_vfvio = { .read_func = cf_vorbis_vfvio_read, .seek_func = cf_vorbis_vfvio_seek, .close_func = (int (*)(void * )) _g_cf_vorbis_vfvio_return_err, .tell_func = cf_vorbis_vfvio_tell }; int update_stream (struct roar_connection * con, roar_vs_t ** vss, OggVorbis_File * vf, const char * file, struct roar_audio_info * info, struct roar_vio_calls * vclt) { struct roar_stream * s; vorbis_info *vi = ov_info(vf, -1); int bits = 16; int codec = ROAR_CODEC_PCM_S_LE; char **ptr = ov_comment(vf, -1)->user_comments; char key[ROAR_META_MAX_NAMELEN], value[LIBROAR_BUFFER_MSGDATA] = {0}; int j, h = 0; struct roar_meta meta; static int need_new_stream = 1; int need_close = 0; int meta_ok; fprintf(stderr, "\n"); if ( vclt != NULL ) { roar_vio_printf(vclt, "AUDIOINFO=rate:%liHz, channels:%li\n", (long int)vi->rate, (long int)vi->channels); } if ( !need_new_stream ) { if ( info->rate != (uint16_t)vi->rate || info->channels != (uint16_t)vi->channels ) { need_close = 1; need_new_stream = 1; } } if ( need_new_stream ) { if ( need_close ) { roar_vs_sync(*vss, ROAR_VS_WAIT, NULL); roar_vs_close(*vss, ROAR_VS_FALSE, NULL); } fprintf(stderr, "Audio: %i channel, %liHz\n\n", vi->channels, vi->rate); info->rate = vi->rate; info->channels = vi->channels; info->bits = bits; info->codec = codec; *vss = roar_vs_new_from_con(con, NULL); if ( *vss == NULL ) { roar_disconnect(con); return -1; } if ( roar_vs_stream(*vss, info, ROAR_DIR_PLAY, NULL) == -1 ) { roar_vs_close(*vss, ROAR_VS_TRUE, NULL); roar_disconnect(con); return -1; } need_new_stream = 0; } s = roar_vs_stream_obj(*vss, NULL); meta.value = value; meta.key[0] = 0; meta.type = ROAR_META_TYPE_NONE; roar_stream_meta_set(con, s, ROAR_META_MODE_CLEAR, &meta); if ( strncmp(file, "http:", 5) == 0 ) meta.type = ROAR_META_TYPE_FILEURL; else meta.type = ROAR_META_TYPE_FILENAME; strncpy(value, file, LIBROAR_BUFFER_MSGDATA-1); value[LIBROAR_BUFFER_MSGDATA-1] = 0; roar_stream_meta_set(con, s, ROAR_META_MODE_SET, &meta); while(*ptr){ meta_ok = 1; for (j = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) { if ( j == ROAR_META_MAX_NAMELEN ) { ROAR_ERR("update_stream(*): invalid meta data: meta data key too long"); meta_ok = 0; j = 0; break; } key[j] = (*ptr)[j]; } key[j] = 0; if ( meta_ok ) { for (j++, h = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) { if ( h == LIBROAR_BUFFER_MSGDATA ) { ROAR_ERR("update_stream(*): invalid meta data: meta data value for key '%s' too long", key); meta_ok = 0; h = 0; break; } value[h++] = (*ptr)[j]; } value[h] = 0; } if ( meta_ok ) { fprintf(stderr, "Meta %-16s: %s\n", key, value); if ( vclt != NULL ) { roar_vio_printf(vclt, "%s=%s\n", key, value); } meta.type = roar_meta_inttype(key); if ( meta.type != -1 ) roar_stream_meta_set(con, s, ROAR_META_MODE_SET, &meta); } ptr++; } fprintf(stderr, "\n"); *value = 0; meta.key[0] = 0; meta.type = ROAR_META_TYPE_NONE; roar_stream_meta_set(con, s, ROAR_META_MODE_FINALIZE, &meta); if ( vclt != NULL ) { roar_vio_printf(vclt, "==\n"); } return 0; } const char * time2str(double t, char * buf, size_t len) { int h, m; if ( t < 0 ) { // strncpy(buf, "unknown", len); // return buf; *buf++ = '-'; t *= -1; } h = t / 3600; t -= h * 3600; m = t / 60; t -= m * 60; snprintf(buf, len, "%.2i:%.2i:%.2i", h, m, (int)t); return buf; } void print_time (OggVorbis_File * vf, roar_vs_t * vss, double time_total, struct roar_audio_info * info) { ssize_t pos; double time_cur; long bitrate_cur = ov_bitrate_instant(vf); float bitrate = bitrate_cur / 1000.0; char time_buf[3][10]; pos = roar_vs_position(vss, ROAR_VS_BACKEND_DEFAULT, NULL); if ( pos == -1 ) { time_cur = ov_time_tell(vf); } else { time_cur = (double)pos/(double)(info->channels*info->rate); } time2str(time_cur, time_buf[0], sizeof(time_buf[0])); if ( time_total > 0 ) { time2str(time_total-time_cur, time_buf[1], sizeof(time_buf[1])); time2str(time_total, time_buf[2], sizeof(time_buf[2])); //Time: 00:02.53 [03:26.20] of 03:28.73 (122.7 kbps) Output Buffer 43.8% fprintf(stderr, "\rTime: %s [%s] of %s (%.1f kbps) ", time_buf[0], time_buf[1], time_buf[2], bitrate); } else { fprintf(stderr, "\rTime: %s (%.1f kbps) ", time_buf[0], bitrate); } fflush(stderr); } #endif int main (int argc, char * argv[]) { #ifndef ROAR_HAVE_LIBVORBISFILE (void)argc, (void)argv; fprintf(stderr, "Error: no Vorbis support!\n"); return 1; #else struct roar_vio_calls vclt, in; struct roar_vio_defaults def; const char * file = NULL; const char * vcltfile = NULL; const char * k; int i; struct roar_connection con; roar_vs_t * vss = NULL; OggVorbis_File vf; int eof=0; int current_section = -1; int last_section = -1; struct roar_audio_info info; char pcmout[4096]; double time_total; ssize_t bits_per_sec = -1; ssize_t bits_written = -1; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); roar_libroar_set_server(argv[++i]); } else if ( strcmp(k, "--vclt-out") == 0 ) { ROAR_CKHAVEARGS(1); vcltfile = argv[++i]; } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( file == NULL ) { file = k; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( file == NULL ) { ROAR_ERR("No filename given."); return 1; } if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 ) return 1; if ( roar_vio_open_dstr(&in, file, &def, 1) == -1 ) { fprintf(stderr, "Error: can not open file: %s: %s\n", file, strerror(errno)); return 1; } if ( roar_simple_connect(&con, NULL, "roarvorbis") == -1 ) { ROAR_DBG("roar_simple_play(*): roar_simple_connect() faild!"); roar_vio_close(&in); return 1; } if ( ov_open_callbacks((void*)&in, &vf, NULL, 0, _g_cf_vorbis_vfvio) < 0 ) { // if( ov_open(in, &vf, NULL, 0) < 0 ) { fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n"); roar_disconnect(&con); roar_vio_close(&in); return 1; } time_total = ov_time_total(&vf, -1); if ( vcltfile != NULL ) { if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY|O_CREAT|O_APPEND, 0644) == -1 ) return 1; if ( roar_vio_open_dstr(&vclt, vcltfile, &def, 1) == -1 ) { fprintf(stderr, "Error: can not open file: %s: %s\n", vcltfile, strerror(errno)); roar_disconnect(&con); roar_vio_close(&in); return 1; } } // if ( update_stream(&con, &s, &out, &vf, file) == -1 ) // return 1; while (!eof) { long ret = ov_read(&vf, pcmout, sizeof(pcmout), 0, 2, 1, ¤t_section); if ( last_section != current_section ) if ( update_stream(&con, &vss, &vf, file, &info, vcltfile == NULL ? NULL : &vclt) == -1 ) { roar_vio_close(&in); if ( vcltfile != NULL ) roar_vio_close(&vclt); return 1; } bits_per_sec = roar_info2bitspersec(&info); last_section = current_section; if (ret == 0) { /* EOF */ eof = 1; } else if (ret < 0) { /* error in the stream. Not a problem, just reporting it in case we (the app) cares. In this case, we don't. */ } else { if ( roar_vs_write(vss, pcmout, ret, NULL) != (ssize_t)ret ) { fprintf(stderr, "\nError: Can not write to server.\n"); eof = 1; continue; } bits_written += ret * 8; if ( bits_written > bits_per_sec ) { bits_written = 0; print_time(&vf, vss, time_total, &info); } } } fprintf(stderr, "\n"); // end the lion of print_time(). ov_clear(&vf); // fclose(in); roar_vs_close(vss, ROAR_VS_FALSE, NULL); roar_disconnect(&con); if ( vcltfile != NULL ) roar_vio_close(&vclt); roar_vio_close(&in); return 0; #endif } //ll roaraudio-1.0beta11/roarclients/roarvumeter.c0000644000175000017500000001767112264733652017551 0ustar phiphi//roarvumeter.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #ifdef ROAR_HAVE_LIBM #include #define BUFSIZE 1024 #define LOWPASS_ORDER 6 #define MODE_NONE 0x00 #define MODE_PC 0x01 #define MODE_DB 0x02 #define MODE_BEAT 0x04 void usage (void) { printf("roarvumeter [OPTIONS]...\n"); printf("\nOptions:\n\n"); printf(" --server SERVER - Set server hostname\n" " --rate -R RATE - Set sample rate\n" " --bits -B BITS - Set bits per sample\n" " --chans -C CHANS - Set number of channels\n" " --aiprofile PROFILE - Set audio profile\n" " --samples SAMPLES - Set number of input samples per block\n" " --pc - Use percent scale\n" " --db - Use dB scale\n" " --beat - Enable beat detection\n" " --lowpass FREQ - Use lowpass to filter input (-%idB/dec)\n" " --help - Show this help\n", LOWPASS_ORDER * 20 ); } int vumeter16bit2ch (struct roar_vio_calls * vio, int samples, int16_t * buf, int mode, struct roardsp_filterchain * fc) { struct roar_stream beat_stream[1]; struct roardsp_filter beat_lp[1]; float beat_lpfreq = 1; int i; int samples_half = samples/2; int64_t suml, sumr; double rmsl, rmsr; int run_filters = roardsp_fchain_num(fc); int beat_detection = mode & MODE_BEAT; char * beat[2] = {" ", "Beat!"}; char * dbeat = beat[0]; int have_beat = 0; int16_t beat_val, beat_old; if ( beat_detection ) { mode -= MODE_BEAT; roar_stream_new(beat_stream, 10, 1, 16, ROAR_CODEC_PCM); roardsp_filter_init(beat_lp, beat_stream, ROARDSP_FILTER_LOWP); roardsp_filter_ctl(beat_lp, ROARDSP_FCTL_FREQ, &beat_lpfreq); } printf("\e[s"); fflush(stdout); while (roar_vio_read(vio, buf, samples * 2) > 0) { suml = sumr = 0; if ( run_filters ) { roardsp_fchain_calc(fc, buf, samples * 2); } for (i = 0; i < samples; i += 2) { suml += (int64_t) buf[i ] * (int64_t) buf[i ]; sumr += (int64_t) buf[i+1] * (int64_t) buf[i+1]; } rmsl = sqrt((double)suml/(double)samples_half); rmsr = sqrt((double)sumr/(double)samples_half); if ( beat_detection ) { beat_old = beat_val = (rmsl + rmsr) / 2; roardsp_filter_calc(beat_lp, &beat_val, 2); if ( (float)beat_old > (float)beat_val*1.1f ) { dbeat = beat[1]; have_beat = 1; } else { dbeat = beat[0]; have_beat = 0; } } switch (mode) { case MODE_NONE: // beat only if ( have_beat ) printf("%s\n", dbeat); break; case MODE_PC: printf("L: %3i%% R: %3i%% %s \e[u", (int)(rmsl/327.68), (int)(rmsr/327.68), dbeat); break; case MODE_DB: printf("L: %6.2fdB R: %6.2fdB %s \e[u", 20*log10(rmsl/32768.), 20*log10(rmsr/32768.), dbeat); break; } fflush(stdout); } if ( beat_detection ) { roardsp_filter_uninit(beat_lp); } return 0; } int vumeter (struct roar_vio_calls * vio, int samples, int bits, int channels, int mode, struct roardsp_filterchain * fc) { void * buf = roar_mm_malloc((samples*bits*channels)/8); if ( buf == NULL ) return -1; if ( bits == 16 ) { if ( channels == 2 ) { vumeter16bit2ch(vio, samples, (int16_t *) buf, mode, fc); roar_mm_free(buf); return 0; } else { roar_mm_free(buf); return -1; } } else { roar_mm_free(buf); return -1; } } int main (int argc, char * argv[]) { struct roar_connection con; struct roar_stream s; struct roardsp_filterchain fchain; struct roardsp_filter * filter; float lowpass_freq = 0; struct roar_audio_info info; int samples = -1; const char * server = NULL; const char * k; struct roar_vio_calls stream, re; int i; int mode = 0; if ( roar_profile2info(&info, "default") == -1 ) return 1; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { ROAR_CKHAVEARGS(1); server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) { ROAR_CKHAVEARGS(1); info.rate = roar_str2rate(argv[++i]); } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) { ROAR_CKHAVEARGS(1); info.bits = roar_str2bits(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) { ROAR_CKHAVEARGS(1); info.channels = roar_str2channels(argv[++i]); } else if ( !strcmp(k, "--aiprofile") ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&info, argv[++i]) == -1 ) { fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error)); return 1; } } else if ( strcmp(k, "--samples") == 0 ) { ROAR_CKHAVEARGS(1); samples = atoi(argv[++i]); } else if ( strcmp(k, "--db") == 0 ) { mode |= MODE_PC; mode -= MODE_PC; mode |= MODE_DB; } else if ( strcmp(k, "--pc") == 0 ) { mode |= MODE_DB; mode -= MODE_DB; mode |= MODE_PC; } else if ( strcmp(k, "--beat") == 0 ) { mode |= MODE_BEAT; } else if ( strcmp(k, "--lowpass") == 0 ) { ROAR_CKHAVEARGS(1); lowpass_freq = atof(argv[++i]); } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( !mode ) mode = MODE_PC; if ( samples == -1 ) samples = info.rate/10; if ( roar_simple_connect(&con, server, "roarvumeter") == -1 ) { fprintf(stderr, "Error: can not connect to server!\n"); return 1; } if ( roar_vio_simple_new_stream_obj(&stream, &con, &s, info.rate, info.channels, info.bits, ROAR_CODEC_DEFAULT, ROAR_DIR_MONITOR, -1) == -1) { fprintf(stderr, "Error: can not start monetoring\n"); return 1; } if ( roar_vio_open_re(&re, &stream) == -1 ) { roar_vio_close(&stream); fprintf(stderr, "Error: can not open RE VIO layer\n"); return 1; } if ( roardsp_fchain_init(&fchain) == -1 ) { roar_vio_close(&re); fprintf(stderr, "Error: can not init filterchain\n"); return 1; } if ( lowpass_freq > 1 ) { for (i = 0; i < LOWPASS_ORDER; i++) { if ( roardsp_filter_new(&filter, &s, ROARDSP_FILTER_LOWP) == -1 ) { fprintf(stderr, "Error: can not open lowpass\n"); roar_vio_close(&re); roardsp_fchain_uninit(&fchain); return 1; } if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_FREQ, &lowpass_freq) == -1 ) { fprintf(stderr, "Error: can not set filter frequency\n"); roar_vio_close(&re); roardsp_fchain_uninit(&fchain); return 1; } if ( roardsp_fchain_add(&fchain, filter) == -1 ) { fprintf(stderr, "Error: can not set filter frequency\n"); roar_vio_close(&re); roardsp_fchain_uninit(&fchain); return 1; } } } vumeter(&re, samples*info.channels, info.bits, info.channels, mode, &fchain); printf("\n"); // if the reach this then roard has quited and we should print a newline roar_vio_close(&re); roar_disconnect(&con); roardsp_fchain_uninit(&fchain); return 0; } #else int main (void) { fprintf(stderr, "Error: No Math library support compiled in.\n"); return 1; } #endif //ll roaraudio-1.0beta11/roarclients/zcattest.c0000644000175000017500000000264612264733652017033 0ustar phiphi//zcattest.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #define BUF_MAX 1024 int main (void) { char buf[BUF_MAX]; size_t len; struct roar_vio_calls file, zcat; if ( roar_vio_open_fh(&file, ROAR_STDIN) == -1 ) { ROAR_ERR("roar_vio_open_fh(&file, ROAR_STDIN) = -1"); return 1; } if ( roar_vio_open_gzip(&zcat, &file, -1) == -1 ) { ROAR_ERR("roar_vio_open_gzip(&zcat, &file, -1) = -1"); return 1; } while ((len = roar_vio_read(&zcat, buf, BUF_MAX))) write(ROAR_STDOUT, buf, len); roar_vio_close(&zcat); return 0; } //ll roaraudio-1.0beta11/roard/0000755000175000017500000000000012267553244013600 5ustar phiphiroaraudio-1.0beta11/roard/include/0000755000175000017500000000000012267553244015223 5ustar phiphiroaraudio-1.0beta11/roard/include/auth.h0000644000175000017500000000421012264733701016325 0ustar phiphi//auth.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _AUTH_H_ #define _AUTH_H_ #include #define AT_TRUST_MAX_ENTRYS 8 #define AUTH_KEYRING_LEN 8 struct at_none { char dummy; }; struct at_cookie { char * cookie; size_t len; }; struct at_trust { pid_t pids[AT_TRUST_MAX_ENTRYS]; uid_t uids[AT_TRUST_MAX_ENTRYS]; gid_t gids[AT_TRUST_MAX_ENTRYS]; size_t pids_len, uids_len, gids_len; }; struct at_password { const char * password; }; union auth_typeunion { struct at_none none; struct at_cookie cookie; struct at_trust trust; struct at_password password; }; struct auth_key { int type; enum roard_client_acclev acclev; union auth_typeunion at_data; }; extern struct auth_key g_auth_keyring[AUTH_KEYRING_LEN]; int auth_init (void); int auth_free (void); union auth_typeunion * auth_regkey_simple(int type, enum roard_client_acclev acclev); int auth_client_ckeck(struct roar_client_server * cs, struct roar_auth_message * authmes, int * next); int auth_addkey_anonymous(enum roard_client_acclev acclev); int auth_addkey_password(enum roard_client_acclev acclev, const char * password); int auth_addkey_cookie(enum roard_client_acclev acclev, const void * cookie, const size_t len); int auth_addkey_trust(enum roard_client_acclev acclev, ...); #endif //ll roaraudio-1.0beta11/roard/include/beep.h0000644000175000017500000000203312264733701016300 0ustar phiphi//beep.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _BEEP_H_ #define _BEEP_H_ #include int beep_start (int client, struct roar_beep * beep); #endif //ll roaraudio-1.0beta11/roard/include/caps.h0000644000175000017500000000204612264733701016317 0ustar phiphi//caps.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CAPS_H_ #define _CAPS_H_ #include extern struct roar_stds g_caps_stds; char * stds_string (void); #endif //ll roaraudio-1.0beta11/roard/include/client.h0000644000175000017500000001243212264733701016647 0ustar phiphi//client.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CLIENT_H_ #define _CLIENT_H_ /* Defined in #define ROAR_BUFFER_NAME 80 #define ROAR_CLIENTS_MAX 64 #define ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT 4 struct roar_client { int fh; /-* controll connection *-/ // int last_stream; /-* id of the last stream created *-/ char name[ROAR_BUFFER_NAME]; int pid; char host[ROAR_BUFFER_NAME]; int execed; int streams[ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT]; } * g_clients[ROAR_CLIENTS_MAX]; */ // access level: enum roard_client_acclev { ACCLEV_ERROR = -1, // used as erorr return value. ACCLEV_NONE = 0, // only very basic commands like NOOP and IDENTIFY ACCLEV_IDENTED, // same as NONE but INDENTIFY worked. ACCLEV_CONCTL, // only allowed to do basic connection things. ACCLEV_GUEST, // guest connection (read only) ACCLEV_USER, // normal user connect (read write) ACCLEV_PWRUSER, // power user, may access other user's clients ACCLEV_ALL // full (admin) access (read write ctl) }; struct roar_client_nsubscribe { struct roar_subscriber * sub; }; extern struct roar_client_server { struct roar_client _client; size_t blockc; struct roar_subscriber ** waits; enum roard_client_acclev acclev; // may be used by protocols working directly on big data blocks to buffer a bit: struct roar_buffer * inbuf, * outbuf; void * protoinst; } * g_clients[ROAR_CLIENTS_MAX]; struct roard_listen; struct roard_proto { int proto; int subsystems; const char * description; struct roar_dl_lhandle * lhandle; int (*new_client)(int client, struct roar_vio_calls * vio, struct roard_listen * lsock); int (*delete_client)(int client); int (*check_client)(int client, struct roar_vio_calls * vio); int (*flush_client)(int client, struct roar_vio_calls * vio); int (*flushed_client)(int client, struct roar_vio_calls * vio); }; enum roard_proto_type { ROARD_PROTO_TYPE_BUILDIN = 0, // ROARD_PROTO_TYPE_ROARDPROTO = 1, // old. Removed in 1.0beta6. ROARD_PROTO_TYPE_COMMON = 2 }; struct roard_proto_handle { int proto; struct roar_dl_lhandle * lhandle; enum roard_proto_type type; const struct roar_keyval * para; ssize_t paralen; union { int buildin; // dummy const struct roar_dl_proto * common; } impl; }; #define MAX_PROTOS 16 // basic functions int clients_init (void); int clients_free (void); int clients_new (void); int clients_new_from_fh(int fh, int proto, int byteorder, int update_nnode); int clients_new_from_fh2(int fh, int proto, int byteorder, int update_nnode, struct roard_listen * lsock, struct sockaddr * sockaddr, socklen_t addrlen); int clients_delete (int id); int clients_close (int id, int nocheck_exec); int clients_set_fh (int id, int fh); int clients_set_pid (int id, int pid); int clients_set_uid (int id, int uid); int clients_set_gid (int id, int gid); int clients_set_name (int id, const char * name); int clients_set_proto (int id, int proto); int clients_get (int id, struct roar_client ** client); int clients_get_server (int id, struct roar_client_server ** client); int clients_get_fh (int id); int clients_block (int id, int unblock); // network functions int clients_check_all (void); int clients_check (int id); int clients_flush (int id); int clients_send_mon (struct roar_audio_info * sa); int clients_send_filter(struct roar_audio_info * sa); int clients_add_output (int id, struct roar_buffer ** buf); // proto support const struct roard_proto_handle * clients_get_protohandle(const int proto); int clients_register_proto_common(const struct roar_dl_proto * proto, struct roar_dl_lhandle * lhandle); int clients_unregister_proto(int proto); void print_protolist (enum output_format format); // stream functions int client_stream_exec (int client, int stream); int client_stream_set_fh (int client, int stream, int fh); int client_stream_add (int client, int stream); int client_stream_delete (int client, int stream); int client_stream_move (int client, int stream); // notify thingys int clients_wait (int client, struct roar_event * events, size_t num); void clients_ncb_wait(struct roar_notify_core * core, struct roar_event * event, void * userdata); // acclev: enum roard_client_acclev clients_str2acclev(const char * acclev); const char * clients_acclev2str(const enum roard_client_acclev acclev); #endif //ll roaraudio-1.0beta11/roard/include/codecfilter.h0000644000175000017500000001406112264733702017655 0ustar phiphi//codecfilter.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_H_ #define _CODECFILTER_H_ #include #define CODECFILTER_USERDATA_T void * struct roar_stream_server; #define ROAR_CODECFILTER_NONE 0x00 #define ROAR_CODECFILTER_READ 0x01 #define ROAR_CODECFILTER_WRITE 0x02 #define ROAR_CODECFILTER_PRETHRU 0x04 /* we have support for prethru */ #define ROAR_CODECFILTER_PRETHRU_NN 0x08 /* prethru Not Needed */ #define ROAR_CODECFILTER_CTL_NOOP ROAR_STREAM_CTL_COMP_CF|0x0000 /* noop... */ #define ROAR_CODECFILTER_CTL_BASE ROAR_STREAM_CTL_COMP_CF|0x0000 /* Base ops... */ #define ROAR_CODECFILTER_CTL_META ROAR_STREAM_CTL_COMP_CF|0x1000 /* Meta data things... */ #define ROAR_CODECFILTER_CTL_VIRTUAL ROAR_STREAM_CTL_COMP_CF|0x2000 /* container/virtual stream things... */ #define ROAR_CODECFILTER_CTL_SET 0x0002 #define ROAR_CODECFILTER_CTL_GET 0x0003 #define ROAR_CODECFILTER_CTL_UPDATE 0x0001 #define ROAR_CODECFILTER_CTL_DELETE 0x0004 #define ROAR_CODECFILTER_CTL_NEW 0x0005 #define ROAR_CODECFILTER_CTL_Q 0x0010 #define ROAR_CODECFILTER_CTL_SET_Q ROAR_CODECFILTER_CTL_BASE|ROAR_CODECFILTER_CTL_Q|ROAR_CODECFILTER_CTL_SET #define ROAR_CODECFILTER_CTL_GET_Q ROAR_CODECFILTER_CTL_BASE|ROAR_CODECFILTER_CTL_Q|ROAR_CODECFILTER_CTL_GET #define ROAR_CODECFILTER_CTL_META_UPDATE ROAR_CODECFILTER_CTL_META|ROAR_CODECFILTER_CTL_UPDATE #define ROAR_CODECFILTER_CTL_VIRTUAL_DELETE ROAR_CODECFILTER_CTL_VIRTUAL|ROAR_CODECFILTER_CTL_DELETE #define ROAR_CODECFILTER_CTL_VIRTUAL_NEW ROAR_CODECFILTER_CTL_VIRTUAL|ROAR_CODECFILTER_CTL_NEW #define ROAR_CODECFILTER_CTL2CMD(x) ((x) & (~ROAR_STREAM_CTL_COMP_CF)) struct roar_codecfilter { int codec; char * name; char * desc; char * options; void * setup; int flags; unsigned int subsystems; int (*open )(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int (*close)(CODECFILTER_USERDATA_T inst); int (*pause)(CODECFILTER_USERDATA_T inst, int newstate); int (*write)(CODECFILTER_USERDATA_T inst, char * buf, int len); int (*read )(CODECFILTER_USERDATA_T inst, char * buf, int len); int (*flush)(CODECFILTER_USERDATA_T inst); int (*delay)(CODECFILTER_USERDATA_T inst, uint_least32_t * delay); int (*ctl )(CODECFILTER_USERDATA_T inst, int cmd, void * data); }; #include "codecfilter_cmd.h" #include "codecfilter_wave.h" #include "codecfilter_au.h" #ifdef ROAR_HAVE_LIBVORBISFILE #include "codecfilter_vorbis.h" #endif #ifdef ROAR_HAVE_LIBCELT #include "codecfilter_celt.h" #endif #ifdef ROAR_HAVE_LIBSPEEX #include "codecfilter_speex.h" #endif #ifdef ROAR_HAVE_LIBSNDFILE #include "codecfilter_sndfile.h" #endif #ifdef ROAR_HAVE_LIBFISHSOUND #include "codecfilter_fishsound.h" #endif #ifdef ROAR_HAVE_LIBFLAC #include "codecfilter_flac.h" #endif #ifdef ROAR_HAVE_LIBUNIRAUM #include "codecfilter_uniraum.h" #endif #include "container_framework.h" //cf alaw/mulaw: #include void print_codecfilterlist (void); int codecfilter_open (CODECFILTER_USERDATA_T * inst, int * codecfilter_id, char * codecfilter /* NOTE: this is not part of struct roar_codecfilter's def! */, int codec, struct roar_stream_server * info); int codecfilter_close(CODECFILTER_USERDATA_T inst, int codecfilter); int codecfilter_pause(CODECFILTER_USERDATA_T inst, int codecfilter, int newstate); int codecfilter_write(CODECFILTER_USERDATA_T inst, int codecfilter, char * buf, int len); int codecfilter_read (CODECFILTER_USERDATA_T inst, int codecfilter, char * buf, int len); int codecfilter_flush(CODECFILTER_USERDATA_T inst, int codecfilter); int codecfilter_delay(CODECFILTER_USERDATA_T inst, int codecfilter, uint_least32_t * delay); int codecfilter_ctl (CODECFILTER_USERDATA_T inst, int codecfilter, int_least32_t cmd, void * data); int codecfilter_delay_fulldyn(CODECFILTER_USERDATA_T inst, uint_least32_t * delay); int codecfilter_delay_zero(CODECFILTER_USERDATA_T inst, uint_least32_t * delay); // codecfilter without a own .h: int cf_alaw_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_alaw_close(CODECFILTER_USERDATA_T inst); int cf_alaw_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_alaw_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_mulaw_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_mulaw_close(CODECFILTER_USERDATA_T inst); int cf_mulaw_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_mulaw_write(CODECFILTER_USERDATA_T inst, char * buf, int len); // cf_mulaw_delay() would be exactly the same as cf_alaw_delay() so it is just used by mulaw, too. CONT_FW_SETUP_TYPE(cf_raum_setup); #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_au.h0000644000175000017500000000411712264733702020343 0ustar phiphi//codecfilter_au.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_AU_H_ #define _CODECFILTER_AU_H_ #include #ifndef ROAR_WITHOUT_CF_AU #define ROAR_AU_MIN_HEADER_LEN (6*4) #define ROAR_AU_MAGIC 0x2e736e64 #define ROAR_AU_DATASIZE 0xffffffff // most important codec IDs: #define ROAR_AU_CID_MULAW 0x00000001 #define ROAR_AU_CID_PCM_S_8 0x00000002 #define ROAR_AU_CID_PCM_S_16 0x00000003 #define ROAR_AU_CID_PCM_S_24 0x00000004 #define ROAR_AU_CID_PCM_S_32 0x00000005 #define ROAR_AU_CID_ALAW 0x00000033 struct codecfilter_au_inst { struct roar_stream_server * stream; struct roar_stream_server * vstream; int opened; }; int cf_au_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_au_close(CODECFILTER_USERDATA_T inst); int cf_au_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_au_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_au_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data); #endif #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_celt.h0000644000175000017500000000370512264733703020670 0ustar phiphi//codecfilter_celt.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_CELT_H_ #define _CODECFILTER_CELT_H_ #include #ifdef ROAR_HAVE_LIBCELT #include #include struct codecfilter_celt_inst { struct roar_stream_server * stream; CELTMode * mode; CELTEncoder * encoder; CELTDecoder * decoder; int frame_size; int lookahead; int out_size; char * ibuf; char * obuf; char * i_rest; char * o_rest; int s_buf; int fi_rest; /* how much is in rest? */ int fo_rest; /* how much is in rest? */ int opened_encoder; int opened_decoder; }; int cf_celt_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_celt_close(CODECFILTER_USERDATA_T inst); int cf_celt_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_celt_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_celt_delay(CODECFILTER_USERDATA_T inst, uint_least32_t * delay); #endif #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_cmd.h0000644000175000017500000000234112264733703020477 0ustar phiphi//codecfilter_cmd.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_CMD_H_ #define _CODECFILTER_CMD_H_ #include int cf_cmd_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_fishsound.h0000644000175000017500000000315012264733704021736 0ustar phiphi//codecfilter_fishsound.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_FISHSOUND_H_ #define _CODECFILTER_FISHSOUND_H_ #include #include #include struct codecfilter_fishsound_inst { struct roar_stream_server * stream; int opened; FishSoundInfo fsinfo; FishSound * fsound; OGGZ * oggz; struct roar_buffer * buffer; }; int cf_fishsound_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_fishsound_close(CODECFILTER_USERDATA_T inst); int cf_fishsound_read(CODECFILTER_USERDATA_T inst, char * buf, int len); #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_flac.h0000644000175000017500000000440712264733704020647 0ustar phiphi//codecfilter_flac.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_FLAC_H_ #define _CODECFILTER_FLAC_H_ #include #if defined(ROAR_HAVE_LIBFLAC) #include struct codecfilter_flac_inst { struct roar_stream_server * ss; struct { FLAC__StreamDecoder * decoder; struct roar_buffer * written; ssize_t readret; size_t readc; } decoder; }; FLAC__StreamDecoderReadStatus cf_flac_cb_read(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); FLAC__StreamDecoderWriteStatus cf_flac_cb_write(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); void cf_flac_cb_metadata(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); void cf_flac_cb_error(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); int cf_flac_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_flac_close(CODECFILTER_USERDATA_T inst); int cf_flac_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_flac_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_flac_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data); #endif #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_sndfile.h0000644000175000017500000000317412264733705021367 0ustar phiphi//codecfilter_sndfile.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_SNDFILE_H_ #define _CODECFILTER_SNDFILE_H_ #include #ifdef ROAR_HAVE_LIBSNDFILE #include struct codecfilter_sndfile_inst { struct roar_stream_server * stream; int opened; int bytes; SNDFILE * state; SF_INFO info; }; int cf_sndfile_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_sndfile_close(CODECFILTER_USERDATA_T inst); int cf_sndfile_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_sndfile_write(CODECFILTER_USERDATA_T inst, char * buf, int len); #endif #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_speex.h0000644000175000017500000000415712264733705021071 0ustar phiphi//codecfilter_speex.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_SPEEX_H_ #define _CODECFILTER_SPEEX_H_ #include #include #include #include struct codecfilter_speex_inst { void * encoder; void * decoder; SpeexBits bits; SpeexStereoState stereo_state; SpeexCallback stereo_callback; int stereo; struct roar_stream_server * stream; int frame_size; void * cd; /* current data */ char cc[ROAR_SPEEX_MAX_CC]; /* buffer for read() and write() */ void * i_rest; /* rest... */ int fi_rest; char * o_rest; int fo_rest; /* how much is in rest? */ /* char * ibuf; char * obuf; int out_size; char * i_rest; int s_buf; int fi_rest; /-* how much is in rest? *-/ */ struct roar_libroar_config_codec * codec_config; }; int cf_speex_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_speex_close(CODECFILTER_USERDATA_T inst); int cf_speex_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_speex_write(CODECFILTER_USERDATA_T inst, char * buf, int len); #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_uniraum.h0000644000175000017500000000330312264733706021416 0ustar phiphi//codecfilter_uniraum.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_UNIRAUM_H_ #define _CODECFILTER_UNIRAUM_H_ #include #ifdef ROAR_HAVE_LIBUNIRAUM int cf_uniraum_open (CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_uniraum_close(CODECFILTER_USERDATA_T inst); //int cf_uniraum_pause(CODECFILTER_USERDATA_T inst, int newstate); int cf_uniraum_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_uniraum_read (CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_uniraum_flush(CODECFILTER_USERDATA_T inst); //int cf_uniraum_delay(CODECFILTER_USERDATA_T inst, uint_least32_t * delay); int cf_uniraum_ctl (CODECFILTER_USERDATA_T inst, int cmd, void * data); #endif #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_vorbis.h0000644000175000017500000000503112264733706021242 0ustar phiphi//codecfilter_vorbis.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_VORBIS_H_ #define _CODECFILTER_VORBIS_H_ #include #if defined(ROAR_HAVE_LIBVORBISFILE) && defined(ROAR_REQUIRE_LIBVORBISFILE) #include #include #include #ifdef ROAR_HAVE_LIBVORBISENC #include #endif struct codecfilter_vorbis_inst { int current_section; int last_section; int opened; struct roar_stream_server * stream; OggVorbis_File vf; int got_it_running; int bigendianp; #ifdef ROAR_HAVE_LIBVORBISENC int encoding; struct { int srn; float v_base_quality; ogg_stream_state os; ogg_page og; ogg_packet op; vorbis_dsp_state vd; vorbis_block vb; vorbis_info vi; vorbis_comment vc; } encoder; #endif }; size_t cf_vorbis_vfvio_read (void *ptr, size_t size, size_t nmemb, void *datasource); int cf_vorbis_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_vorbis_close(CODECFILTER_USERDATA_T inst); int cf_vorbis_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_vorbis_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_vorbis_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data); int cf_vorbis_update_stream (struct codecfilter_vorbis_inst * self); int cf_vorbis_encode_start (struct codecfilter_vorbis_inst * self); int cf_vorbis_encode_end (struct codecfilter_vorbis_inst * self); int cf_vorbis_encode_flushout(struct codecfilter_vorbis_inst * self); #endif #endif //ll roaraudio-1.0beta11/roard/include/codecfilter_wave.h0000644000175000017500000000440012264733706020677 0ustar phiphi//codecfilter_wave.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CODECFILTER_WAVE_H_ #define _CODECFILTER_WAVE_H_ #include #ifndef ROAR_WITHOUT_CF_WAVE // most important codec IDs: #define ROAR_RIFF_WAVE_CID_PCM 0x0001 #define ROAR_RIFF_WAVE_CID_IEEE_FLOAT 0x0003 #define ROAR_RIFF_WAVE_CID_ALAW 0x0006 #define ROAR_RIFF_WAVE_CID_MULAW 0x0007 // Invalid but used by RSound: #define ROAR_RIFF_WAVE_CID_RSOUND 0x0000 // Type is encoded in length by RSound using the following values: #define ROAR_RIFF_WAVE_RSID_S16_LE 0x0001 #define ROAR_RIFF_WAVE_RSID_S16_BE 0x0002 #define ROAR_RIFF_WAVE_RSID_U16_LE 0x0004 #define ROAR_RIFF_WAVE_RSID_U16_BE 0x0008 #define ROAR_RIFF_WAVE_RSID_U8 0x0010 #define ROAR_RIFF_WAVE_RSID_S8 0x0020 struct codecfilter_wave_inst { struct roar_stream_server * stream; struct roar_stream_server * vstream; int opened; }; int cf_wave_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cf_wave_close(CODECFILTER_USERDATA_T inst); int cf_wave_read(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_wave_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_wave_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data); #endif #endif //ll roaraudio-1.0beta11/roard/include/commands.h0000644000175000017500000000344212264733707017201 0ustar phiphi//commands.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. nd_exec* */ #ifndef _COMMANDS_H_ #define _COMMANDS_H_ #include #define COMMAND_MAX_NAMELEN 80 #define COMMAND_MAX_COMMANDS 48 #define COMMAND_FLAG_NONE 0x00000000 #define COMMAND_FLAG_OUT_CLOSECON 0x00000001 #define COMMAND_FLAG_OUT_LONGDATA 0x00000002 #define COMMAND_FLAG_OUT_NOSEND 0x00000004 #define COMMAND_FLAG_OUT_DELETE 0x00000008 /* delete the client */ struct roar_command { int cmd; #if !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_MINIMAL) const char name[COMMAND_MAX_NAMELEN]; #else const char * name; #endif int (*handler)(int client, struct roar_message * mes, char ** data, uint32_t flags[2]); enum roard_client_acclev minacclev; }; int command_get_id_by_cmd (int command); int command_exec (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int command_get_name (int command, const char ** name); #endif //ll roaraudio-1.0beta11/roard/include/container_framework.h0000644000175000017500000001107512264733707021440 0ustar phiphi//container_framework.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _CONTAINER_FRAMEWORK_H_ #define _CONTAINER_FRAMEWORK_H_ #include #define CONT_FW_MAX_CHILDS 8 #define CONT_FW_SETUP_TYPE(f) int (f)(struct cont_fw_parent_inst * self, int codec, struct roar_codecfilter * filter) struct cont_fw_parent_inst; struct cont_fw_child_vio_inst { int child; void * u_inst; struct cont_fw_parent_inst * parent; }; struct cont_fw_parent_inst { struct cont_fw_child_vio_inst * child[CONT_FW_MAX_CHILDS]; void * u_inst; int state; struct roar_vio_calls vio; struct { int id; int codec; struct roar_stream_server * stream; struct roar_codecfilter * filter; } stream; struct { ssize_t (*read) (struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child, void *buf, size_t len); ssize_t (*write)(struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child, void *buf, size_t len); int (*flush)(struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child); int (*close)(struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child); } ccb; struct { int (*open )(struct cont_fw_parent_inst * self, int codec, struct roar_stream_server * stream, struct roar_codecfilter * filter); int (*close )(struct cont_fw_parent_inst * self); int (*flush )(struct cont_fw_parent_inst * self); int (*new_child)(struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child); } pcb; }; // Parent: int cont_fw_new (struct cont_fw_parent_inst ** inst); int cont_fw_delete (struct cont_fw_parent_inst * inst); int cont_fw_set_uinst(struct cont_fw_parent_inst * inst, void * u_inst); int cont_fw_get_uinst(struct cont_fw_parent_inst * inst, void ** u_inst); // Child: int cont_fw_new_child(struct cont_fw_parent_inst * inst, int id); int cont_fw_init_vio(struct roar_vio_calls * vio, void * inst); // VIO Childs: ssize_t cont_fw_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t cont_fw_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t cont_fw_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int cont_fw_sync (struct roar_vio_calls * vio); int cont_fw_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int cont_fw_close (struct roar_vio_calls * vio); // VIO Parent: int cont_pvio_open (struct roar_vio_calls * vio, void * inst); ssize_t cont_pvio_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t cont_pvio_write (struct roar_vio_calls * vio, void *buf, size_t count); roar_off_t cont_pvio_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int cont_pvio_sync (struct roar_vio_calls * vio); int cont_pvio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int cont_pvio_close (struct roar_vio_calls * vio); // CF: int cont_fw_cf_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter); int cont_fw_cf_close(CODECFILTER_USERDATA_T inst); int cont_fw_cf_pause(CODECFILTER_USERDATA_T inst, int newstate); int cont_fw_cf_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cont_fw_cf_read (CODECFILTER_USERDATA_T inst, char * buf, int len); int cont_fw_cf_flush(CODECFILTER_USERDATA_T inst); int cont_fw_cf_delay(CODECFILTER_USERDATA_T inst, uint_least32_t * delay); int cont_fw_cf_ctl (CODECFILTER_USERDATA_T inst, int cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/include/driver.h0000644000175000017500000001106712264733710016667 0ustar phiphi//driver.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_H_ #define _DRIVER_H_ #include #define DRIVER_USERDATA_T void * #ifdef ROAR_HAVE_ESD #include #include "driver_esd.h" #endif #include "driver_roar.h" #include "driver_dstr.h" #include "driver_dmx.h" #include "driver_pwmled.h" #if defined(ROAR_HAVE_GETTIMEOFDAY) && defined(ROAR_HAVE_USLEEP) #define ROAR_HAVE_DRIVER_SYSCLOCK #include "driver_sysclock.h" #endif #ifdef ROAR_HAVE_LIBAO #include #include "driver_ao.h" #endif #ifdef ROAR_HAVE_LIBSHOUT #include #include "driver_shout.h" #endif #ifdef ROAR_HAVE_LIBSNDIO #include #include "driver_sndio.h" #endif #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) #if defined(__OpenBSD__) || defined(__NetBSD__) #include #else #include #endif #include #include "driver_oss.h" #endif #ifdef ROAR_HAVE_LIBRSOUND #ifdef _DRV_NEED_RSOUND_H #include #endif #include "driver_rsound.h" #endif #ifdef ROAR_HAVE_LIBPORTAUDIO #include #ifdef ROAR_HAVE_LIBPABLIO #include #endif #include "driver_portaudio.h" #endif #ifdef ROAR_HAVE_LIBASOUND #include #include "driver_alsa.h" #endif #ifdef ROAR_HAVE_LIBWINMM #include #include #include "driver_wmm.h" #endif #ifdef ROAR_HAVE_LIBPULSE #include #include #include "driver_pulsesimple.h" #endif #ifdef ROAR_HAVE_LIBJACK #include #include #include "driver_jack.h" #endif #ifdef ROAR_HAVE_LIBARTSC #include #include "driver_artsc.h" #endif #if !defined(ROAR_WITHOUT_VIO_DSTR) && !defined(ROAR_WITHOUT_DCOMP_DMX) && defined(ROAR_HAVE_H_LINUX_I2C) && defined(ROAR_HAVE_H_LINUX_I2C_DEV) #define ROAR_HAVE_DRIVER_I2CDMX int driver_i2cdmx_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); #endif #define DRV_FLAG_NONE 0x00 #define DRV_FLAG_FHSEC 0x01 #define ROAR_DRIVER_CTL_NOOP ROAR_STREAM_CTL_COMP_DRV|0x0000 /* noop... */ #define ROAR_DRIVER_CTL_BASE ROAR_STREAM_CTL_COMP_DRV|0x0000 /* Base ops... */ #define ROAR_DRIVER_CTL_SET 0x0002 #define ROAR_DRIVER_CTL_GET 0x0003 #define ROAR_DRIVER_CTL_RECORD 0x0010 #define ROAR_DRIVER_CTL_SET_RECORD ROAR_DRIVER_CTL_BASE|ROAR_DRIVER_CTL_RECORD|ROAR_DRIVER_CTL_SET #define ROAR_DRIVER_CTL2CMD(x) ((x) & (~ROAR_STREAM_CTL_COMP_DRV)) struct roar_driver { char * name; char * desc; char * devices; unsigned int mode; unsigned int flags; unsigned int subsystems; int (*open )(DRIVER_USERDATA_T * inst, char * device, struct roar_audio_info * info); int (*close)(DRIVER_USERDATA_T inst); int (*vio_init)(struct roar_vio_calls * calls, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); }; void print_driverlist (enum output_format format); int driver_openvio(struct roar_vio_calls * calls, int * driver_id, char * driver /* NOTE: this is not part of struct roar_driver's def! */, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_closevio(struct roar_vio_calls * calls, int driver); int driver_set_volume(int stream, struct roar_mixer_settings * mixer); // opening a cdriver #ifndef ROAR_WITHOUT_DCOMP_CDRIVER int driver_cdriver_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); #endif int driver_dummy_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/include/driver_alsa.h0000644000175000017500000000324412264733710017665 0ustar phiphi//driver_alsa.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_ALSA_H_ #define _DRIVER_ALSA_H_ typedef struct roar_alsa { snd_pcm_t * handle; snd_pcm_hw_params_t * params; snd_pcm_format_t format; struct roar_audio_info info; struct roar_stream_server * sstream; int ssid; } roar_alsa_t; int driver_alsa_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); ssize_t driver_alsa_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_alsa_close (struct roar_vio_calls * vio); int driver_alsa_sync (struct roar_vio_calls * vio); int driver_alsa_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/include/driver_ao.h0000644000175000017500000000235612264733710017347 0ustar phiphi//driver_ao.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_AO_H_ #define _DRIVER_AO_H_ int driver_ao_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); ssize_t driver_ao_write(struct roar_vio_calls * vio, void *buf, size_t count); int driver_ao_close(struct roar_vio_calls * vio); #endif //ll roaraudio-1.0beta11/roard/include/driver_artsc.h0000644000175000017500000000267212264733711020066 0ustar phiphi//driver_artsc.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_ARTSC_H_ #define _DRIVER_ARTSC_H_ struct roar_artsc { arts_stream_t stream; struct roar_audio_info * info; }; int driver_artsc_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); ssize_t driver_artsc_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_artsc_close (struct roar_vio_calls * vio); int driver_artsc_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/include/driver_dmx.h0000644000175000017500000000267012264733711017540 0ustar phiphi//driver_dmx.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_DMX_H_ #define _DRIVER_DMX_H_ #if defined(ROAR_WITHOUT_DCOMP_LIGHT) && !defined(ROAR_WITHOUT_DCOMP_DMX) #define ROAR_WITHOUT_DCOMP_DMX #endif #ifndef ROAR_WITHOUT_DCOMP_DMX int driver_dmx_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); ssize_t driver_dmx_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_dmx_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); #endif #endif //ll roaraudio-1.0beta11/roard/include/driver_dstr.h0000644000175000017500000000216712264733711017725 0ustar phiphi//driver_dstr.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_DSTR_H_ #define _DRIVER_DSTR_H_ int driver_dstr_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); #endif //ll roaraudio-1.0beta11/roard/include/driver_esd.h0000644000175000017500000000216112264733711017516 0ustar phiphi//driver_esd.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_ESD_H_ #define _DRIVER_ESD_H_ int driver_esd_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); #endif //ll roaraudio-1.0beta11/roard/include/driver_jack.h0000644000175000017500000000316312264733711017656 0ustar phiphi//driver_jack.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_JACK_H_ #define _DRIVER_JACK_H_ struct driver_jack { jack_client_t * client; unsigned int channels; jack_port_t ** ports_in; jack_port_t ** ports_out; }; int driver_jack_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); ssize_t driver_jack_read (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t driver_jack_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_jack_sync (struct roar_vio_calls * vio); int driver_jack_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int driver_jack_close (struct roar_vio_calls * vio); #endif //ll roaraudio-1.0beta11/roard/include/driver_oss.h0000644000175000017500000000340112264733711017545 0ustar phiphi//driver_oss.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_OSS_H_ #define _DRIVER_OSS_H_ struct driver_oss { char * device; int fh; int blocks; int blocksize; struct roar_audio_info info; int need_config; struct roar_stream_server * stream; int ssid; int fh_savemode; }; int driver_oss_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_oss_close(DRIVER_USERDATA_T inst); int driver_oss_sync(struct roar_vio_calls * vio); int driver_oss_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); ssize_t driver_oss_write (struct roar_vio_calls * vio, void *buf, size_t count); ssize_t driver_oss_read (struct roar_vio_calls * vio, void *buf, size_t count); int driver_oss_close_vio(struct roar_vio_calls * vio); int driver_oss_reopen_device(struct driver_oss * self); #endif //ll roaraudio-1.0beta11/roard/include/driver_portaudio.h0000644000175000017500000000333412264733711020754 0ustar phiphi//driver_portaudio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_PORTAUDIO_H_ #define _DRIVER_PORTAUDIO_H_ #ifdef ROAR_HAVE_LIBPORTAUDIO #if defined(ROAR_HAVE_LIBPABLIO) || defined(ROAR_HAVE_PA19_VERSION_19) #define _DRIVER_PORTAUDIO_CAN_OPERATE #endif #endif #ifdef _DRIVER_PORTAUDIO_CAN_OPERATE struct driver_portaudio { #ifdef ROAR_HAVE_LIBPABLIO PABLIO_Stream * ostream; #elif defined(ROAR_HAVE_PA19_VERSION_19) PaStream *stream; int framesize; #endif }; int driver_portaudio_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_portaudio_close (struct roar_vio_calls * vio); ssize_t driver_portaudio_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_portaudio_sync (struct roar_vio_calls * vio); #endif #endif //ll roaraudio-1.0beta11/roard/include/driver_pulsesimple.h0000644000175000017500000000317112264733712021310 0ustar phiphi//driver_pulsesimple.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_PULSESIMPLE_H_ #define _DRIVER_PULSESIMPLE_H_ struct driver_pulsesimple { pa_simple * handle; /* int dir; char * device; struct roar_stream_server * stream; int ssid; */ }; int driver_pulsesimple_open (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_pulsesimple_close (struct roar_vio_calls * vio); ssize_t driver_pulsesimple_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_pulsesimple_sync (struct roar_vio_calls * vio); int driver_pulsesimple_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/include/driver_pwmled.h0000644000175000017500000000327712264733712020245 0ustar phiphi//driver_pwmled.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_PWMLED_H_ #define _DRIVER_PWMLED_H_ #if defined(ROAR_WITHOUT_DCOMP_LIGHT) && !defined(ROAR_WITHOUT_DCOMP_PWMLED) #define ROAR_WITHOUT_DCOMP_PWMLED #endif #ifndef ROAR_WITHOUT_DCOMP_PWMLED struct driver_pwmled { struct roar_vio_calls vio; struct roar_lpwm_state state; unsigned int rate; // bit/s uint16_t channel; // DMX Channel }; int driver_pwmled_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); ssize_t driver_pwmled_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_pwmled_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); int driver_pwmled_close (struct roar_vio_calls * vio); #endif #endif //ll roaraudio-1.0beta11/roard/include/driver_roar.h0000644000175000017500000000216512264733712017713 0ustar phiphi//driver_roar.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_ROAR_H_ #define _DRIVER_ROAR_H_ int driver_roar_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); #endif //ll roaraudio-1.0beta11/roard/include/driver_rsound.h0000644000175000017500000000244412264733712020262 0ustar phiphi//driver_rsound.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_RSOUND_H_ #define _DRIVER_RSOUND_H_ int driver_rsound_open (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_rsound_close (struct roar_vio_calls * vio); ssize_t driver_rsound_write (struct roar_vio_calls * vio, void *buf, size_t count); #endif //ll roaraudio-1.0beta11/roard/include/driver_shout.h0000644000175000017500000000241012264733712020103 0ustar phiphi//driver_shout.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_SHOUT_H_ #define _DRIVER_SHOUT_H_ int driver_shout_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); ssize_t driver_shout_write(struct roar_vio_calls * vio, void *buf, size_t count); int driver_shout_close(struct roar_vio_calls * vio); #endif //ll roaraudio-1.0beta11/roard/include/driver_sndio.h0000644000175000017500000000354012264733713020063 0ustar phiphi//driver_sndio.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_SNDIO_H_ #define _DRIVER_SNDIO_H_ struct driver_sndio { int dir; char * device; struct sio_hdl * shandle; struct mio_hdl * mhandle; struct roar_audio_info info; int need_reopen; int need_config; struct roar_stream_server * stream; int ssid; }; int driver_sndio_open (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_sndio_close_vio (struct roar_vio_calls * vio); int driver_sndio_open_device (struct driver_sndio * self); int driver_sndio_config_device(struct driver_sndio * self); int driver_sndio_reopen_device(struct driver_sndio * self); ssize_t driver_sndio_write (struct roar_vio_calls * vio, void *buf, size_t count); int driver_sndio_sync (struct roar_vio_calls * vio); int driver_sndio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/include/driver_sysclock.h0000644000175000017500000000257012264733713020603 0ustar phiphi//driver_sysclock.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_SYSCLOCK_H_ #define _DRIVER_SYSCLOCK_H_ struct driver_sysclock { int bps; struct timeval lasttime; long int last_wanted; }; int driver_sysclock_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_sysclock_close (struct roar_vio_calls * vio); ssize_t driver_sysclock_write (struct roar_vio_calls * vio, void *buf, size_t count); #endif //ll roaraudio-1.0beta11/roard/include/driver_wmm.h0000644000175000017500000000543412264733713017553 0ustar phiphi//driver_wmm.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _DRIVER_WMM_H_ #define _DRIVER_WMM_H_ #include #ifdef ROAR_HAVE_LIBWINMM struct driver_wmm { UINT id; /* device id */ HWAVEOUT hwo; /* waveout handler */ WAVEOUTCAPS caps; /* device caps */ WAVEFORMATEX wavefmt; /* sample format */ int opened; /* device has been opened */ int prepared; /* waveheaders have been prepared */ int blocks; /* number of blocks (wave headers) */ int splPerBlock; /* sample per blocks. */ int msPerBlock; /* millisecond per block (approx.) */ void * bigbuffer; /* Allocated buffer for waveheaders and sound data */ struct { WAVEHDR wh; /* waveheader */ char * data; /* sample data ptr */ int idx; /* index of this header */ int count; /* current byte count */ int length; /* size of data */ int sent; /* set when header is sent to device */ } * wh; /* Pointer to waveheaders in bigbuffer */ BYTE * spl; /* Pointer to sound data in bigbuffer */ int sent_blocks; /* Number of waveheader sent (not ack). */ int full_blocks; /* Number of waveheader full (ready to send). */ int widx; /* Index to the block being currently filled. */ int ridx; /* Index to the block being sent. */ }; int driver_wmm_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream); int driver_wmm_close_vio(struct roar_vio_calls * vio); ssize_t driver_wmm_write(struct roar_vio_calls * vio, void *buf, size_t count); #endif #endif //ll roaraudio-1.0beta11/roard/include/empty.h0000644000175000017500000000173312264733713016534 0ustar phiphi//*.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2013-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _*_H_ #define _*_H_ #include #endif //ll roaraudio-1.0beta11/roard/include/emul_rsound.h0000644000175000017500000000312712264733713017731 0ustar phiphi//emul_rsound.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _EMUL_RSOUND_H_ #define _EMUL_RSOUND_H_ #include #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND #define EMUL_RSOUND_MSG_HEADER_LEN (3+5) #define EMUL_RSOUND_MSG_DATA_LEN (64) struct emul_rsound_msg { char header[EMUL_RSOUND_MSG_HEADER_LEN+1]; size_t datalen; char data[EMUL_RSOUND_MSG_DATA_LEN+1]; char * datasp; size_t dataslen; }; int emul_rsound_vrecv_msg(struct emul_rsound_msg * msg, struct roar_vio_calls * vio); int emul_rsound_vsend_msg(struct emul_rsound_msg * msg, struct roar_vio_calls * vio); int emul_rsound_on_connect (int fh, struct roard_listen * lsock); int emul_rsound_check_client(int client, struct roar_vio_calls * vio); #endif #endif //ll roaraudio-1.0beta11/roard/include/emul_simple.h0000644000175000017500000000212012264733713017700 0ustar phiphi//emul_simple.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _EMUL_SIMPLE_H_ #define _EMUL_SIMPLE_H_ #include #if 1 int emul_simple_on_connect (int client, struct roard_listen * lsock); #endif #endif //ll roaraudio-1.0beta11/roard/include/hwmixer.h0000644000175000017500000000505612264733714017064 0ustar phiphi//hwmixer.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _HWMIXER_H_ #define _HWMIXER_H_ #include #define HWMIXER_MODE_ASK 0 #define HWMIXER_MODE_SET 1 struct hwmixer; struct hwmixer_stream { struct hwmixer * hwmixer; int basestream; int stream; void * baseud; void * ud; }; void print_hwmixerlist (void); int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames); int hwmixer_close(int stream); int hwmixer_set_volume(int id, struct roar_stream_server * ss, struct hwmixer_stream * mstream, struct roar_mixer_settings * settings); int hwmixer_get_volume(int id, struct roar_stream_server * ss, struct hwmixer_stream * mstream, struct roar_mixer_settings * settings); struct hwmixer_stream * hwmixer_substream_new(struct hwmixer_stream * parent); int hwmixer_add (char * drv, char * dev, char * opts, int prim, int count); // Mixers: // dstr int hwmixer_dstr_open(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen); int hwmixer_dstr_close(struct hwmixer_stream * stream); int hwmixer_dstr_set_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings); // OSS int hwmixer_oss_open(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen); int hwmixer_oss_close(struct hwmixer_stream * stream); int hwmixer_oss_set_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings); int hwmixer_oss_get_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings); #endif //ll roaraudio-1.0beta11/roard/include/lib.h0000644000175000017500000000213412264733714016141 0ustar phiphi//lib.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _LIB_H_ #define _LIB_H_ #include int lib_run_bg(const char * cmd, const int infh, const int outfh, const int errfh, int * closefh, const size_t lenclose); #endif //ll roaraudio-1.0beta11/roard/include/light.h0000644000175000017500000000425112264733714016504 0ustar phiphi//light.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _LIGHT_H_ #define _LIGHT_H_ #include #ifndef ROAR_WITHOUT_DCOMP_LIGHT #define LIGHT_CHANNELS_DEFAULT 512 /* one DMX Universe */ #define MAX_EVENTS_PER_CYCLE 16 /* this*cfreq is event thruput (16*100Hz = 1.6kEvents/s) */ extern struct light_state { unsigned int channels; uint8_t events[MAX_EVENTS_PER_CYCLE]; size_t eventsqueuelen; uint8_t * state; uint8_t * changes; } g_light_state; extern struct light_mixer { int stream; } g_light_mixer; int light_init (uint32_t channels); int light_free (void); int light_update(void); int light_reset (void); int light_reinit(void); int light_check_stream (int id); int light_send_stream (int id); // for plugins: int light_dmxchannel_get(size_t index); int light_dmxchannel_set(size_t index, uint8_t val); ssize_t light_dmxchannel_num(void); int light_dmxchannel_swap_universe(uint8_t * universe, size_t len); int light_dmxevent_add(const uint8_t * events, size_t len); int light_dmxevent_read(const uint8_t ** events, size_t * len); #define light_dmxevent_addone(event) light_dmxevent_add(&(uint8_t){(event)}, 1) // codec filters: int cf_light_roardmx_read(int id, struct roar_stream_server * ss); int cf_light_roardmx_write(int id, struct roar_stream_server * ss); #endif #endif //ll roaraudio-1.0beta11/roard/include/memlock.h0000644000175000017500000000311612264733714017023 0ustar phiphi//memlock.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _MEMLOCK_H_ #define _MEMLOCK_H_ #include #define MEMLOCK_NONE 0 #define MEMLOCK_LOW 1 #define MEMLOCK_MEDIUM 2 #define MEMLOCK_HIGH 3 #define MEMLOCK_NEARLYALL 124 #define MEMLOCK_NEARLYALLSYS 125 /* include stack and heap if possible */ #define MEMLOCK_ALLCUR 126 /* specal as it uses roar_mm_mlockall() excluding future pages */ #define MEMLOCK_ALL 127 /* specal as it uses roar_mm_mlockall() including future pages */ #define MEMLOCK_DEFAULT MEMLOCK_MEDIUM int memlock_str2level(const char * str); int memlock_set_level(int level); int memlock_register(int level, void * addr, size_t len); #endif //ll roaraudio-1.0beta11/roard/include/meta.h0000644000175000017500000000257512264733714016332 0ustar phiphi//meta.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _META_H_ #define _META_H_ #include #ifdef ROAR_SUPPORT_META int stream_meta_set (int id, int type, const char * name, const char * val); int stream_meta_add (int id, int type, const char * name, const char * val); int stream_meta_get (int id, int type, const char * name, char * val, size_t len); int stream_meta_list (int id, int * types, size_t len); int stream_meta_clear (int id); int stream_meta_finalize(int id); #endif #endif //ll roaraudio-1.0beta11/roard/include/midi.h0000644000175000017500000001027212264733714016317 0ustar phiphi//midi.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _MIDI_H_ #define _MIDI_H_ #include // CB has MIDI as dep #if defined(ROAR_WITHOUT_DCOMP_MIDI) && !defined(ROAR_WITHOUT_DCOMP_CB) #define ROAR_WITHOUT_DCOMP_CB #endif #ifndef ROAR_WITHOUT_DCOMP_MIDI #ifndef ROAR_WITHOUT_DCOMP_CB #ifdef __linux__ #include #include #endif #define MIDI_CB_NOOVERRIDE 0 #define MIDI_CB_OVERRIDE 1 #endif #define MIDI_RATE 31250 // standard MIDI commands: #define MIDI_TYPE_NOTE_OFF 0x80 #define MIDI_TYPE_NOTE_ON 0x90 #define MIDI_TYPE_PA 0xA0 #define MIDI_TYPE_CONTROLER 0xB0 #define MIDI_TYPE_PROGRAM 0xC0 #define MIDI_TYPE_MA 0xD0 #define MIDI_TYPE_PB 0xE0 #define MIDI_TYPE_SYSEX 0xF0 #define MIDI_TYPE_CLOCK_TICK 0xF8 #define MIDI_TYPE_CLOCK_START 0xFA #define MIDI_TYPE_CLOCK_STOP 0xFC // RoarAudio MIDI Commands: #define MIDI_TYPE_NONE 0x00 #define MIDI_TYPE_RAW_PASS 0x10 #define MIDI_TYPE_RAW_NOPASS 0x20 // controller events: #define MIDI_CCE_MAIN_VOL 7 #define MIDI_CCE_BALANCE 8 #define MIDI_CCE_PANORAMA 10 #define MIDI_CCE_LOCAL_CONTR 122 #define MIDI_CCE_ALL_NOTE_OFF 123 #define MIDI_MES_BUFSIZE 4 #define MIDI_READ_SIZE 256 /* this should be big enoth in both cfreq=20..100Hz mode */ #define MIDI_MFLAG_FREE_DP (1<<0) #define MIDI_INITED_MAIN 0x01 #define MIDI_INITED_CB 0x02 #define MIDI_INITED_CLOCK 0x04 extern struct midi_config { int init; int inited; #ifndef ROAR_WITHOUT_DCOMP_CB int init_cb; char * console_dev; #endif } midi_config; struct midi_message { unsigned char type; unsigned char channel; unsigned char flags; unsigned char kk; unsigned char vv; size_t datalen; unsigned char * dataptr; union { unsigned char ldata[MIDI_MES_BUFSIZE]; struct roar_note_octave note; } d; }; extern struct midi_state_mess { struct roar_buffer * buf; } g_midi_mess; #ifndef ROAR_WITHOUT_DCOMP_CB extern struct midi_state_cb { int console; int stream; uint32_t stoptime; int playing; } g_midi_cb; #endif extern struct midi_clock { int stream; uint_least32_t bph; // beats per hour uint_least32_t spt; // samples per tick uint32_t nt; // time of next tick } g_midi_clock; extern struct midi_mixer { int stream; } g_midi_mixer; // general midi interface: int midi_init_config(void); int midi_init (void); int midi_free (void); int midi_update(void); int midi_reinit(void); // streams: int midi_check_stream (int id); int midi_send_stream (int id); int midi_conv_midi2mes (int id); int midi_conv_mes2midi (int id); int midi_conv_mes2ssynth(void); int midi_new_bufmes (struct roar_buffer ** buf, struct midi_message ** mes); int midi_add_buf (int id, struct roar_buffer ** buf); // bridges: int midi_check_bridge (int id); // clock: int midi_clock_init (void); int midi_clock_set_bph (uint_least32_t bph); int midi_clock_tick (void); // cb = console beep #ifndef ROAR_WITHOUT_DCOMP_CB int midi_cb_init(void); int midi_cb_free(void); int midi_cb_play(float t, float freq, int override); int midi_cb_update (void); int midi_cb_start(float freq); int midi_cb_stop (void); int midi_cb_readbuf(void); #endif // dummys: int midi_vio_set_dummy(int stream); #endif #endif //ll roaraudio-1.0beta11/roard/include/mixer.h0000644000175000017500000000240612264733715016522 0ustar phiphi//mixer.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _MIXER_H_ #define _MIXER_H_ #include #define _MIXER_NAME_PREFIX "" #define _MIXER_NAME_SUFFIX " Mixer" #define _MIXER_NAME(x) (_MIXER_NAME_PREFIX x _MIXER_NAME_SUFFIX) int need_vol_change (int channels, struct roar_mixer_settings * set); int add_mixer (int subsys, char * name, struct roar_stream_server ** ss_ptr); #endif //ll roaraudio-1.0beta11/roard/include/network.h0000644000175000017500000000213112264733715017062 0ustar phiphi//network.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _NETWORK_H_ #define _NETWORK_H_ #include int net_check_listen (void); struct roard_listen; int net_get_new_client (struct roard_listen * lsock); #endif //ll roaraudio-1.0beta11/roard/include/output.h0000644000175000017500000000672212264733715016743 0ustar phiphi//output.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _OUTPUT_H_ #define _OUTPUT_H_ #include // NOTE: we do not set ROAR_OUTPUT_BUFFER_SAMPLES depending on DEBUG anymore // as it caused a lot problems with partly enabled debugging #ifdef ROAR_OUTPUT_CFREQ #define ROAR_OUTPUT_BUFFER_SAMPLES (ROAR_RATE_DEFAULT/ROAR_OUTPUT_CFREQ) #else // in normal case we use 100 cycles per sec, as we do not know the sample // rate at compile time we guess it's normaly the default rate. // on OpenBSD we need to set a lower freq, use 20 cycles per sec here as // it seems to work. // FIXME: find out what the problem is and how to fix #ifdef ROAR_OS_OPENBSD #define ROAR_OUTPUT_BUFFER_SAMPLES (ROAR_RATE_DEFAULT/20) #define ROAR_OUTPUT_CFREQ 20 #else #define ROAR_OUTPUT_BUFFER_SAMPLES (ROAR_RATE_DEFAULT/100) #define ROAR_OUTPUT_CFREQ 100 #endif #endif #define ROAR_OUTPUT_WRITE_SIZE 1024 //#define ROAR_OUTPUT_CALC_OUTBUFSIZE(x) (ROAR_OUTPUT_BUFFER_SAMPLES * (x)->channels * ((x)->bits / 8) * ((float)(x)->rate/g_sa->rate)) // First rounds the samples count, and makes sure that the outbuffer size is divisible by the framesize (channels * bits/8) #define ROAR_OUTPUT_CALC_OUTBUFSIZE(x) ( \ ( \ (int)(ROAR_OUTPUT_BUFFER_SAMPLES * ((float)(x)->rate/g_sa->rate) + 0.5) \ ) * \ (x)->channels * ((x)->bits / 8) \ ) #define ROAR_OUTPUT_CALC_OUTBUFSAMP(x,y) ((y) / ((x)->channels * ((x)->bits / 8)*((float)(x)->rate/g_sa->rate))) #define ROAR_OUTPUT_CALC_OUTBUFSIZE_MAX(x0,x1) (ROAR_OUTPUT_BUFFER_SAMPLES * \ ROAR_MAX((x0)->channels,(x1)->channels) * \ (ROAR_MAX((x0)->bits, (x1)->bits ) / 8) * \ (ROAR_MAX((float)(x0)->rate,(float)(x1)->rate)/g_sa->rate) \ ) extern void * g_output_buffer; extern void * g_input_buffer; extern size_t g_output_buffer_len; #define g_input_buffer_len g_output_buffer_len int output_buffer_init (struct roar_audio_info * info); int output_buffer_reinit (void); int output_buffer_free (void); int output_add (char * drv, char * dev, char * opts, int prim, int count); int output_add_default (char * drv, char * dev, char * opts, int prim, int count); #endif //ll roaraudio-1.0beta11/roard/include/plugins.h0000644000175000017500000000266212264733715017063 0ustar phiphi//plugins.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _PLUGINS_H_ #define _PLUGINS_H_ #include #define ROARD_DL_APPNAME "roard " ROAR_VSTR_ROARAUDIO #define ROARD_DL_ABIVERSION "1.0beta8" int plugins_preinit (void); int plugins_init (void); int plugins_free (void); int plugins_update (void); int plugins_load (const char * filename, const char * args); void print_pluginlist(enum output_format format); // Check version: #define ROARD_DL_CHECK_VERSIONS() ROAR_DL_PLUGIN_CHECK_VERSIONS(ROARD_DL_APPNAME, ROARD_DL_ABIVERSION) #endif //ll roaraudio-1.0beta11/roard/include/raw.h0000644000175000017500000000210612264733715016164 0ustar phiphi//raw.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _RAW_H_ #define _RAW_H_ #include #ifndef ROAR_WITHOUT_DCOMP_RAW #define RAW_READ_LEN 1024 int raw_check_stream (int id); #endif #endif //ll roaraudio-1.0beta11/roard/include/rdtcs.h0000644000175000017500000000417112264733715016516 0ustar phiphi//rdtcs.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _RDTCS_H_ #define _RDTCS_H_ #include #ifndef ROAR_WITHOUT_DCOMP_RDTCS #define RDTCS_RDS_PS_LEN 8 #define RDTCS_RDS_PS_DEFAULT "ROARING" #define RDTCS_RDS_PTY_DEFAULT 0 #define RDTCS_RDS_PI_DEFAULT 0x0000 #define RDTCS_RDS_BLOCK_A 1 #define RDTCS_RDS_BLOCK_B 2 #define RDTCS_RDS_BLOCK_C0 3 #define RDTCS_RDS_BLOCK_C1 4 #define RDTCS_RDS_BLOCK_D 5 #define RDTCS_RDS_GROUP_LEN ((4*(16+10))/8) #define RDTCS_RDS_FLAG_NONE 0x0000 #define RDTCS_RDS_FLAG_TP 0x0001 #define RDTCS_RDS_FLAG_CT 0x0002 extern struct rdtcs_state { int inited; struct { char ps[RDTCS_RDS_PS_LEN+1]; unsigned char pty; uint16_t pi; unsigned int flags; } rds; } g_rdtcs; int rdtcs_init (void); int rdtcs_free (void); int rdtcs_init_config (void); int rdtcs_rds_set_ps (char * ps); int rdtcs_rds_set_pty (char * pty); int rdtcs_rds_set_flag(unsigned int flag, int reset); int rdtcs_check_stream (int id); int rdtcs_send_stream (int id); int rdtcs_send_stream_rds (int id, struct roar_stream_server * ss); int rdtcs_send_stream_rds_group (int id, struct roar_stream_server * ss); uint16_t rdtcs_rds_crc_calc (uint16_t data, int block); #endif #endif //ll roaraudio-1.0beta11/roard/include/req.h0000644000175000017500000001022412264733716016163 0ustar phiphi//req.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _REQ_H_ #define _REQ_H_ #include int req_on_noop (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_quit (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_identify (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_auth (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_whoami (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_new_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_exec_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_con_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_passfh (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); #ifdef ROAR_SUPPORT_META int req_on_set_meta (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_get_meta (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_list_meta (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); #endif int req_on_get_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_set_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_exit (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_gettimeofday(int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_server_info (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_server_oinfo(int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_caps (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_list_clients(int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_list_streams(int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_get_client (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_get_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_get_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_set_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_kick (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_attach (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_set_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_get_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_add_data (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_beep (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); int req_on_wait (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); //int req_on_ (int client, struct roar_message * mes, char ** data, uint32_t flags[2]); #endif //ll roaraudio-1.0beta11/roard/include/roard.h0000644000175000017500000001273212264733716016511 0ustar phiphi//roard.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _ROARD_H_ #define _ROARD_H_ // configure ROAR_INFO() extern int g_verbose; #define ROAR_DBG_INFOVAR g_verbose // configure ROAR_*() #define ROAR_DBG_PREFIX "roard" // need to include this first as we need the config #include #include #include #include #include #ifdef ROAR_HAVE_H_SIGNAL #include #endif #if defined(ROAR_HAVE_SELECT) && defined(ROAR_HAVE_H_SYS_SELECT) #include #endif #ifdef ROAR_HAVE_WAIT #include #endif #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) #include #include #endif #ifdef ROAR_HAVE_H_SYS_TIME #include #endif #ifdef ROAR_HAVE_H_TIME #include #endif #ifdef ROAR_HAVE_LIBSLP #include #endif /* #ifdef __linux__ #include #include #endif */ #define ROAR_SUBSYS_NONE 0x00 #define ROAR_SUBSYS_WAVEFORM 0x01 #define ROAR_SUBSYS_MIDI 0x02 #define ROAR_SUBSYS_CB 0x04 #define ROAR_SUBSYS_LIGHT 0x08 #define ROAR_SUBSYS_RAW 0x10 #define ROAR_SUBSYS_COMPLEX 0x20 #define ROAR_SUBSYS_RDTCS 0x40 // listeing code: #define ROAR_MAX_LISTEN_SOCKETS 16 union uniinst { void * vp; int si; }; enum output_format { FORMAT_NATIVE = 1, FORMAT_WIKI, FORMAT_CSV, FORMAT_DEFAULT = FORMAT_NATIVE }; // MFOI = Marked For Optional Include //#include "buffer.h" #include "caps.h" #include "memlock.h" #include "codecfilter.h" /* MFOI */ #include "container_framework.h" /* MFOI */ #include "rolestack.h" #include "client.h" #include "auth.h" #include "driver.h" /* MFOI */ #include "output.h" #include "mixer.h" //#include "convert.h" #include "streams.h" #include "network.h" #include "commands.h" #include "req.h" #include "emul_simple.h" /* MFOI */ #include "emul_rsound.h" /* MFOI */ #include "sources.h" #include "sample.h" #include "hwmixer.h" #include "meta.h" #include "midi.h" #include "ssynth.h" #include "light.h" #include "raw.h" #include "rdtcs.h" #include "waveform.h" #include "beep.h" #include "lib.h" #include "plugins.h" extern int alive; #ifdef ROAR_SUPPORT_LISTEN extern int g_no_listen; #endif extern uint32_t g_pos; // current position in output stream extern int g_standby; extern int g_autostandby; #ifdef ROAR_SUPPORT_LISTEN struct roard_listen; #endif int main_loop (struct roar_audio_info * sa, int sysclocksync); void cleanup_listen_socket (int terminate); void clean_quit (void); void clean_quit_prep (void); void on_sig_int (int signum); void on_sig_term (int signum); void on_sig_chld (int signum); void on_sig_usr1 (int signum); #ifdef ROAR_SUPPORT_LISTEN int get_listen(struct roard_listen ** sock, const char *** sockname); int add_listen (const char * addr, int port, int sock_type, char * user, char * group, int proto, int dir, struct roar_audio_info * info); #endif #ifdef ROAR_SUPPORT_LISTEN extern struct roard_listen { int used; struct roar_vio_calls sock; int proto; union { void * vp; int si; struct { int dir; struct roar_audio_info info; } stpl; } inst; } g_listen[ROAR_MAX_LISTEN_SOCKETS]; #endif extern int g_self_client; extern int g_terminate; extern struct roar_audio_info * g_sa, * g_max_sa; #define CONF_DEF_STRING "***default***" extern struct roard_config { uint32_t flags; struct { uint32_t flags; struct roar_mixer_settings mixer; int mixer_channels; int rpgmode; } streams[ROAR_DIR_DIRIDS]; char * location; char * description; char * contact; char * serial; char * uiurl; size_t jumbo_mtu; int memlock_level; #ifdef ROAR_HAVE_SYSTEM struct { const char * post_shutdown; } scripts; #endif } * g_config; struct _counters { size_t clients, streams, samples, sources, outputs, mixers, bridges, listens; }; extern struct counters { struct _counters cur, sum; } g_counters; #define counters_init() memset(counters_getptr(), 0, sizeof(struct counters)) //#define counters_inc(c,i) do { signed long int __i = (i); if ( __i < 0 && __i > (g_counters.cur.c) ) { ROAR_WARN("counters_inc(c=%s, i=%li): Decrement request bigger than current counter value. Counter out of syn!", ) } while (0) #define counters_inc(c,i) do { signed long int __i = (i); counters_getptr()->cur.c += __i; if ( __i > 0 ) counters_getptr()->sum.c += __i; } while (0) #define counters_get(g,c) ((counters_getptr()->g.c)) struct counters * counters_getptr(void); void counters_print(int type, int force); #endif //ll roaraudio-1.0beta11/roard/include/rolestack.h0000644000175000017500000000273312264733716017371 0ustar phiphi//rolestack.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _ROLESTACK_H_ #define _ROLESTACK_H_ #include enum rs_action { RS_ERROR = -1, RS_MIX = 0, RS_KICK, RS_MUTE, RS_PAUSE }; struct rolestack { int index; int role; enum rs_action action; }; void rolestack_init(void); void print_rolestack(void); const struct rolestack * rolestack_get_role(int role); int rolestack_push(const struct rolestack * role); enum rs_action rolestack_str2action(const char * str); const char * rolestack_action2str(enum rs_action action); const struct rolestack * rolestack_parse(const char * str); #endif //ll roaraudio-1.0beta11/roard/include/sample.h0000644000175000017500000000244312264733717016662 0ustar phiphi//sample.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _SAMPLE_H_ #define _SAMPLE_H_ #include #define ROAR_SAMPLES_MAX 32 extern struct roar_sample * g_samples[ROAR_SAMPLES_MAX]; int samples_init (void); int samples_free (void); int samples_new (void); int samples_delete (int id); int samples_set_name (int id, char * name); int samples_add_data (int id, void * data, size_t len); #endif //ll roaraudio-1.0beta11/roard/include/sources.h0000644000175000017500000000443612264733717017070 0ustar phiphi//sources.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _SOURCES_H_ #define _SOURCES_H_ #include #ifndef ROAR_WITHOUT_DCOMP_SOURCES #define SRC_FLAG_NONE 0x00 #define SRC_FLAG_FHSEC 0x01 struct roar_source { char * name; char * desc; char * devices; unsigned int flags; unsigned int subsystems; int (*old_open)(const char * driver, const char * device, const char * container, const char * options, int primary); int (*new_open)(int stream , const char * device, int fh, const char * driver); }; int sources_init (void); int sources_free (void); int sources_set_client (int client); void print_sourcelist (void); int sources_add (char * driver, char * device, char * container, char * options, int primary); int sources_add_new (struct roar_source * source, char * driver, char * device, char * options, int primary); int sources_add_dstr (int stream , const char * device, int fh, const char * driver); int sources_add_cf (const char * driver, const char * device, const char * container, const char * options, int primary); int sources_add_roar (int stream, const char * device, int fh, const char * driver); int sources_add_radionoise (int stream, const char * device, int fh, const char * driver); #ifndef ROAR_WITHOUT_DCOMP_CDRIVER int sources_add_cdriver (int stream , const char * device, int fh, const char * driver); #endif #endif #endif //ll roaraudio-1.0beta11/roard/include/ssynth.h0000644000175000017500000000423512264733717016732 0ustar phiphi//ssynth.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _SSYNTH_H_ #define _SSYNTH_H_ #include // we relay on the MIDI subsystem #if defined(ROAR_WITHOUT_DCOMP_MIDI) && !defined(ROAR_WITHOUT_DCOMP_SSYNTH) #define ROAR_WITHOUT_DCOMP_SSYNTH #endif #ifndef ROAR_WITHOUT_DCOMP_SSYNTH #define SSYNTH_NOTES_MAX 16 #define SSYNTH_STAGE_NONE 0 #define SSYNTH_STAGE_UNUSED SSYNTH_STAGE_NONE #define SSYNTH_STAGE_KEYSTROKE 1 #define SSYNTH_STAGE_MIDSECTION 2 #define SSYNTH_STAGE_KEYRELEASE 3 #define SSYNTH_POLY_KEYDOWN 0 #define SSYNTH_POLY_KEYUP 1 #define SSYNTH_POLY_POLYMAX 2 #define SSYNTH_POLY_COEFF 4 extern struct ssynth_conf { int enable; } ssynth_conf; int ssynth_init_config(void); int ssynth_init (void); int ssynth_free (void); int ssynth_update (void); int ssynth_note_new(struct roar_note_octave * note, char vv); int ssynth_note_free(int id); int ssynth_note_find(struct roar_note_octave * note); int ssynth_note_set_stage(int id, int stage); int ssynth_note_render (int id, void * data); int ssynth_note_on (struct roar_note_octave * note, char vv); int ssynth_note_off (struct roar_note_octave * note, char vv); int ssynth_eval_message (struct midi_message * mes); #endif #endif //ll roaraudio-1.0beta11/roard/include/streams.h0000644000175000017500000001554712264733717017070 0ustar phiphi//streams.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _STREAMS_H_ #define _STREAMS_H_ #include /* Defined in #define ROAR_STREAMS_MAX 64 */ //#define ROAR_STREAM(x) ((struct roar_stream*)(x)) #define ROAR_STREAM_SERVER(x) ((struct roar_stream_server*)(x)) // stream ctls...: #define ROAR_STREAM_CTL_COMPMASK 0xFF000000 #define ROAR_STREAM_CTL_TYPEMASK 0x00FF0000 #define ROAR_STREAM_CTL_CMDMASK 0x0000FFFF #define ROAR_STREAM_CTL_COMP_BASE 0x00000000 #define ROAR_STREAM_CTL_COMP_CF 0x01000000 #define ROAR_STREAM_CTL_COMP_DRV 0x02000000 #define ROAR_STREAM_CTL_TYPE_VOID 0x00000000 #define ROAR_STREAM_CTL_TYPE_INT 0x00010000 #define ROAR_STREAM_CTL_TYPE_FLOAT 0x00020000 #define ROAR_STREAM_CTL_TYPE_FPI100 0x00030000 /* fix point integter int/100 */ #define STREAM_DIR_NONE 0x00 #define STREAM_DIR_IN 0x01 #define STREAM_DIR_OUT 0x02 #define STREAM_DIR_BIDIR (STREAM_DIR_IN|STREAM_DIR_OUT) #define MAX_LTM_WINDOWS_PER_STREAM 1 struct roar_ltm_vals { int64_t rms; }; struct roar_stream_ltm { int window; int parent_window; int mt; size_t refc; size_t channels; struct roar_ltm_vals * cur; struct roar_ltm_vals ** history; }; extern struct roar_stream_server { struct roar_stream _stream; unsigned int pos_abs; int client; struct roar_buffer * buffer; size_t need_extra; void * output; struct roar_mixer_settings mixer; #ifdef ROAR_SUPPORT_META struct roar_meta meta[ROAR_META_MAX_PER_STREAM]; #endif int is_new; int codecfilter; ROAR_AUDIO_INFO_TYPE codec_orgi; CODECFILTER_USERDATA_T codecfilter_inst; int socktype; int pre_underruns; int post_underruns; struct roar_vio_calls vio; int primary; int driver_id; // struct roardsp_filterchain fc; uint32_t flags; uint32_t flags_protection; uint_least32_t delay; char * name; int ready; struct roar_buffer * outputbuffer; int state; struct roar_buffer * prethru; struct roar_vio_calls jumbo; struct roar_vio_calls * viop; int mixer_stream; struct roardsp_chanmap chanmap; int role; int parent_stream; struct roar_stream_ltm ltm[MAX_LTM_WINDOWS_PER_STREAM]; #ifndef ROAR_WITHOUT_DCOMP_MIXER struct hwmixer_stream * mixerstream; #endif size_t single_sink_c; size_t single_sink_self_c; int rpgmode; } * g_streams[ROAR_STREAMS_MAX]; extern int streams_recsource_id; void streams_change_sync_num(int id, int diff); int streams_init (void); int streams_free (void); int streams_new (void); int streams_delete (int id); int streams_set_client (int id, int client); int streams_get_client (int id); int streams_set_dir (int id, int dir, int defaults); int streams_get_dir (int id); int streams_set_mixer_stream(int id, int mixer); int streams_get_mixer_stream(int id); int streams_set_role (int id, int role); int streams_dir2subsys (int dir); int streams_get_subsys (int id); int streams_get_ssdir (int id); int streams_new_virtual (int parent, struct roar_stream_server ** stream); int streams_set_fh (int id, int fh); int streams_get_fh (int id); int streams_set_null_io(int id); int streams_get (int id, struct roar_stream_server ** stream); int streams_get_clientobj (int id, struct roar_stream ** stream); int streams_set_socktype (int id, int socktype); int streams_get_socktype (int id); int streams_is_ready (int id); int streams_is_new (int id); int streams_set_primary (int id, int prim); int streams_mark_primary (int id); int streams_set_sync (int id, int sync); int streams_set_mmap (int id, int reset); int streams_set_single_sink(int id, int reset); int streams_set_flag (int id, uint32_t flag); int streams_set_rawflag (int id, uint32_t flag); int streams_reset_flag (int id, uint32_t flag); int streams_get_flag (int id, uint32_t flag); int streams_protect_flag (int id, uint32_t flag); int streams_set_name (int id, char * name); char * streams_get_name (int id); int streams_calc_delay (int id); int streams_set_mixer (int id); int streams_set_map (int id, char * map, size_t len); int streams_get_rpg (int id, struct roar_stream_rpg * rpg); int streams_set_rpg (int id, const struct roar_stream_rpg * rpg); int streams_ltm_ctl (int id, int mt, int window, int cmd); int streams_ltm_calc (int id, struct roar_audio_info * info, void * data, size_t len); struct roar_stream_ltm * streams_ltm_get(int id, int mt, int window); struct hwmixer_stream * streams_get_mixerstream(int id); int streams_set_mixerstream(int id, struct hwmixer_stream * mstream); int streams_read_mixervalues(int id); int streams_ctl (int id, int_least32_t cmd, void * data); int stream_add_buffer (int id, struct roar_buffer ** buf); int stream_shift_out_buffer (int id, void * data, size_t * len); int stream_outputbuffer_request(int id, struct roar_buffer ** buf, size_t len); int stream_outputbuffer_destroy(int id); int stream_prethru_add(int id, struct roar_buffer ** buf); int stream_prethru_add_data(int id, void ** buf, size_t len); int stream_prethru_destroy(int id); int stream_prethru_send(int dst, int src); int streams_check (int id); int streams_send_mon (int id); int streams_send_filter_all(void); int streams_send_filter(int id); int streams_get_mixbuffers (void *** bufferlist, struct roar_audio_info * info, unsigned int pos); int streams_get_outputbuffer (int id, void ** buffer, size_t size); int streams_fill_mixbuffer (int id, struct roar_audio_info * info); int streams_fill_mixbuffer2 (int id, struct roar_audio_info * info); ssize_t stream_vio_read (int stream, void * buf, size_t count); ssize_t stream_vio_write(int stream, void * buf, size_t count); int stream_vio_ctl (int stream, roar_vio_ctl_t cmd, void * data); ssize_t stream_vio_s_read (struct roar_stream_server * stream, void * buf, size_t count); ssize_t stream_vio_s_write(struct roar_stream_server * stream, void * buf, size_t count); int stream_vio_s_ctl (struct roar_stream_server * stream, roar_vio_ctl_t cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/include/waveform.h0000644000175000017500000000240012264733717017220 0ustar phiphi//waveform.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _WAVEFORM_H_ #define _WAVEFORM_H_ #include struct waveform_stream { int stream; struct roar_stream_server * ss; }; extern struct waveform_stream g_waveform_mixer, g_waveform_recbridge; int waveform_init (void); int waveform_free (void); int waveform_update_inputs (void); int waveform_update_mixer (void); #endif //ll roaraudio-1.0beta11/roard/Makefile0000644000175000017500000000416312243154240015227 0ustar phiphiTARGETS=roard OBJ=roard.o driver.o mixer.o output.o signals.o loop.o clients.o streams.o network.o commands.o req.o sources.o sample.o meta.o codecfilter.o lib.o ssynth.o container_framework.o plugins.o memlock.o hwmixer.o auth.o caps.o rolestack.o SUBSYS=midi.o light.o raw.o rdtcs.o waveform.o beep.o DRV=driver_esd.o driver_ao.o driver_roar.o driver_oss.o driver_shout.o driver_sndio.o driver_dmx.o driver_pwmled.o driver_i2cdmx.o driver_sysclock.o driver_wmm.o driver_dstr.o driver_alsa.o driver_rsound.o driver_portaudio.o driver_pulsesimple.o driver_jack.o driver_artsc.o CF_CODEC=codecfilter_cmd.o codecfilter_vorbis.o codecfilter_celt.o codecfilter_speex.o codecfilter_alaw.o codecfilter_mulaw.o codecfilter_sndfile.o codecfilter_fishsound.o codecfilter_flac.o codecfilter_roardmx.o CF_CONTAINER=codecfilter_wave.o codecfilter_au.o codecfilter_uniraum.o EMUL=emul_simple.o emul_rsound.o HWMIXER=hwmixer_dstr.o hwmixer_oss.o CF=${CF_CONTAINER} ${CF_CODEC} include ../Makefile.conf include ../Makefile.inc #DEFINES = -DDEBUG #DEFINES = -DMONITOR_LATENCY INCLUDE = -I../include -I./include CFLAGS += $(DEBUG_g) $(Wall) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) LDFLAGS += $(DEBUG_g) $(Wall) $(rdynamic) -L../lib/ $(LDPATH) DRVLIBS = $(lib_esd) $(lib_ossaudio) $(lib_ao) $(lib_shout) $(pthread) $(lib_sndio) $(lib_rsound) $(lib_portaudio) $(lib_pablio) $(lib_asound) $(lib_winmm) $(lib_pulse_simple) $(lib_pulse) $(lib_jack) $(lib_artsc) CODEC_CELT= $(lib_celt) $(lib_celt0) CODECLIBS = $(lib_vorbisfile) $(lib_vorbisenc) $(lib_vorbis) $(lib_fishsound) $(lib_speex) $(lib_speexdsp) $(CODEC_CELT) $(lib_flac) CONTLIBS = $(lib_oggz) $(lib_sndfile) $(lib_ogg) $(lib_uniraum) OWNLIBS = $(LIBROAREIO) $(LIBROARLIGHT) $(LIBROARMIDI) $(LIBROARDSP) $(LIBROAR) LIBS = $(DRVLIBS) $(CODECLIBS) $(CONTLIBS) $(OWNLIBS) $(lib_slp) all: ${TARGETS} rm -f ../lib/${TARGETS} 2> /dev/null || true cp $(cp_v) ${TARGETS} ../lib/ clean: rm -f ${TARGETS} *.o new: clean all run: roard ./roard $(ARGS) roard: ${OBJ} ${SUBSYS} ${DRV} ${CF} ${EMUL} ${HWMIXER} ${CC} ${LDFLAGS} -o roard ${OBJ} ${SUBSYS} ${DRV} ${CF} ${EMUL} ${HWMIXER} ${LIBS} roaraudio-1.0beta11/roard/auth.c0000644000175000017500000001400612264733653014707 0ustar phiphi//auth.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #define _NONE ROAR_AUTH_T_AUTO // declared 'extern' struct auth_key g_auth_keyring[AUTH_KEYRING_LEN]; int auth_init (void) { int i; memset(g_auth_keyring, 0, sizeof(g_auth_keyring)); for (i = 0; i < AUTH_KEYRING_LEN; i++) { g_auth_keyring[i].type = _NONE; } #if 0 // test password for API tests... auth_addkey_password(ACCLEV_ALL, "test"); #endif #if 0 // test trust for API tests... auth_addkey_trust(ACCLEV_ALL, -1, 0, getuid()+1, -1, getgid()+1, -1); #endif return 0; } int auth_free (void) { return 0; } union auth_typeunion * auth_regkey_simple(int type, enum roard_client_acclev acclev) { struct auth_key * key; int i; for (i = 0; i < AUTH_KEYRING_LEN; i++) { if ( (key = &(g_auth_keyring[i]))->type == _NONE ) { memset(key, 0, sizeof(struct auth_key)); key->type = type; key->acclev = acclev; return &(key->at_data); } } return NULL; } static int _ck_cookie(struct auth_key * key, struct roar_auth_message * authmes) { if ( key->at_data.cookie.len == authmes->len ) { if ( memcmp(key->at_data.cookie.cookie, authmes->data, authmes->len) ) { return -1; } else { return 1; } } return -1; } static int _ck_password(struct auth_key * key, struct roar_auth_message * authmes) { size_t len = strlen(key->at_data.password.password); // need to check here if we have a padding \0-byte. if ( len == authmes->len ) { if ( memcmp(key->at_data.password.password, authmes->data, len) ) { return -1; } else { return 1; } } return -1; } static int _ck_trust(struct auth_key * key, struct roar_auth_message * authmes, struct roar_client_server * cs) { struct at_trust * t = &(key->at_data.trust); size_t i; (void)authmes; // we ship pids at the moment as cs does not contain a verifyed one. for (i = 0; i < t->uids_len; i++) if ( t->uids[i] == ROAR_CLIENT(cs)->uid ) return 1; for (i = 0; i < t->gids_len; i++) if ( t->gids[i] == ROAR_CLIENT(cs)->gid ) return 1; return -1; } int auth_client_ckeck(struct roar_client_server * cs, struct roar_auth_message * authmes, int * next) { struct auth_key * key; int i; int ret; if ( cs == NULL || authmes == NULL || next == NULL ) return -1; *next = -1; for (i = 0; i < AUTH_KEYRING_LEN; i++) { if ( (key = &(g_auth_keyring[i]))->type == authmes->type ) { ROAR_DBG("auth_client_ckeck(cs=%p, authmes=%p, next=%p{%i}): key=%p{.type=%i, ...}", cs, authmes, next, *next, key, key->type); ret = -1; switch (key->type) { case ROAR_AUTH_T_NONE: ret = 1; break; case ROAR_AUTH_T_PASSWORD: ret = _ck_password(key, authmes); break; case ROAR_AUTH_T_COOKIE: ret = _ck_cookie(key, authmes); break; case ROAR_AUTH_T_TRUST: ret = _ck_trust(key, authmes, cs); break; case ROAR_AUTH_T_SYSUSER: case ROAR_AUTH_T_RHOST: default: /* don't know what to do... */ return -1; break; } switch (ret) { case -1: /* ignore this case and continue */ break; case 0: // fatal auth error (server side auth cancel) return 0; break; case 1: cs->acclev = key->acclev; return 1; break; default: /* error! */ return -1; break; } } } // make a better guess: /* if ( authmes->type == ROAR_AUTH_T_PASSWORD ) { *next = -1; } else { *next = ROAR_AUTH_T_PASSWORD; } */ return -1; } int auth_addkey_anonymous(enum roard_client_acclev acclev) { if ( auth_regkey_simple(ROAR_AUTH_T_NONE, acclev) == NULL ) return -1; return 0; } int auth_addkey_password(enum roard_client_acclev acclev, const char * password) { union auth_typeunion * pw; if ( (pw = auth_regkey_simple(ROAR_AUTH_T_PASSWORD, acclev)) == NULL ) return -1; pw->password.password = password; return 0; } int auth_addkey_cookie(enum roard_client_acclev acclev, const void * cookie, const size_t len) { union auth_typeunion * key; if ( (key = auth_regkey_simple(ROAR_AUTH_T_COOKIE, acclev)) == NULL ) return -1; key->cookie.cookie = (void*)cookie; key->cookie.len = len; return 0; } int auth_addkey_trust(enum roard_client_acclev acclev, ...) { union auth_typeunion * key; size_t i; va_list va; pid_t pid = -1; uid_t uid = -1; gid_t gid = -1; int err = 0; if ( (key = auth_regkey_simple(ROAR_AUTH_T_TRUST, acclev)) == NULL ) return -1; // zerosize all counters. memset(key, 0, sizeof(union auth_typeunion)); va_start(va, acclev); do { // eval block we can leave with continue. #define _block(var,type,array) i = 0; \ do { \ if ( i == AT_TRUST_MAX_ENTRYS ) { err = 1; continue; } \ var = va_arg(va, type); \ key->trust.array[i] = var; \ i++; \ } while (var != -1); \ if ( err ) continue; \ key->trust.array ## _len = i; _block(pid, pid_t, pids); _block(uid, uid_t, uids); _block(gid, gid_t, gids); #undef _block } while(0); va_end(va); if ( !err ) return 0; memset(key, 0, sizeof(union auth_typeunion)); return -1; } //ll roaraudio-1.0beta11/roard/beep.c0000644000175000017500000001237312264733653014666 0ustar phiphi//beep.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" // TODO: FIXME: can all this VIO stuff be replaced by one call to stream_add_buffer()? // TODO: FIXME: move them out of here into libroar: static ssize_t beep_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_buffer * rbuf; ROAR_DBG("beep_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); if ( vio->inst == NULL ) return 0; rbuf = vio->inst; if ( roar_buffer_shift_out(&rbuf, buf, &count) == -1 ) return -1; vio->inst = rbuf; return count; } static int beep_close (struct roar_vio_calls * vio) { ROAR_DBG("beep_close(vio=%p) = ?", vio); if ( vio->inst != NULL ) roar_buffer_free(vio->inst); ROAR_DBG("beep_close(vio=%p) = 0", vio); return 0; } static void beep_init_vio (struct roar_vio_calls * vio, void * inst) { ROAR_DBG("beep_init_vio(vio=%p, inst=%p) = ?", vio, inst); memset(vio, 0, sizeof(struct roar_vio_calls)); vio->flags = ROAR_VIO_FLAGS_NONE; vio->refc = 1; vio->inst = inst; vio->read = beep_read; vio->close = beep_close; ROAR_DBG("beep_init_vio(vio=%p, inst=%p) = (void)", vio, inst); } struct roar_buffer * beep_fill_buffer (struct roar_beep * beep, struct roar_audio_info * info) { struct roar_buffer * buf; size_t frames = beep->time * info->rate / 1000; size_t samples = frames * info->channels; size_t mod = info->rate / beep->freq; char * data; void * bufdata; char val; size_t pos; size_t chan; ROAR_DBG("beep_fill_buffer(beep=%p, info=%p) = ?", beep, info); if ( roar_buffer_new_data(&buf, samples, &bufdata) == -1 ) { ROAR_DBG("beep_fill_buffer(beep=%p, info=%p) = NULL", beep, info); return NULL; } data = (char*)bufdata; for (pos = 0; pos < frames; pos++) { val = (pos % mod) < mod/2 ? -128 : 127; for (chan = 0; chan < info->channels; chan++) data[pos*info->channels + chan] = val; } ROAR_DBG("beep_fill_buffer(beep=%p, info=%p) = %p", beep, info, buf); return buf; } int beep_start (int client, struct roar_beep * beep) { struct roar_stream_server * ss; struct roar_stream * s; struct roar_buffer * buf; int stream; ROAR_DBG("beep_start(client=%i, beep=%p) = ?", client, beep); if ( beep->vol == 0 ) beep->vol = ROAR_BEEP_DEFAULT_VOL; if ( beep->time == 0 ) beep->time = ROAR_BEEP_DEFAULT_TIME; if ( beep->freq == 0 ) beep->freq = ROAR_BEEP_DEFAULT_FREQ; if ( beep->type == 0 ) beep->type = ROAR_BEEP_DEFAULT_TYPE; // x, y, z location '0' is allready centered. // TODO: remove the following lions as soon as we support non zero values if ( beep->z != 0 ) return -1; if ( beep->y != 0 ) return -1; ROAR_DBG("beep_start(client=%i, beep=%p) = ?", client, beep); if ((stream = streams_new()) == -1 ) return -1; ROAR_DBG("beep_start(client=%i, beep=%p): stream=%i", client, beep, stream); if ( client_stream_add(client, stream) == -1 ) { streams_delete(stream); return -1; } if ( streams_set_name(stream, "Beep Source") == -1 ) { streams_delete(stream); return -1; } if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); return -1; } s = ROAR_STREAM(ss); memcpy(&(s->info), g_sa, sizeof(s->info)); s->info.channels = 2; s->info.bits = 8; ss->mixer.mixer[0] = beep->x > 0 ? ((long)beep->vol * ((long)ROAR_BEEP_MAX_POS - (long)beep->x)/(long)ROAR_BEEP_MAX_POS) : beep->vol; ss->mixer.mixer[1] = beep->x < 0 ? ((long)beep->vol * ((long)ROAR_BEEP_MAX_POS + (long)beep->x)/(long)ROAR_BEEP_MAX_POS) : beep->vol; ss->mixer.scale = ROAR_BEEP_MAX_VOL; ROAR_DBG("beep_start(client=%i, beep=%p): beep->x=%i, ss->mixer.mixer[] = {%u, %u}", client, beep, beep->x, ss->mixer.mixer[0], ss->mixer.mixer[1]); if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) { streams_delete(stream); return -1; } if ( streams_set_role(stream, ROAR_ROLE_BEEP) == -1 ) { streams_delete(stream); return -1; } if ( (buf = beep_fill_buffer(beep, &(s->info))) == NULL ) { streams_delete(stream); return -1; } ROAR_DBG("beep_start(client=%i, beep=%p): buf=%p", client, beep, buf); beep_init_vio(&(ss->vio), buf); if ( streams_set_fh(stream, -2) == -1 ) { streams_delete(stream); return -1; } ROAR_DBG("beep_start(client=%i, beep=%p) = %i", client, beep, stream); return stream; } //ll roaraudio-1.0beta11/roard/caps.c0000644000175000017500000000450012264733653014672 0ustar phiphi//caps.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" static uint32_t _g_caps_standards[] = { // message formats: ROAR_STD_MAKE(ROAR_STDV_ROARAUDIO, 0, 0), // v. 0 // command sets: ROAR_STD_MAKE(ROAR_STDV_ROARAUDIO, 4, 0), // basic commands // well known numbers: ROAR_STD_MAKE(ROAR_STDV_ROARAUDIO, 12, 0), // codecs // transports: #ifdef ROAR_HAVE_UNIX ROAR_STD_MAKE(ROAR_STDV_ROARAUDIO, 23, 0), // UNIX #endif #ifdef ROAR_HAVE_LIBDNET ROAR_STD_MAKE(ROAR_STDV_ROARAUDIO, 24, 0), // DECnet #endif #ifdef ROAR_HAVE_IPV4 ROAR_STD_MAKE(ROAR_STDV_ROARAUDIO, 25, 0), // TCP #endif 0xFFFFFFFF // terminater }; struct roar_stds g_caps_stds = { .stds_len = (sizeof(_g_caps_standards)/sizeof(*_g_caps_standards)) - 1, .stds = _g_caps_standards }; char * stds_string (void) { size_t len = g_caps_stds.stds_len * 14; char * ret = roar_mm_malloc(len); size_t off = 0; size_t i; int snpret; uint32_t cap; int version; if ( ret == NULL ) return NULL; for (i = 0; i < g_caps_stds.stds_len; i++) { cap = g_caps_stds.stds[i]; version = ROAR_STD_VERSION(cap); if ( version == 0 ) { snpret = snprintf(ret+off, len-off, "%i-%i,", (int)ROAR_STD_VENDOR(cap), (int)ROAR_STD_STD(cap)); } else { snpret = snprintf(ret+off, len-off, "%i-%i-%i,", (int)ROAR_STD_VENDOR(cap), (int)ROAR_STD_STD(cap), (int)version); } if ( snpret > 0 ) { off += snpret; } else { roar_mm_free(ret); return NULL; } } ret[off-1] = 0; return ret; } //ll roaraudio-1.0beta11/roard/clients.c0000644000175000017500000010201212264733653015402 0ustar phiphi//clients.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * ckport: ignore-symbol: roar_event_to_blob of target libroar0 */ #include "roard.h" // declared 'extern' struct roar_client_server * g_clients[ROAR_CLIENTS_MAX]; static struct roard_proto_handle __protos[MAX_PROTOS] = { {.proto = ROAR_PROTO_ROARAUDIO, .lhandle = NULL, .type = ROARD_PROTO_TYPE_BUILDIN, .impl = {.buildin = 0}}, {.proto = -1} }; #define _CHECK_CID_RET(id,ret) if ( (id) < 0 || (id) > ROAR_CLIENTS_MAX || g_clients[(id)] == NULL ) return (ret) #define _CHECK_CID(id) _CHECK_CID_RET((id), -1) int clients_init (void) { int i; for (i = 0; i < ROAR_CLIENTS_MAX; i++) g_clients[i] = NULL; for (i = 0; __protos[i].proto != -1; i++); for (; i < MAX_PROTOS; i++) __protos[i].proto = -1; return 0; } int clients_free (void) { int i; for (i = 0; i < ROAR_CLIENTS_MAX; i++) if ( g_clients[i] != NULL ) clients_delete(i); return 0; } int clients_new (void) { int i; int s; struct roar_client_server * ns; struct roar_client * n; for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( g_clients[i] == NULL ) { ns = roar_mm_malloc(sizeof(struct roar_client_server)); n = ROAR_CLIENT(ns); memset(ns, 0, sizeof(struct roar_client_server)); if ( n != NULL ) { n->pid = -1; n->uid = -1; n->gid = -1; n->fh = -1; *n->name = 0; n->proto = ROAR_PROTO_ROARAUDIO; n->byteorder = ROAR_BYTEORDER_NETWORK; n->acl = NULL; n->execed = -1; for (s = 0; s < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; s++) n->streams[s] = -1; if ( roar_nnode_new(&(n->nnode), ROAR_SOCKET_TYPE_UNKNOWN) == -1 ) { roar_mm_free(n); return -1; } ns->blockc = 0; ns->waits = NULL; ns->acclev = ACCLEV_NONE; g_clients[i] = ns; counters_inc(clients, 1); roar_notify_core_emit_snoargs(ROAR_OE_BASICS_NEW, -1, i, ROAR_OT_CLIENT); ROAR_DBG("clients_new(void) = %i", i); return i; } else { ROAR_ERR("clients_new(void): Can not alloc memory for new client: %s", strerror(errno)); ROAR_ERR("clients_new(void) = -1"); return -1; } } } return -1; } int clients_new_from_fh(int fh, int proto, int byteorder, int update_nnode) { return clients_new_from_fh2(fh, proto, byteorder, update_nnode, NULL, NULL, 0); } int clients_new_from_fh2(int fh, int proto, int byteorder, int update_nnode, struct roard_listen * lsock, struct sockaddr * sockaddr, socklen_t addrlen) { const struct roard_proto_handle * protohandle; struct roar_dl_librarypara * pluginpara; struct roar_vio_calls vio; struct roar_client_server * cs; int supported = 0; int client; if ( fh == -1 ) { roar_err_set(ROAR_ERROR_BADFH); return -1; } if ( lsock == NULL ) { switch (proto) { case ROAR_PROTO_RSOUND: case ROAR_PROTO_SIMPLE: roar_err_set(ROAR_ERROR_FAULT); return -1; break; } } if ( byteorder != ROAR_BYTEORDER_NETWORK ) return -1; if ( proto == ROAR_PROTO_RSOUND ) { #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND client = emul_rsound_on_connect(fh, lsock); switch (client) { case -1: return -1; break; case -2: return 0; break; default: // TODO: write error handling fh = ROAR_CLIENT(cs)->fh; break; } #else roar_err_set(ROAR_ERROR_PROTONOSUP); return -1; #endif } else { client = clients_new(); if ( client == -1 ) { ROAR_DBG("clients_new_from_fh2(*) = -1 // can not create new client"); return -1; } if ( clients_set_fh(client, fh) == -1 ) { ROAR_ERR("clients_new_from_fh2(*): Can not set client's fh"); clients_delete(client); ROAR_DBG("clients_new_from_fh2(*) = -1"); return -1; } } if ( clients_get_server(client, &cs) == -1 ) { clients_delete(client); return -1; } if ( update_nnode ) { if ( roar_nnode_free(&(ROAR_CLIENT(cs)->nnode)) != -1 ) { if ( sockaddr != NULL && addrlen != 0 ) { roar_nnode_new_from_sockaddr(&(ROAR_CLIENT(cs)->nnode), sockaddr, addrlen); } else { roar_nnode_new_from_fh(&(ROAR_CLIENT(cs)->nnode), fh, 1); } } } if ( clients_set_proto(client, proto) == -1 ) { ROAR_WARN("clients_new_from_fh2(*): Setting proto(0x%.4x) of client %i failed.", proto, client); clients_delete(client); return -1; } switch (proto) { case ROAR_PROTO_ROARAUDIO: // nothing needed to be done here break; #ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE case ROAR_PROTO_SIMPLE: if ( emul_simple_on_connect(client, lsock) == -1 ) return -1; break; #endif #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND case ROAR_PROTO_RSOUND: // nothing to do here. break; #endif default: // OS independiend code to close the socket: if ( roar_vio_open_fh_socket(&vio, fh) == -1 ) return -1; protohandle = clients_get_protohandle(proto); supported = 0; if ( protohandle != NULL ) { if ( protohandle->lhandle != NULL ) roar_dl_context_restore(protohandle->lhandle); switch (protohandle->type) { case ROARD_PROTO_TYPE_BUILDIN: //this should not end up here. ROAR_WARN("net_get_new_client(lsock=%p): proto(%i) marked as buildin but isn't. BAD.", lsock, proto); supported = 0; break; case ROARD_PROTO_TYPE_COMMON: supported = 1; if ( protohandle->impl.common->set_proto != NULL ) { pluginpara = roar_dl_getpara(protohandle->lhandle); // will return NULL in case protohandle->lhandle is NULL. if ( protohandle->impl.common->set_proto(client, &vio, &(cs->outbuf), &(cs->protoinst), protohandle->para, protohandle->paralen, pluginpara) == -1 ) { supported = 0; } if ( pluginpara != NULL ) roar_dl_para_unref(pluginpara); } break; } if ( protohandle->lhandle != NULL ) roar_dl_context_store(protohandle->lhandle); } if ( !supported ) { clients_delete(client); //roar_vio_close(&vio); return -1; } break; } return 0; } int clients_delete (int id) { struct roar_client_server * cs; const struct roard_proto_handle * proto; struct roar_dl_librarypara * pluginpara; struct roar_vio_calls vio; int i; int close_client_fh = 1; ROAR_DBG("clients_delete(id=%i) = ?", id); _CHECK_CID(id); cs = g_clients[id]; proto = clients_get_protohandle(ROAR_CLIENT(cs)->proto); if ( proto != NULL ) { if ( proto->lhandle != NULL ) roar_dl_context_restore(proto->lhandle); switch (proto->type) { case ROARD_PROTO_TYPE_BUILDIN: /* noop */ break; case ROARD_PROTO_TYPE_COMMON: if ( proto->impl.common->unset_proto != NULL ) { roar_vio_open_fh_socket(&vio, clients_get_fh(id)); pluginpara = roar_dl_getpara(proto->lhandle); // will return NULL in case protohandle->lhandle is NULL. proto->impl.common->unset_proto(id, &vio, &(cs->outbuf), &(cs->protoinst), proto->para, proto->paralen, pluginpara); if ( pluginpara != NULL ) roar_dl_para_unref(pluginpara); } break; } if ( proto->lhandle != NULL ) roar_dl_context_store(proto->lhandle); } if ( cs->waits != NULL ) { for (i = 0; cs->waits[i] != NULL; i++) roar_notify_core_unsubscribe(NULL, cs->waits[i]); roar_mm_free(cs->waits); cs->waits = NULL; } roar_notify_core_emit_snoargs(ROAR_OE_BASICS_DELETE, -1, id, ROAR_OT_CLIENT); counters_inc(clients, -1); if (ROAR_CLIENT(cs)->execed != -1) { // return streams_delete(g_clients[id]->execed); ROAR_CLIENT(cs)->execed = -1; close_client_fh = 0; } for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) { streams_delete(ROAR_CLIENT(cs)->streams[i]); } if ( ROAR_CLIENT(cs)->fh != -1 && close_client_fh ) close(ROAR_CLIENT(cs)->fh); roar_nnode_free(&(ROAR_CLIENT(cs)->nnode)); if ( cs->inbuf != NULL ) roar_buffer_free(cs->inbuf); if ( cs->outbuf != NULL ) roar_buffer_free(cs->outbuf); if ( cs->protoinst != NULL ) roar_mm_free(cs->protoinst); roar_mm_free(cs); g_clients[id] = NULL; ROAR_DBG("clients_delete(id=%i) = 0", id); return 0; } int clients_close (int id, int nocheck_exec) { struct roar_client * c; ROAR_DBG("clients_close(id=%i) = ?", id); _CHECK_CID(id); c = ROAR_CLIENT(g_clients[id]); if ( c->fh == -1 ) { ROAR_DBG("clients_delete(id=%i) = 0", id); return 0; } if (nocheck_exec || c->execed != -1) { close(c->fh); c->fh = -1; } ROAR_DBG("clients_delete(id=%i) = 0", id); return 0; } int clients_get (int id, struct roar_client ** client) { _CHECK_CID(id); *client = ROAR_CLIENT(g_clients[id]); if ( *client == NULL ) return -1; return 0; } int clients_get_server (int id, struct roar_client_server ** client) { _CHECK_CID(id); *client = g_clients[id]; if ( *client == NULL ) return -1; return 0; } int clients_set_fh (int id, int fh) { struct roar_client * c; #if defined(SO_PEERCRED) && !defined(ROAR_BROKEN_PEERCRED) struct ucred cred; socklen_t cred_len = sizeof(cred); #endif _CHECK_CID(id); if ( (c = ROAR_CLIENT(g_clients[id])) == NULL ) return -1; c->fh = fh; if ( fh == -1 ) return 0; #if defined(SO_PEERCRED) && !defined(ROAR_BROKEN_PEERCRED) if (getsockopt(fh, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len) != -1) { if ( cred.pid != 0 ) { c->pid = cred.pid; c->uid = cred.uid; c->gid = cred.gid; } } else { ROAR_DBG("req_on_identify(): Can't get creds via SO_PEERCRED: %s", strerror(errno)); } #elif defined(ROAR_HAVE_GETPEEREID) if (getpeereid(fh, &(c->uid), &(c->gid)) == -1) { ROAR_DBG("req_on_identify(): Can't get creds via getpeereid(): %s", strerror(errno)); } #endif return 0; } int clients_get_fh (int id) { _CHECK_CID(id); return ROAR_CLIENT(g_clients[id])->fh; } int clients_set_pid (int id, int pid) { _CHECK_CID(id); ROAR_CLIENT(g_clients[id])->pid = pid; return 0; } int clients_set_uid (int id, int uid) { _CHECK_CID(id); ROAR_CLIENT(g_clients[id])->uid = uid; return 0; } int clients_set_gid (int id, int gid) { _CHECK_CID(id); ROAR_CLIENT(g_clients[id])->gid = gid; return 0; } int clients_set_name (int id, const char * name) { _CHECK_CID(id); strncpy(ROAR_CLIENT(g_clients[id])->name, name, ROAR_BUFFER_NAME-1); ROAR_CLIENT(g_clients[id])->name[ROAR_BUFFER_NAME-1] = 0; return 0; } int clients_set_proto (int id, int proto) { int byteorder = ROAR_BYTEORDER_UNKNOWN; _CHECK_CID(id); switch (proto) { case ROAR_PROTO_ROARAUDIO: case ROAR_PROTO_ESOUND: case ROAR_PROTO_RPLAY: case ROAR_PROTO_SIMPLE: byteorder = ROAR_BYTEORDER_NETWORK; break; } ROAR_CLIENT(g_clients[id])->proto = proto; ROAR_CLIENT(g_clients[id])->byteorder = byteorder; return 0; } int clients_block (int id, int unblock) { _CHECK_CID(id); if ( unblock ) { g_clients[id]->blockc--; } else { g_clients[id]->blockc++; } return 0; } #define MAX_STREAMLESS 8 int clients_check_all (void) { #ifdef ROAR_HAVE_SELECT struct roar_client * c; struct timeval tv; fd_set r, w, e; int i, j; int ret; int fh; int max_fh = -1; int have = 0; struct { int id; int fh; } streamless[MAX_STREAMLESS]; int have_streamless = 0; int have_stream; ROAR_DBG("clients_check_all(void) = ?"); FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e); tv.tv_sec = 0; tv.tv_usec = 1; for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( (c = ROAR_CLIENT(g_clients[i])) == NULL ) continue; ROAR_DBG("clients_check_all(void): i(client)=%i", i); if ( (fh = c->fh) != -1 ) { have++; ROAR_DBG("clients_check_all(*): fh=%i", fh); FD_SET(fh, &r); FD_SET(fh, &e); if ( g_clients[i]->outbuf != NULL ) { FD_SET(fh, &w); } if ( fh > max_fh ) max_fh = fh; } have_stream = 0; for (j = 0; j < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; j++) { ROAR_DBG("clients_check_all(void): i(client)=%i, j(stream)=%i", i, j); if ( (fh = streams_get_fh(c->streams[j])) != -1 ) { ROAR_DBG("clients_check_all(*): g_clients[i=%i]->streams[j=%i] = %i, fh = %i", i, j, c->streams[j], fh); if ( fh > -1 ) { FD_SET(fh, &r); if ( fh > max_fh ) max_fh = fh; } else if ( fh == -2 ) { streams_check(c->streams[j]); } have_stream = 1; } //printf("D: client=%i, stream=%i, fh=%i\n", i, j, fh); } if ( !have_stream && have_streamless < MAX_STREAMLESS ) { streamless[have_streamless ].id = i; if ( (streamless[have_streamless++].fh = c->fh) == -1 ) have_streamless--; } } ROAR_DBG("clients_check_all(void): max_fh=%i", max_fh); if ( max_fh == -1 ) return 0; if ( (ret = select(max_fh + 1, &r, &w, &e, &tv)) < 1 ) { return ret < 0 ? ret : have; } for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( (c = ROAR_CLIENT(g_clients[i])) == NULL ) continue; if ( (fh = c->fh) != -1 ) { if ( FD_ISSET(fh, &r) ) { if ( c->execed == -1 ) { clients_check(i); if ( g_clients[i] != NULL && ROAR_CLIENT(g_clients[i])->execed != -1 ) { FD_CLR(fh, &r); } /* } else { streams_check(g_clients[i]->execed); */ } } if ( FD_ISSET(fh, &w) ) { clients_flush(i); } if ( FD_ISSET(fh, &e) ) { clients_delete(i); continue; } } if ( (c = ROAR_CLIENT(g_clients[i])) == NULL ) continue; for (j = 0; j < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; j++) { ROAR_DBG("clients_check_all(*): D: client=%i, stream=%i, g_clients[i=%i] = %p", i, j, i, g_clients[i]); if ( g_clients[i] == NULL ) // streams_check() bellow can delete our client (why?) break; //ROAR_WARN("clients_check_all(*): client=%i: client exists", i); ROAR_DBG("clients_check_all(*): client=%i, stream=%i: id=%i", i, j, c->streams[j]); if ( (fh = streams_get_fh(c->streams[j])) != -1 ) { ROAR_DBG("clients_check_all(*): client=%i, stream=%i: fh=%i", i, j, fh); if ( fh > -1 && FD_ISSET(fh, &r) ) { streams_check(c->streams[j]); } } } } if ( have_streamless ) { FD_ZERO(&r); FD_ZERO(&w); tv.tv_sec = 0; tv.tv_usec = 1; max_fh = -1; for (i = 0; i < have_streamless; i++) { if ( g_clients[j = streamless[i].id] == NULL ) continue; if ( ROAR_CLIENT(g_clients[j])->execed != -1 ) continue; fh = streamless[i].fh; ROAR_DBG("clients_check_all(void): fh=%i", fh); FD_SET(fh, &r); if ( g_clients[j]->outbuf != NULL ) { FD_SET(fh, &w); } if ( fh > max_fh ) max_fh = fh; } if ( (ret = select(max_fh + 1, &r, &w, NULL, &tv)) < 0 ) { return ret; } for (i = 0; i < have_streamless; i++) { if ( FD_ISSET(streamless[i].fh, &r) ) { clients_check(streamless[i].id); } if ( FD_ISSET(streamless[i].fh, &w) ) { clients_flush(streamless[i].id); } } } ROAR_DBG("clients_check_all(void) = %i // have value", have); return have; #else ROAR_DBG("clients_check_all(void) = -1"); return -1; #endif } int clients_check (int id) { struct roar_client_server * cs; struct roar_message m; struct roar_connection con; struct roar_vio_calls vio; struct roar_error_state errstate; const struct roard_proto_handle * proto; struct roar_dl_librarypara * pluginpara; int command_error; char * data = NULL; int oldcmd; int r; int rv = 0; uint32_t flags[2] = {COMMAND_FLAG_NONE, COMMAND_FLAG_NONE}; uint32_t event; ROAR_DBG("clients_check(id=%i) = ?", id); _CHECK_CID(id); cs = g_clients[id]; if ( ROAR_CLIENT(cs)->fh == -1 ) return -1; if ( roar_connect_fh(&con, ROAR_CLIENT(cs)->fh) == -1 ) { ROAR_WARN("clients_check(id=%i): Can not create con object for client: %s", id, roar_errorstring); } ROAR_DBG("clients_check(id=%i): c->proto=%i", id, ROAR_CLIENT(cs)->proto); switch (ROAR_CLIENT(cs)->proto) { case ROAR_PROTO_ROARAUDIO: r = roar_recv_message(&con, &m, &data); if ( r == -1 ) { // should we drop the client? clients_delete(id); return -1; } event = ROAR_NOTIFY_CMD2EVENT(m.cmd); oldcmd = m.cmd; roar_err_store(&errstate); roar_err_clear_all(); r = command_exec(id, &m, &data, flags); roar_err_update(); command_error = roar_error; roar_err_restore(&errstate); if ( r == -1 ) { // use command_error to create an error frame here as soon as this is supported. m.cmd = ROAR_CMD_ERROR; m.datalen = 0; ROAR_DBG("clients_check(*): Exec of command faild!"); } else { if ( m.cmd == oldcmd ) { m.cmd = ROAR_CMD_OK; m.datalen = 0; } else if ( m.cmd == ROAR_CMD_OK_STOP ) { m.cmd = ROAR_CMD_OK; rv = 1; } } ROAR_DBG("clients_check(*): data=%p", data); if ( flags[1] & COMMAND_FLAG_OUT_NOSEND ) { roar_notify_core_emit_simple(event, id, -1, -1, -1, -1, NULL, 0); } else { roar_notify_core_emit_simple(event, id, -1, -1, m.cmd, -1, NULL, 0); if ( roar_send_message(&con, &m, flags[1] & COMMAND_FLAG_OUT_LONGDATA ? data : NULL) == -1 ) { ROAR_WARN("clients_check(id=%i): Can not send answer to client: %s", id, roar_errorstring); } } if ( flags[1] & COMMAND_FLAG_OUT_CLOSECON ) clients_close(id, 1); if ( flags[1] & COMMAND_FLAG_OUT_DELETE ) clients_delete(id); break; #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND case ROAR_PROTO_RSOUND: rv = emul_rsound_check_client(id, NULL); if ( rv == 0 ) { // loop as long as we don't get an error. while (rv == 0) rv = emul_rsound_check_client(id, NULL); rv = 0; // restore } else { // in case of error delete the client if ( #ifdef EAGAIN errno != EAGAIN && #endif #ifdef EWOULDBLOCK errno != EWOULDBLOCK && #endif #ifdef EINTR errno != EINTR && #endif 1 ) { rv = clients_delete(id); } else { rv = 0; } } break; #endif default: rv = -1; proto = clients_get_protohandle(ROAR_CLIENT(cs)->proto); if ( proto != NULL ) { roar_vio_open_fh_socket(&vio, clients_get_fh(id)); if ( proto->lhandle != NULL ) roar_dl_context_restore(proto->lhandle); switch (proto->type) { case ROARD_PROTO_TYPE_BUILDIN: ROAR_WARN("clients_check(id=%i): proto(%i) marked as buildin but isn't. BAD.", id, proto->proto); break; case ROARD_PROTO_TYPE_COMMON: if ( proto->impl.common->handle != NULL ) { pluginpara = roar_dl_getpara(proto->lhandle); // will return NULL in case protohandle->lhandle is NULL. rv = proto->impl.common->handle(id, &vio, &(cs->outbuf), &(cs->protoinst), proto->para, proto->paralen, pluginpara); if ( pluginpara != NULL ) roar_dl_para_unref(pluginpara); } if ( rv == -1 ) rv = clients_delete(id); break; } if ( proto->lhandle != NULL ) roar_dl_context_store(proto->lhandle); } } if ( data != NULL ) roar_mm_free(data); ROAR_DBG("clients_check(id=%i) = %i", id, rv); return rv; } int clients_flush (int id) { struct roar_vio_calls vio; struct roar_client_server * cs; struct roar_client * c; const struct roard_proto_handle * p; struct roar_dl_librarypara * pluginpara; size_t len; ssize_t ret; void * buf; int rv; _CHECK_CID(id); c = ROAR_CLIENT(cs = g_clients[id]); p = clients_get_protohandle(c->proto); if ( p == NULL ) return -1; roar_vio_open_fh_socket(&vio, clients_get_fh(id)); switch (p->type) { case ROARD_PROTO_TYPE_BUILDIN: /* noop */ break; case ROARD_PROTO_TYPE_COMMON: if ( p->impl.common->flush != NULL ) { if ( p->lhandle != NULL ) roar_dl_context_restore(p->lhandle); pluginpara = roar_dl_getpara(p->lhandle); // will return NULL in case protohandle->lhandle is NULL. rv = p->impl.common->flush(id, &vio, &(cs->outbuf), &(cs->protoinst), p->para, p->paralen, pluginpara); if ( p->lhandle != NULL ) roar_dl_context_store(p->lhandle); if ( pluginpara != NULL ) roar_dl_para_unref(pluginpara); if ( rv == -1 ) rv = clients_delete(id); return rv; } break; } if ( roar_buffer_get_len(cs->outbuf, &len) == -1 ) return -1; if ( roar_buffer_get_data(cs->outbuf, &buf) == -1 ) return -1; ret = roar_vio_write(&vio, buf, len); if ( ret < 1 && !(len == 0 && ret == 0) ) { clients_delete(id); return -1; } if ( ret == (ssize_t)len ) { if ( roar_buffer_next(&(cs->outbuf)) == -1 ) { clients_delete(id); return -1; } } else { if ( roar_buffer_set_offset(cs->outbuf, ret) == -1 ) { clients_delete(id); return -1; } } if ( cs->outbuf == NULL ) { switch (p->type) { case ROARD_PROTO_TYPE_BUILDIN: /* noop */ break; case ROARD_PROTO_TYPE_COMMON: if ( p->impl.common->flushed != NULL ) { if ( p->lhandle != NULL ) roar_dl_context_restore(p->lhandle); pluginpara = roar_dl_getpara(p->lhandle); // will return NULL in case protohandle->lhandle is NULL. rv = p->impl.common->flushed(id, &vio, &(cs->outbuf), &(cs->protoinst), p->para, p->paralen, pluginpara); if ( p->lhandle != NULL ) roar_dl_context_store(p->lhandle); if ( pluginpara != NULL ) roar_dl_para_unref(pluginpara); if ( rv == -1 ) rv = clients_delete(id); return rv; } break; } } return 0; } int clients_send_mon (struct roar_audio_info * sa) { int i; // int fh; int j; int keep_going; for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( g_clients[i] == NULL ) continue; keep_going = 1; /* if ( (fh = g_clients[i]->fh) == -1 ) continue; */ ROAR_DBG("clients_send_mon(*): client=%i, execed=%i", i, ROAR_CLIENT(g_clients[i])->execed); /* if ( g_clients[i]->execed == -1 ) { // TODO: add some code to send a message to the client insetd of the raw data. */ for (j = 0; keep_going && j < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; j++) { //if ( (fh = streams_get_fh(g_clients[i]->streams[j])) != -1 ) { ROAR_DBG("clients_send_mon(*): client=%i, stream=%i -> ?", i, j); if ( ROAR_CLIENT(g_clients[i])->streams[j] != -1 ) { ROAR_DBG("clients_send_mon(*): client=%i, stream=%i -> %i", i, j, ROAR_CLIENT(g_clients[i])->streams[j]); streams_send_mon(ROAR_CLIENT(g_clients[i])->streams[j]); // the client may be deleted here, check if it still exists: if ( g_clients[i] == NULL ) keep_going = 0; } } /* } else { // streams_check(g_clients[i]->execed); streams_send_mon(g_clients[i]->execed); // if ( streams_send_mon(g_clients[i]->execed) == -1 ) // clients_delete(i); // delete client in case we could not write } */ } // TODO: FIXME: should this really be -1? return -1; } int clients_send_filter(struct roar_audio_info * sa) { struct roar_client * c; int i; int fh; for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( (c = ROAR_CLIENT(g_clients[i])) == NULL ) continue; if ( (fh = c->fh) == -1 ) continue; if ( c->execed == -1 ) { // TODO: add some code to send a message to the client insetd of the raw data. } else { // streams_check(g_clients[i]->execed); streams_send_filter(c->execed); // if ( streams_send_mon(g_clients[i]->execed) == -1 ) // clients_delete(i); // delete client in case we could not write } } return -1; } int clients_add_output (int id, struct roar_buffer ** buf) { struct roar_client_server * cs; _CHECK_CID(id); cs = g_clients[id]; if ( cs->outbuf == NULL ) { cs->outbuf = *buf; } else { return roar_buffer_moveinto(cs->outbuf, buf); } return 0; } // proto support const struct roard_proto_handle * clients_get_protohandle(const int proto) { size_t i; if ( proto < 0 ) { roar_err_set(ROAR_ERROR_INVAL); return NULL; } for (i = 0; i < (sizeof(__protos)/sizeof(*__protos)); i++) if ( __protos[i].proto == proto ) return &(__protos[i]); roar_err_set(ROAR_ERROR_NOENT); return NULL; } int clients_register_proto_common(const struct roar_dl_proto * proto, struct roar_dl_lhandle * lhandle) { const size_t len = sizeof(__protos)/sizeof(*__protos); size_t i; ROAR_DBG("clients_register_proto_common(proto=%p, lhandle=%p) = ?", proto, lhandle); if ( proto == NULL ) return -1; for (i = 0; __protos[i].proto != -1; i++); // i is now at pos of current EOS entry. // test if we have space for one more entry: if ( (i+1) >= len ) return -1; __protos[i].impl.common = proto; __protos[i].proto = proto->proto; __protos[i].type = ROARD_PROTO_TYPE_COMMON; __protos[i].lhandle = lhandle; return 0; } int clients_unregister_proto(int proto) { size_t i; if ( proto < 0 ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } for (i = 0; i < (sizeof(__protos)/sizeof(*__protos)); i++) { if ( __protos[i].proto == proto ) { memset(&(__protos[i]), 0, sizeof(*__protos)); __protos[i].proto = -1; return 0; } } roar_err_set(ROAR_ERROR_NOENT); return -1; } void print_protolist (enum output_format format) { struct roard_proto_handle * p; char flags[5] = " "; char subsys[7] = " "; const char * description; size_t i; switch (format) { case FORMAT_NATIVE: printf(" Protocol Flag Subsys - Description\n"); printf("------------------------------------------------------\n"); printf(" roar bb WM LRX - RoarAudio native protocol\n"); #ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE printf(" simple bb WM LRX - PulseAudio simple protocol\n"); #endif #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND printf(" rsound bb W - RSound emulation\n"); #endif break; case FORMAT_WIKI: printf("||=Protocol =||=Flag =||=Subsys =||=Description =||\n"); printf("||roar ||bb ||WM LRX ||RoarAudio native protocol ||\n"); #ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE printf("||simple ||bb ||WM LRX ||PulseAudio simple protocol ||\n"); #endif #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND printf("||rsound ||bb ||W ||RSound emulation ||\n"); #endif break; case FORMAT_CSV: printf("Protocol,Flag,Subsys,Description\n"); printf("roar,bb,WM LRX,RoarAudio native protocol\n"); #ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE printf("simple,bb,WM LRX,PulseAudio simple protocol\n"); #endif #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND printf("rsound,bb,W,RSound emulation\n"); #endif break; default: roar_err_set(ROAR_ERROR_NOTSUP); return; } for (i = 0; i < (sizeof(__protos)/sizeof(*__protos)); i++) { p = &(__protos[i]); if ( p->proto == -1 ) continue; strncpy(flags, " ", 4); strncpy(subsys, " ", 6); description = "(none)"; if ( p->lhandle != NULL ) { flags[0] = 'P'; } else { flags[0] = 'b'; } switch (p->type) { case ROARD_PROTO_TYPE_BUILDIN: continue; break; case ROARD_PROTO_TYPE_COMMON: flags[1] = 'C'; description = p->impl.common->description; break; } switch (format) { case FORMAT_NATIVE: printf(" %-8s %s %s - %s\n", roar_proto2str(p->proto), flags, subsys, description); break; case FORMAT_WIKI: printf("||%s ||%s ||%s ||%s ||\n", roar_proto2str(p->proto), flags, subsys, description); break; case FORMAT_CSV: printf("%s,%s,%s,%s\n", roar_proto2str(p->proto), flags, subsys, description); break; } } } int client_stream_exec (int client, int stream) { struct roar_client * c; int i; int fh; _CHECK_CID(client); #if 0 if ( g_clients[client] == NULL ) { ROAR_WARN("client_stream_exec(client=%i, stream=%i) = -1 // client does not exist", client, stream); return -1; } #endif c = ROAR_CLIENT(g_clients[client]); for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) { if ( c->streams[i] == stream ) { c->execed = stream; if ( streams_is_ready(stream) == 0 ) { streams_set_fh(stream, c->fh); streams_set_socktype(stream, ROAR_SOCKET_TYPE_GENSTR); } else { ROAR_DBG("client_stream_exec(client=%i, stream=%i): fh=?", client, stream); if ( (fh = c->fh) != -1 ) { close(fh); c->fh = -1; } } ROAR_DBG("client_stream_exec(client=%i, stream=%i) = 0", client, stream); return 0; } } ROAR_WARN("client_stream_exec(client=%i, stream=%i) = -1 // client does not own stream", client, stream); return -1; } int client_stream_set_fh (int client, int stream, int fh) { int i; ROAR_DBG("client_stream_set_fh(client=%i, stream=%i, fh=%i) = ?", client, stream, fh); _CHECK_CID(client); for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) { if ( ROAR_CLIENT(g_clients[client])->streams[i] == stream ) { ROAR_DBG("client_stream_set_fh(client=%i, stream=%i, fh=%i): stream found, index %i", client, stream, fh, i); return streams_set_fh(stream, fh); } } ROAR_WARN("client_stream_set_fh(client=%i, stream=%i, fh=%i) = -1 // client does not own stream", client, stream, fh); return -1; } int client_stream_add (int client, int stream) { int i; _CHECK_CID(client); for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) { if ( ROAR_CLIENT(g_clients[client])->streams[i] == -1 ) { ROAR_CLIENT(g_clients[client])->streams[i] = stream; streams_set_client(stream, client); return 0; } } return -1; } int client_stream_delete (int client, int stream) { int i; _CHECK_CID(client); for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) { if ( ROAR_CLIENT(g_clients[client])->streams[i] == stream ) { ROAR_CLIENT(g_clients[client])->streams[i] = -1; if ( stream == ROAR_CLIENT(g_clients[client])->execed ) { ROAR_DBG("client_stream_delete(client=%i, stream=%i): stream is execed one, deleting client!", client, stream); clients_delete(client); } ROAR_DBG("client_stream_delete(client=%i, stream=%i) = 0", client, stream); return 0; } } ROAR_DBG("client_stream_delete(client=%i, stream=%i) = -1", client, stream); return -1; } int client_stream_move (int client, int stream) { int old_client = streams_get_client(stream); ROAR_DBG("client_stream_move(client=%i, stream=%i): old_client = %i", client, stream, old_client); if ( old_client != -1 ) if ( client_stream_delete(old_client, stream) == -1 ) return -1; return client_stream_add(client, stream); } // notify thingys int clients_wait (int client, struct roar_event * events, size_t num) { struct roar_client_server * cs; size_t i, c; ROAR_DBG("clients_wait(client=%i, events=%p, num=%llu) = ?", client, events, (long long unsigned int)num); _CHECK_CID(client); cs = g_clients[client]; if ( cs->waits != NULL ) return -1; cs->waits = roar_mm_malloc((num+1) * sizeof(struct roar_subscriber *)); if ( cs->waits == NULL ) return -1; if ( clients_block(client, 0) != 0 ) return -1; for (i = 0; i < num; i++) { #if defined(DEBUG) && 0 dbg_notify_cb(NULL, &(events[i]), cs); #endif cs->waits[i] = roar_notify_core_subscribe(NULL, &(events[i]), clients_ncb_wait, cs); if ( cs->waits[i] == NULL ) { for (c = 0; c < i; c++) roar_notify_core_unsubscribe(NULL, cs->waits[c]); roar_mm_free(cs->waits); cs->waits = NULL; clients_block(client, 1); return -1; } } cs->waits[num] = NULL; ROAR_DBG("clients_wait(client=%i, events=%p, num=%llu) = 0", client, events, (long long unsigned int)num); return 0; } void clients_ncb_wait(struct roar_notify_core * core, struct roar_event * event, void * userdata) { struct roar_client_server * cs = userdata; struct roar_message m; struct roar_connection con; uint16_t * u16 = (uint16_t *) m.data; size_t tmp; size_t i; ROAR_DBG("clients_ncb_wait(core=%p, event=%p, userdata=%p) = ?", core, event, userdata); for (i = 0; cs->waits[i] != NULL; i++) roar_notify_core_unsubscribe(NULL, cs->waits[i]); roar_mm_free(cs->waits); cs->waits = NULL; // protocol depended handling... memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_OK; u16[0] = ROAR_HOST2NET16(0); // Version u16[1] = ROAR_HOST2NET16(0); // flags tmp = sizeof(m.data) - 4; roar_event_to_blob(event, m.data + 4, &tmp); m.datalen = tmp + 4; roar_connect_fh(&con, ROAR_CLIENT(cs)->fh); roar_send_message(&con, &m, NULL); // ...end of protocol depended handling. // clients_block(, 1); // TODO: FIXME: bad hack... cs->blockc--; } // acclev: static struct { const enum roard_client_acclev acclev; const char * name; } _g_acclevs[] = { {ACCLEV_NONE, "none" }, {ACCLEV_IDENTED, "idented"}, {ACCLEV_CONCTL, "conctl" }, {ACCLEV_GUEST, "guest" }, {ACCLEV_USER, "user" }, {ACCLEV_PWRUSER, "pwruser"}, {ACCLEV_ALL, "all" }, {-1, NULL} }; enum roard_client_acclev clients_str2acclev(const char * acclev) { int i; for (i = 0; _g_acclevs[i].name != NULL; i++) if ( !strcasecmp(_g_acclevs[i].name, acclev) ) return _g_acclevs[i].acclev; return ACCLEV_ERROR; } const char * clients_acclev2str(const enum roard_client_acclev acclev) { int i; for (i = 0; _g_acclevs[i].name != NULL; i++) if ( _g_acclevs[i].acclev == acclev ) return _g_acclevs[i].name; return NULL; } //ll roaraudio-1.0beta11/roard/codecfilter.c0000644000175000017500000003371312264733654016240 0ustar phiphi//codecfilter.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #define ROAR_REQUIRE_LIBVORBISFILE #include "roard.h" #ifndef ROAR_WITHOUT_CF_CMD #if !defined(ROAR_HAVE_UNIX) || !defined(ROAR_HAVE_BSDSOCKETS) || !defined(ROAR_HAVE_IO_POSIX) #define ROAR_WITHOUT_CF_CMD #endif #endif #define _DUMMY_FILTER(codec,name,desc,flags,subsystem,delay) {(codec),(name),(desc),NULL,NULL,(flags),(subsystem), \ NULL, NULL, NULL, NULL, NULL, NULL, (delay), NULL } #define _PCM_FILTER(codec) _DUMMY_FILTER(codec, "PCM", "Native PCM Support", \ ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU_NN, \ ROAR_SUBSYS_WAVEFORM, codecfilter_delay_zero) struct roar_codecfilter g_codecfilter[] = { _DUMMY_FILTER(-1, "null", "null codec filter", ROAR_CODECFILTER_NONE, ROAR_SUBSYS_NONE, NULL), _PCM_FILTER(ROAR_CODEC_PCM_S_LE), _PCM_FILTER(ROAR_CODEC_PCM_S_BE), _PCM_FILTER(ROAR_CODEC_PCM_S_PDP), _PCM_FILTER(ROAR_CODEC_PCM_U_LE), _PCM_FILTER(ROAR_CODEC_PCM_U_BE), _PCM_FILTER(ROAR_CODEC_PCM_U_PDP), #ifndef ROAR_WITHOUT_DCOMP_MIDI _DUMMY_FILTER(ROAR_CODEC_MIDI, "MIDI", "Native MIDI Support", ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU_NN, ROAR_SUBSYS_MIDI, NULL), #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT {ROAR_CODEC_DMX512, "DMX512", "Native DMX512 Support", NULL, NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU_NN, ROAR_SUBSYS_LIGHT, NULL, NULL, NULL, NULL, NULL, NULL, codecfilter_delay_zero, NULL}, #endif #ifndef ROAR_WITHOUT_DCOMP_RDTCS {ROAR_CODEC_RDS, "RDS", "Native RDS Support", NULL, NULL, ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU_NN, ROAR_SUBSYS_RDTCS, NULL, NULL, NULL, NULL, NULL, NULL, codecfilter_delay_zero, NULL}, #endif /* #ifdef ROAR_HAVE_LIBSNDFILE {ROAR_CODEC_RIFF_WAVE, "sndfile", "libsndfile codec filter", NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE, cf_sndfile_open, cf_sndfile_close, NULL, cf_sndfile_write, cf_sndfile_read, NULL}, #else */ #ifndef ROAR_WITHOUT_CF_WAVE {ROAR_CODEC_RIFF_WAVE, "RIFF/WAVE", "RIFF/WAVE", NULL, NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU, ROAR_SUBSYS_WAVEFORM, cf_wave_open, cf_wave_close, NULL, cf_wave_write, cf_wave_read, NULL, NULL, cf_wave_ctl}, #endif //#endif #ifndef ROAR_WITHOUT_CF_AU {ROAR_CODEC_AU, "AU", "AU", NULL, NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU, ROAR_SUBSYS_WAVEFORM, cf_au_open, cf_au_close, NULL, cf_au_write, cf_au_read, NULL, NULL, cf_au_ctl}, #endif #if 0 #ifdef ROAR_HAVE_LIBRAUM {ROAR_CODEC_RAUM, "RAUM", "RAUM Container Format", NULL, cf_raum_setup, ROAR_CODECFILTER_WRITE, ROAR_SUBSYS_WAVEFORM|ROAR_SUBSYS_MIDI|ROAR_SUBSYS_LIGHT|ROAR_SUBSYS_RAW|ROAR_SUBSYS_COMPLEX, cont_fw_cf_open, cont_fw_cf_close, NULL, cont_fw_cf_write, cont_fw_cf_read, cont_fw_cf_flush, NULL, cont_fw_cf_ctl}, #endif #endif #ifdef ROAR_HAVE_LIBUNIRAUM {ROAR_CODEC_RAUM, "uniraum", "RAUM Container Format", NULL, NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM|ROAR_SUBSYS_MIDI|ROAR_SUBSYS_LIGHT|ROAR_SUBSYS_RAW|ROAR_SUBSYS_COMPLEX, cf_uniraum_open, cf_uniraum_close, NULL, cf_uniraum_write, cf_uniraum_read, cf_uniraum_flush, NULL, cf_uniraum_ctl}, #endif #ifdef ROAR_HAVE_LIBOGG {ROAR_CODEC_OGG, "Ogg", "Ogg Container Format", NULL, NULL, ROAR_CODECFILTER_NONE, ROAR_SUBSYS_WAVEFORM|ROAR_SUBSYS_MIDI, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, #endif #ifdef ROAR_SUPPORT_ALAW {ROAR_CODEC_ALAW, "alaw", "A-Law", NULL, NULL, #ifdef ROAR_SUPPORT_ALAW_RW ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU_NN, #else ROAR_CODECFILTER_READ|ROAR_CODECFILTER_PRETHRU_NN, #endif ROAR_SUBSYS_WAVEFORM, cf_alaw_open, cf_alaw_close, NULL, #ifdef ROAR_SUPPORT_ALAW_RW cf_alaw_write, #else NULL, #endif cf_alaw_read, NULL, codecfilter_delay_zero, NULL}, #endif #ifdef ROAR_SUPPORT_MULAW {ROAR_CODEC_MULAW, "mulaw", "mu-Law", NULL, NULL, #ifdef ROAR_SUPPORT_MULAW_RW ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU_NN, #else ROAR_CODECFILTER_READ|ROAR_CODECFILTER_PRETHRU_NN, #endif ROAR_SUBSYS_WAVEFORM, cf_mulaw_open, cf_mulaw_close, NULL, #ifdef ROAR_SUPPORT_MULAW_RW cf_mulaw_write, #else NULL, #endif cf_mulaw_read, NULL, codecfilter_delay_zero, NULL}, #endif #ifndef ROAR_WITHOUT_CF_CMD #ifdef ROAR_HAVE_BIN_OGG123 {ROAR_CODEC_OGG_GENERAL, "cmd", "ogg123", ROAR_HAVE_BIN_OGG123 " -q -d raw -f - -", NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM, cf_cmd_open, NULL, NULL, NULL, NULL, NULL, codecfilter_delay_fulldyn, NULL}, #endif #endif #ifdef ROAR_HAVE_LIBVORBISFILE {ROAR_CODEC_OGG_VORBIS, "oggvorbis", "Ogg Vorbis decoder", NULL, NULL, #ifdef ROAR_HAVE_LIBVORBISENC ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU, #else ROAR_CODECFILTER_READ, #endif ROAR_SUBSYS_WAVEFORM, cf_vorbis_open, cf_vorbis_close, NULL, cf_vorbis_write, cf_vorbis_read, NULL, codecfilter_delay_fulldyn, cf_vorbis_ctl}, #else #ifndef ROAR_WITHOUT_CF_CMD #ifdef ROAR_HAVE_BIN_OGG123 {ROAR_CODEC_OGG_VORBIS, "cmd", "ogg123", ROAR_HAVE_BIN_OGG123 " -q -d raw -f - -", NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM, cf_cmd_open, NULL, NULL, NULL, NULL, NULL, codecfilter_delay_fulldyn, NULL}, #endif #endif #endif #ifdef ROAR_HAVE_LIBFISHSOUND {ROAR_CODEC_OGG_SPEEX, "fishsound", "libfishsound Xiph Codec library", NULL, NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM, cf_fishsound_open, cf_fishsound_close, NULL, NULL, cf_fishsound_read, NULL, codecfilter_delay_fulldyn, NULL}, {ROAR_CODEC_OGG_FLAC, "fishsound", "libfishsound Xiph Codec library", NULL, NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM, cf_fishsound_open, cf_fishsound_close, NULL, NULL, cf_fishsound_read, NULL, codecfilter_delay_fulldyn, NULL}, #endif #ifndef ROAR_WITHOUT_CF_CMD #ifdef ROAR_HAVE_BIN_TIMIDITY {ROAR_CODEC_MIDI_FILE, "MIDIFILE", "timidity MIDI synth", ROAR_HAVE_BIN_TIMIDITY " -Or1sl -s %R -o - -", NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM, cf_cmd_open, NULL, NULL, NULL, NULL, NULL, codecfilter_delay_fulldyn, NULL}, #endif #endif #ifdef ROAR_HAVE_LIBCELT {ROAR_CODEC_ROAR_CELT, "RoarCELT", "RoarAudio CELT", NULL, NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU, ROAR_SUBSYS_WAVEFORM, cf_celt_open, cf_celt_close, NULL, cf_celt_write, cf_celt_read, NULL, cf_celt_delay, NULL}, #endif #ifdef ROAR_HAVE_LIBSPEEX {ROAR_CODEC_ROAR_SPEEX, "RoarSpeex", "RoarAudio Speex", NULL, NULL, ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU, ROAR_SUBSYS_WAVEFORM, cf_speex_open, cf_speex_close, NULL, cf_speex_write, cf_speex_read, NULL, NULL, NULL}, #endif #ifndef ROAR_WITHOUT_CF_CMD #if defined(ROAR_HAVE_BIN_FLAC) && !defined(ROAR_HAVE_LIBFLAC) {ROAR_CODEC_FLAC, "cmd", "flac", #if BYTE_ORDER == BIG_ENDIAN ROAR_HAVE_BIN_FLAC " --silent --force-raw-format --sign=signed --endian=big -d - -o -", #elif BYTE_ORDER == LITTLE_ENDIAN ROAR_HAVE_BIN_FLAC " --silent --force-raw-format --sign=signed --endian=little -d - -o -", #else "false", #endif NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM, cf_cmd_open, NULL, NULL, NULL, NULL, NULL, codecfilter_delay_fulldyn, NULL}, #endif #endif #ifdef ROAR_HAVE_LIBFLAC {ROAR_CODEC_FLAC, "FLAC", "flac codec", NULL, NULL, ROAR_CODECFILTER_READ, ROAR_SUBSYS_WAVEFORM, cf_flac_open, cf_flac_close, NULL, NULL, cf_flac_read, NULL, codecfilter_delay_fulldyn, NULL}, #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT _DUMMY_FILTER(ROAR_CODEC_ROARDMX, "RoarDMX", "Native RoarDMX Support", ROAR_CODECFILTER_READ|ROAR_CODECFILTER_WRITE|ROAR_CODECFILTER_PRETHRU_NN, ROAR_SUBSYS_LIGHT, NULL), #endif {-1, NULL, NULL, NULL, NULL, ROAR_CODECFILTER_NONE, ROAR_SUBSYS_NONE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} // end of list }; void print_codecfilterlist (void) { int i; int flags; char mode[5]; char delay[6]; char subsys[7] = " "; uint_least32_t d; printf(" Codec Filtername Mode Subsys Delay - Description\n"); printf("-------------------------------------------------------------\n"); for (i = 0; g_codecfilter[i].name != NULL; i++) { strncpy(subsys, " ", 6); if ( g_codecfilter[i].subsystems & ROAR_SUBSYS_WAVEFORM ) subsys[0] = 'W'; if ( g_codecfilter[i].subsystems & ROAR_SUBSYS_MIDI ) subsys[1] = 'M'; if ( g_codecfilter[i].subsystems & ROAR_SUBSYS_CB ) subsys[2] = 'C'; if ( g_codecfilter[i].subsystems & ROAR_SUBSYS_LIGHT ) subsys[3] = 'L'; if ( g_codecfilter[i].subsystems & ROAR_SUBSYS_RAW ) subsys[4] = 'R'; if ( g_codecfilter[i].subsystems & ROAR_SUBSYS_COMPLEX ) subsys[5] = 'X'; flags = g_codecfilter[i].flags; if ( flags == ROAR_CODECFILTER_NONE ) { strcpy(mode, "none"); } else { strcpy(mode, " "); if ( flags & ROAR_CODECFILTER_READ ) mode[0] = 'r'; if ( flags & ROAR_CODECFILTER_WRITE ) mode[1] = 'w'; if ( flags & ROAR_CODECFILTER_PRETHRU ) mode[2] = 'P'; if ( flags & ROAR_CODECFILTER_PRETHRU_NN ) mode[2] = 'p'; } *delay = 0; if ( g_codecfilter[i].codec == -1 ) { // null codec filter strcpy(delay, "0ms"); } else if ( g_codecfilter[i].delay == NULL ) { strcpy(delay, "?"); } else { if ( codecfilter_delay(NULL, i, &d) == -1 ) { strcpy(delay, "dyn"); } else { snprintf(delay, 5, "%ims", (int)(d/(uint_least32_t)1000)); } } printf(" %-12s %-12s %-4s %6s %-5s - %s\n", roar_codec2str(g_codecfilter[i].codec), g_codecfilter[i].name, mode, subsys, delay, g_codecfilter[i].desc ); } } int codecfilter_open (CODECFILTER_USERDATA_T * inst, int * codecfilter_id, char * codecfilter /* NOTE: this is not part of struct roar_codecfilter's def! */, int codec, struct roar_stream_server * info) { int i; struct roar_codecfilter * filter = NULL; *codecfilter_id = -1; ROAR_DBG("codecfilter_open(*): codecfilter='%s', info->id=%i", codecfilter, ROAR_STREAM(info)->id); for (i = 0; g_codecfilter[i].name != NULL; i++) { ROAR_DBG("codecfilter_open(*): g_codecfilter[i].codec <-> codec => %i <-> %i", g_codecfilter[i].codec, codec); if ( g_codecfilter[i].codec == codec ) { if ( !codecfilter || strcmp(codecfilter, g_codecfilter[i].name) == 0 ) { *codecfilter_id = i; filter = &g_codecfilter[i]; break; } } } info->codecfilter = *codecfilter_id; if (*codecfilter_id != -1) { if ( filter->open != NULL ) { if ( (i = filter->open(inst, codec, info, filter)) == -1 ) { info->codecfilter = *codecfilter_id = -1; } return i; } else { // in case we can not open the filter we will not use it *codecfilter_id = -1; info->codecfilter = -1; } return 0; } return -1; // we found no filter -> ok } int codecfilter_close(CODECFILTER_USERDATA_T inst, int codecfilter) { ROAR_DBG("codecfilter_close(inst=%p, codecfilter=%i) = ?", inst, codecfilter); if ( codecfilter == -1 ) return -1; if ( g_codecfilter[codecfilter].close ) return g_codecfilter[codecfilter].close(inst); return 0; } int codecfilter_pause(CODECFILTER_USERDATA_T inst, int codecfilter, int newstate) { if ( codecfilter == -1 ) return -1; if ( g_codecfilter[codecfilter].pause ) return g_codecfilter[codecfilter].pause(inst, newstate); return 0; } int codecfilter_write(CODECFILTER_USERDATA_T inst, int codecfilter, char * buf, int len) { if ( codecfilter == -1 ) return -1; if ( g_codecfilter[codecfilter].write ) return g_codecfilter[codecfilter].write(inst, buf, len); return 0; } int codecfilter_read (CODECFILTER_USERDATA_T inst, int codecfilter, char * buf, int len) { if ( codecfilter == -1 ) return -1; errno = 0; if ( g_codecfilter[codecfilter].read ) return g_codecfilter[codecfilter].read(inst, buf, len); return 0; } int codecfilter_flush(CODECFILTER_USERDATA_T inst, int codecfilter) { if ( codecfilter == -1 ) return -1; if ( g_codecfilter[codecfilter].flush ) return g_codecfilter[codecfilter].flush(inst); return 0; } int codecfilter_delay(CODECFILTER_USERDATA_T inst, int codecfilter, uint_least32_t * delay) { ROAR_DBG("codecfilter_delay(inst=%p, codecfilter=%i, *delay=?) = ?", inst, codecfilter); if ( codecfilter == -1 ) return -1; if ( g_codecfilter[codecfilter].delay ) return g_codecfilter[codecfilter].delay(inst, delay); return -1; } int codecfilter_ctl (CODECFILTER_USERDATA_T inst, int codecfilter, int_least32_t cmd, void * data) { ROAR_DBG("codecfilter_ctl(inst=%p, codecfilter=%i, cmd=0x%.8x, data=%p) = ?", inst, codecfilter, cmd, data); if ( codecfilter == -1 ) return -1; if ( g_codecfilter[codecfilter].ctl ) return g_codecfilter[codecfilter].ctl(inst, cmd, data); return -1; } int codecfilter_delay_fulldyn(CODECFILTER_USERDATA_T inst, uint_least32_t * delay) { *delay = 0; // just to be sure return -1; } int codecfilter_delay_zero(CODECFILTER_USERDATA_T inst, uint_least32_t * delay) { // this codec does not create any addition latency. *delay = 0; return 0; } //ll roaraudio-1.0beta11/roard/codecfilter_alaw.c0000644000175000017500000000502512264733655017240 0ustar phiphi//codecfilter_alaw.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * ckport: ignore-symbol: roardsp_conv_pcm162alaw of target libroardsp0 * ckport: ignore-symbol: roardsp_conv_alaw2pcm16 of target libroardsp0 */ #include "roard.h" #ifdef ROAR_SUPPORT_ALAW int cf_alaw_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct roar_stream * s = ROAR_STREAM(info); (void)codec, (void)filter; *inst = (CODECFILTER_USERDATA_T) info; s->info.bits = 16; s->info.codec = ROAR_CODEC_DEFAULT; return 0; } int cf_alaw_close(CODECFILTER_USERDATA_T inst) { (void)inst; return 0; } int cf_alaw_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct roar_stream_server * s = ROAR_STREAM_SERVER(inst); if ( (len = stream_vio_s_read(s, buf, len/2)) < 1 ) { return len; } roardsp_conv_alaw2pcm16((int16_t *)buf, buf, len); return len*2; } #ifdef ROAR_SUPPORT_ALAW_RW int cf_alaw_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct roar_stream_server * s = ROAR_STREAM_SERVER(inst); char * out; // TODO: add a more effect way to use memory than allways alloc/freeing it. // maybe by keeping a buffer over instanzes or by using ca global buffer // with an refrenze counter so we can free it on last use len /= 2; if ( (out = (char*)roar_mm_malloc(len)) == NULL ) return -1; roardsp_conv_pcm162alaw(out, (int16_t*)buf, len); len = stream_vio_s_write(s, out, len); roar_mm_free(out); if ( len > 0 ) { return len*2; } else { return -1; } } #endif #endif //ll roaraudio-1.0beta11/roard/codecfilter_au.c0000644000175000017500000001700312264733655016720 0ustar phiphi//codecfilter_au.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_CF_AU int cf_au_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_au_inst * self = roar_mm_malloc(sizeof(struct codecfilter_au_inst)); struct roar_stream * s = ROAR_STREAM(info); (void)codec, (void)filter; if ( self == NULL ) return -1; self->stream = info; self->vstream = NULL; self->opened = 0; *inst = (CODECFILTER_USERDATA_T) self; memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); s->info.codec = ROAR_CODEC_PCM_S_BE; return 0; } int cf_au_close(CODECFILTER_USERDATA_T inst) { // struct codecfilter_au_inst * self = (struct codecfilter_au_inst *) inst; if ( !inst ) return -1; roar_mm_free(inst); return 0; } int cf_au_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_au_inst * self = (struct codecfilter_au_inst *) inst; int r = -1; char tbuf[ROAR_AU_MIN_HEADER_LEN]; uint32_t * header = (uint32_t*)tbuf; struct roar_stream * ps = ROAR_STREAM(self->stream); struct roar_stream * s; struct roar_audio_info info; char * extra_header; int codec = -1; int vid, fh; int i; if ( self->opened ) { return stream_vio_s_read(self->stream, buf, len); } else { if (stream_vio_s_read(self->stream, tbuf, ROAR_AU_MIN_HEADER_LEN) != ROAR_AU_MIN_HEADER_LEN) { return -1; } for (i = 0; i < ROAR_AU_MIN_HEADER_LEN/4; i++) { header[i] = ROAR_NET2HOST32(header[i]); ROAR_DBG("cf_au_read(inst=%p, buf=%p, len=%i): header[%i] = 0x%.8x", inst, buf, len, i, header[i]); } // test the header, is this really a AU stream? if ( header[0] != ROAR_AU_MAGIC ) return -1; if ( header[1] != ROAR_AU_MIN_HEADER_LEN ) { header[1] -= ROAR_AU_MIN_HEADER_LEN; if ( header[1] > (uint32_t)32768U ) // do not allow more than 32KiB header... return -1; if ( (extra_header = roar_mm_malloc(header[1])) == NULL ) return -1; if ( stream_vio_s_read(self->stream, extra_header, header[1]) != (ssize_t)header[1] ) { roar_mm_free(extra_header); return -1; } roar_mm_free(extra_header); } // TODO: write better code here! if ( (fh = streams_get_fh(ps->id)) == -1 ) { return -1; } if ( (vid = streams_new_virtual(ps->id, &(self->vstream))) == -1 ) { return -1; } ROAR_DBG("cf_au_read(*): self->vstream=%p", self->vstream); s = ROAR_STREAM(self->vstream); s->info.rate = header[4]; s->info.channels = header[5]; switch (header[3]) { case ROAR_AU_CID_MULAW: s->info.bits = 8; codec = ROAR_CODEC_MULAW; break; case ROAR_AU_CID_ALAW: s->info.bits = 8; codec = ROAR_CODEC_ALAW; break; case ROAR_AU_CID_PCM_S_8: s->info.bits = 8; codec = ROAR_CODEC_PCM_S_BE; break; case ROAR_AU_CID_PCM_S_16: s->info.bits = 16; codec = ROAR_CODEC_PCM_S_BE; break; case ROAR_AU_CID_PCM_S_24: s->info.bits = 24; codec = ROAR_CODEC_PCM_S_BE; break; case ROAR_AU_CID_PCM_S_32: s->info.bits = 32; codec = ROAR_CODEC_PCM_S_BE; break; default: return -1; } s->info.codec = codec; self->vstream->codec_orgi = codec; memcpy(&info, &(s->info), sizeof(struct roar_audio_info)); if ( streams_set_fh(vid, fh) == -1 ) { return -1; } /* if ( roar_vio_open_pass(&(self->vstream->vio), &(self->stream->vio)) == -1 ) { return -1; } */ memcpy(&(self->vstream->vio), &(self->stream->vio), sizeof(struct roar_vio_calls)); if ( streams_set_null_io(ps->id) == -1 ) { return -1; } memcpy(&(ps->info), &info, sizeof(struct roar_audio_info)); self->opened = 1; errno = EAGAIN; return -1; } return r; } int cf_au_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_au_inst * self = (struct codecfilter_au_inst *) inst; struct roar_stream * s = ROAR_STREAM(self->stream); void * headerdata; uint32_t * header; uint32_t codec; int sid; int i; ROAR_DBG("cf_au_write(inst=%p, buf=%p, len=%i) = ?", inst, buf, len); ROAR_DBG("cf_au_write(inst=%p, buf=%p, len=%i): self->opened=%i", inst, buf, len, self->opened); if ( self->opened ) { return stream_vio_s_write(self->stream, buf, len); } else { if ( s->fh == -1 ) { errno = EAGAIN; return -1; } sid = ROAR_STREAM(self->stream)->id; if ( stream_prethru_destroy(sid) == -1 ) { return -1; } if ( stream_prethru_add_data(sid, &headerdata, ROAR_AU_MIN_HEADER_LEN) == -1 ) { return -1; } header = headerdata; switch (s->info.codec) { case ROAR_CODEC_PCM_S_BE: switch (s->info.bits) { case 8: codec = ROAR_AU_CID_PCM_S_8; break; case 16: codec = ROAR_AU_CID_PCM_S_16; break; case 24: codec = ROAR_AU_CID_PCM_S_24; break; case 32: codec = ROAR_AU_CID_PCM_S_32; break; default: ROAR_ERR("cf_au_write(*) bits per sample not supported!"); return -1; break; } break; default: ROAR_ERR("cf_au_write(*) Codec not supported!: %s(%i)", roar_codec2str(s->info.codec), s->info.codec); return -1; break; } ROAR_DBG("cf_au_write(*) Codec supported!"); header[0] = ROAR_AU_MAGIC; header[1] = ROAR_AU_MIN_HEADER_LEN; header[2] = ROAR_AU_DATASIZE; header[3] = codec; header[4] = s->info.rate; header[5] = s->info.channels; for (i = 0; i < ROAR_AU_MIN_HEADER_LEN/4; i++) header[i] = ROAR_HOST2NET32(header[i]); if ( stream_vio_s_write(self->stream, header, ROAR_AU_MIN_HEADER_LEN) != ROAR_AU_MIN_HEADER_LEN ) return -1; self->opened = 1; errno = EAGAIN; // return -1; len = stream_vio_s_write(self->stream, buf, len); cf_au_close(inst); ROAR_STREAM_SERVER(s)->codecfilter = -1; return len; // return stream_vio_s_write(self->stream, buf, len); } return -1; } int cf_au_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data) { struct codecfilter_au_inst * self = (struct codecfilter_au_inst *) inst; int_least32_t type = cmd & ROAR_STREAM_CTL_TYPEMASK; (void)data; cmd -= type; ROAR_DBG("cf_au_ctl(*): command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); switch (cmd) { case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_VIRTUAL_DELETE): streams_delete(ROAR_STREAM(self->stream)->id); return 0; break; default: ROAR_DBG("cf_au_ctl(*): Unknown command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); return -1; } return -1; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_celt.c0000644000175000017500000002166212264733656017251 0ustar phiphi//codecfilter_celt.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBCELT #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 typedef celt_int16 celt_int16_t; #endif int cf_celt_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_celt_inst * self = roar_mm_malloc(sizeof(struct codecfilter_celt_inst)); struct roar_stream * s = ROAR_STREAM(info); (void)codec, (void)filter; if ( self == NULL ) return -1; /* CELTMode * mode; CELTEncoder * encoder; CELTDecoder * decoder; int frame_size; int lookahead; int out_size; char * ibuf; char * obuf; char * rest; int s_buf; int f_rest; /-* how much is in rest? *-/ */ self->stream = info; self->frame_size = 256; self->lookahead = self->frame_size; self->encoder = NULL; self->decoder = NULL; self->opened_encoder = 0; self->opened_decoder = 0; self->s_buf = s->info.channels * self->frame_size * 2; self->ibuf = roar_mm_malloc(self->s_buf); self->obuf = roar_mm_malloc(self->s_buf); self->i_rest = roar_mm_malloc(self->s_buf); self->o_rest = roar_mm_malloc(self->s_buf); self->fi_rest = 0; self->fo_rest = 0; if ( !(self->ibuf && self->obuf && self->i_rest && self->o_rest) ) { if ( self->ibuf != NULL ) roar_mm_free(self->ibuf); if ( self->obuf != NULL ) roar_mm_free(self->obuf); if ( self->i_rest != NULL ) roar_mm_free(self->o_rest); if ( self->o_rest != NULL ) roar_mm_free(self->o_rest); roar_mm_free(self); return -1; } #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 self->mode = celt_mode_create(s->info.rate, self->frame_size, NULL); #else self->mode = celt_mode_create(s->info.rate, s->info.channels, self->frame_size, NULL); #endif if ( !self->mode ) { roar_mm_free(self); return -1; } if ( s->dir == ROAR_DIR_PLAY ) { #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 self->decoder = celt_decoder_create(self->mode, s->info.channels, NULL); #else self->decoder = celt_decoder_create(self->mode); #endif } else if ( s->dir == ROAR_DIR_MONITOR || s->dir == ROAR_DIR_OUTPUT ) { #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 self->encoder = celt_encoder_create(self->mode, s->info.channels, NULL); #else self->encoder = celt_encoder_create(self->mode); #endif } else if ( s->dir == ROAR_DIR_BIDIR || s->dir == ROAR_DIR_RECPLAY ) { #ifdef ROAR_HAVE_CELT_VERSION_0_7_1 self->decoder = celt_decoder_create(self->mode, s->info.channels, NULL); self->encoder = celt_encoder_create(self->mode, s->info.channels, NULL); #else self->decoder = celt_decoder_create(self->mode); self->encoder = celt_encoder_create(self->mode); #endif } else { celt_mode_destroy(self->mode); roar_mm_free(self); return -1; } *inst = (CODECFILTER_USERDATA_T) self; s->info.codec = ROAR_CODEC_DEFAULT; s->info.bits = 16; // CELT hardcoded return 0; } int cf_celt_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst; if ( !inst ) return -1; if ( self->encoder != NULL ) celt_encoder_destroy(self->encoder); if ( self->decoder != NULL ) celt_decoder_destroy(self->decoder); if ( self->mode != NULL ) celt_mode_destroy(self->mode); if ( self->ibuf != NULL ) roar_mm_free(self->ibuf); if ( self->obuf != NULL ) roar_mm_free(self->obuf); if ( self->i_rest != NULL ) roar_mm_free(self->i_rest); if ( self->o_rest != NULL ) roar_mm_free(self->o_rest); roar_mm_free(inst); return 0; } int cf_celt_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst; int r = 0; uint16_t fs; char * cbuf; char magic[ROAR_CELT_MAGIC_LEN]; // printf("buf=%p, len=%i\n", buf, len); if ( !self->opened_decoder ) { errno = ENOSYS; if ( stream_vio_s_read(self->stream, magic, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN ) return -1; if ( memcmp(magic, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != 0 ) return -1; errno = 0; self->opened_decoder = 1; } if ( self->fi_rest ) { memcpy(buf, self->i_rest, self->fi_rest); r += self->fi_rest; self->fi_rest = 0; } while ( r <= (len - self->s_buf) ) { if ( stream_vio_s_read(self->stream, &fs, 2) != 2 ) break; fs = ROAR_NET2HOST16(fs); // ROAR_WARN("0:fs=%i", fs); if ( fs > self->s_buf ) return -1; if ( stream_vio_s_read(self->stream, self->ibuf, fs) != fs ) return -1; cbuf = buf + r; // printf("buf=%p, r=%i // cbuf=%p\n", buf, r, cbuf); if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) cbuf) < 0 ) return -1; r += self->s_buf; } if ( r < len ) { // printf("r < len!\n"); if ( stream_vio_s_read(self->stream, &fs, 2) == 2 ) { fs = ROAR_NET2HOST16(fs); // ROAR_WARN("1:fs=%i", fs); // printf("next: fs=%i\n", fs); if ( fs > self->s_buf ) return -1; if ( stream_vio_s_read(self->stream, self->ibuf, fs) == fs ) { // printf("got data!\n"); if ( celt_decode(self->decoder, (unsigned char *) self->ibuf, fs, (celt_int16_t *) self->obuf) >= 0 ) { // printf("{ // decode rest\n"); // printf(" r=%i // need %i Bytes\n", r, len - r); // printf(" memcpy(buf+%i, self->obuf, %i) = ?\n", r, len - r); memcpy(buf+r, self->obuf, len - r); self->fi_rest = self->s_buf + r - len; memcpy(self->i_rest, self->obuf + len - r, self->fi_rest); // printf(" len=%i, r=%i, fi_rest=%i, s_buf=%i\n", len, r, self->fi_rest, self->s_buf); r = len; // printf("}\n"); } } } } ROAR_DBG("cf_celt_read(inst=%p, buf=%p, len=%i) = %i", inst, buf, len, r); return r; } #define BS (ROAR_STREAM(self->stream)->info.channels * 32) int cf_celt_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst; int have = 0; int org_len = len; int diff; int fs2 = self->frame_size * 2 * ROAR_STREAM(self->stream)->info.channels; int sid; uint16_t pkglen_net, pkglen; unsigned char cbits[BS+2]; void * prethru; if ( !self->opened_encoder ) { sid = ROAR_STREAM(self->stream)->id; if ( stream_prethru_destroy(sid) == -1 ) { return -1; } if ( stream_prethru_add_data(sid, &prethru, ROAR_CELT_MAGIC_LEN) == -1 ) { return -1; } memcpy(prethru, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN); if ( stream_vio_s_write(self->stream, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) != ROAR_CELT_MAGIC_LEN ) return -1; self->opened_encoder = 1; } if ( (self->fo_rest + len) > fs2 ) { if ( self->fo_rest ) { memcpy(self->obuf, self->o_rest, self->fo_rest); have = self->fo_rest; self->fo_rest = 0; } memcpy(self->obuf+have, buf, (diff=fs2-have)); buf += diff; len -= diff; pkglen = celt_encode(self->encoder, (celt_int16_t *) self->obuf, NULL, cbits+2, BS); pkglen_net = ROAR_HOST2NET16(pkglen); *(uint16_t*)cbits = pkglen_net; if ( stream_vio_s_write(self->stream, cbits, pkglen+2) == -1 ) return -1; while (len >= fs2) { pkglen = celt_encode(self->encoder, (celt_int16_t *) buf, NULL, cbits+2, BS); pkglen_net = ROAR_HOST2NET16(pkglen); *(uint16_t*)cbits = pkglen_net; if ( stream_vio_s_write(self->stream, cbits, pkglen+2) == -1 ) return -1; len -= fs2; buf += fs2; } } if ( len ) { memcpy(self->o_rest + self->fo_rest, buf, len); self->fo_rest += len; len = 0; } return org_len; } int cf_celt_delay(CODECFILTER_USERDATA_T inst, uint_least32_t * delay) { struct codecfilter_celt_inst * self = (struct codecfilter_celt_inst *) inst; ROAR_DBG("cf_celt_delay(*) = ?"); if ( self == NULL ) { *delay = (1000000 * 256) / ROAR_RATE_DEFAULT; return 0; } else { *delay = (1000000 * self->frame_size) / ROAR_STREAM(self->stream)->info.rate; ROAR_DBG("cf_celt_delay(*): frame_size=%i, rate=%i, *delay=%i", self->frame_size, ROAR_STREAM(self->stream)->info.rate, *delay); return 0; } return -1; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_cmd.c0000644000175000017500000000560212264733656017061 0ustar phiphi//codecfilter_cmd.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #if defined(ROAR_HAVE_UNIX) && defined(ROAR_HAVE_BSDSOCKETS) && defined(ROAR_HAVE_IO_POSIX) #define _CAN_OPERATE #endif #if !defined(ROAR_WITHOUT_CF_CMD) && defined(_CAN_OPERATE) #define CMDMAXLEN 1024 int cf_cmd_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { int socks[2]; int execed = -1; char cmd[CMDMAXLEN+1] = {0}; char * tmp = NULL; char tb[CMDMAXLEN+1]; char * o = filter->options; int i; if ( !o ) return -1; for (i = 0; i < CMDMAXLEN && *o != 0; i++, o++) { if ( *o == '%' ) { // printf("ol: *o='%c' (escape)\n", *o); tmp = NULL; o++; if ( *o == 0 ) { break; } else if ( *o == 'R' ) { tmp = tb; snprintf(tb, CMDMAXLEN, "%i", g_sa->rate); } else if ( *o == 'B' ) { tmp = tb; snprintf(tb, CMDMAXLEN, "%i", g_sa->bits); } else if ( *o == 'C' ) { tmp = tb; snprintf(tb, CMDMAXLEN, "%i", g_sa->channels); } // printf("*o='%c', tmp=%p\n", *o, tmp); if ( tmp ) { for (; i < CMDMAXLEN && *tmp != 0; i++, tmp++) cmd[i] = *tmp; i--; } } else { // printf("ol: *o='%c' (copy to cmd[i=%i])\n", *o, i); cmd[i] = *o; } } cmd[i+1] = 0; //printf("cmd='%s'\n", cmd); if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) { return -1; } if ( lib_run_bg(cmd, ROAR_STREAM(info)->fh, socks[1], ROAR_STDERR, socks, 2) == -1 ) return -1; if ( info->client != -1 ) { execed = g_clients[info->client]->execed; if ( execed != -1 ) { if ( g_streams[execed] == info ) { g_clients[info->client]->fh = socks[0]; } else { close(ROAR_STREAM(info)->fh); } } else { close(ROAR_STREAM(info)->fh); } } else { close(ROAR_STREAM(info)->fh); } ROAR_STREAM(info)->fh = socks[0]; ROAR_STREAM(info)->info.codec = ROAR_CODEC_DEFAULT; close(socks[1]); info->codecfilter = -1; return 0; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_fishsound.c0000644000175000017500000001434712264733657020327 0ustar phiphi//codecfilter_fishsound.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBFISHSOUND int cf_fishsound_decoded_float (FishSound * fsound, float ** pcm, long frames, void * user_data) { struct codecfilter_fishsound_inst * self = (struct codecfilter_fishsound_inst *) user_data; struct roar_stream * stream = ROAR_STREAM(self->stream); struct roar_buffer * buf; int i; double s; union { void * v; char * c; int16_t * i16; int32_t * i32; } data; ROAR_DBG("cf_fishsound_decoded_float(fsound=%p, pcm=%p, frames=%li, user_data=%p) = ?", fsound, pcm, frames, user_data); ROAR_DBG("cf_fishsound_decoded_float(*): self->opened=%i", self->opened); if (!self->opened) { fish_sound_command(fsound, FISH_SOUND_GET_INFO, &(self->fsinfo), sizeof(FishSoundInfo)); } if ( roar_buffer_new_data(&buf, frames*stream->info.bits*stream->info.channels/8, &(data.v)) == -1 ) return -1; frames *= self->fsinfo.channels; switch (stream->info.bits) { case 8: for (i = 0; i < frames; i++) { s = ((float*)pcm)[i]; s *= 127; data.c[i] = s; } break; case 16: for (i = 0; i < frames; i++) { s = ((float*)pcm)[i]; s *= 32767; data.i16[i] = s; } break; case 32: for (i = 0; i < frames; i++) { s = ((float*)pcm)[i]; s *= 2147483647; data.i32[i] = s; } break; default: return -1; } if ( self->buffer == NULL ) { self->buffer = buf; } else { if ( roar_buffer_moveinto(self->buffer, &buf) == -1 ) { roar_buffer_free(buf); return -1; } } // shouldn't that be zero? return -1; } int cf_fishsound_read_packet (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data) { FishSound * fsound = (FishSound *)user_data; fish_sound_prepare_truncation(fsound, op->granulepos, op->e_o_s); fish_sound_decode(fsound, op->packet, op->bytes); return 0; } int cf_fishsound_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_fishsound_inst * self = roar_mm_malloc(sizeof(struct codecfilter_fishsound_inst)); struct roar_stream * s = ROAR_STREAM(info); if ( !self ) return -1; if ( s->dir != ROAR_DIR_PLAY ) { roar_mm_free(self); return -1; } self->stream = info; self->opened = 0; self->buffer = NULL; self->fsound = fish_sound_new(FISH_SOUND_DECODE, &(self->fsinfo)); fish_sound_set_interleave(self->fsound, 1); fish_sound_set_decoded_float_ilv(self->fsound, cf_fishsound_decoded_float, (void*)self); self->oggz = oggz_new(OGGZ_READ); oggz_set_read_callback(self->oggz, -1, cf_fishsound_read_packet, self->fsound); *inst = (CODECFILTER_USERDATA_T) self; return 0; } int cf_fishsound_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_fishsound_inst * self = (struct codecfilter_fishsound_inst *) inst; if ( inst == NULL ) return -1; oggz_close(self->oggz); fish_sound_delete(self->fsound); if ( self->buffer != NULL ) roar_buffer_free(self->buffer); roar_mm_free(inst); return 0; } int cf_fishsound_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_fishsound_inst * self = (struct codecfilter_fishsound_inst *) inst; struct roar_stream * s = ROAR_STREAM(self->stream); long inlen; int need_data = 0; struct roar_buffer_stats stats; size_t stlen; ROAR_DBG("cf_fishsound_read(inst=%p, buf=%p, len=%i) = ?", inst, buf, len); /* if ( self->opened ) { // return stream_vio_s_read(self->stream, buf, len); } else { /-* if (stream_vio_s_read(self->stream, tbuf, 44) != 44) { return -1; } *ä/ self->opened = 1; errno = EAGAIN; return -1; } */ if ( self->buffer == NULL ) { need_data = 1; } else { if ( roar_buffer_ring_stats(self->buffer, &stats) == -1 ) return -1; if ( stats.bytes < len ) need_data = 1; } ROAR_DBG("cf_fishsound_read(*): need_data=%i, self->opened=%i", need_data, self->opened); // while (need_data) { if ( (inlen = stream_vio_s_read(self->stream, buf, len)) == -1 ) { // if ( errno != EAGAIN ) { return -1; /* } else { return -1; } */ } else { if ( inlen == 0 ) return 0; oggz_read_input(self->oggz, (unsigned char *)buf, inlen); if( self->buffer != NULL ) { if ( roar_buffer_ring_stats(self->buffer, &stats) == -1 ) return -1; if ( stats.bytes < len ) { need_data = 1; } else { need_data = 0; } } } // } ROAR_DBG("cf_fishsound_read(*): need_data=%i, self->opened=%i", need_data, self->opened); if ( need_data ) { errno = EAGAIN; return -1; } if ( !self->opened ) { s->info.channels = self->fsinfo.channels; s->info.rate = self->fsinfo.samplerate; s->info.bits = g_sa->bits; s->info.codec = ROAR_CODEC_NATIVE; self->opened = 1; errno = EAGAIN; ROAR_DBG("cf_fishsound_read(inst=%p, buf=%p, len=%i) = -1 // errno=EAGAIN", inst, buf, len); return -1; } // ok, now we should have all the data we want... stlen = len; if ( roar_buffer_shift_out(&(self->buffer), buf, &stlen) == -1 ) { ROAR_DBG("cf_fishsound_read(inst=%p, buf=%p, len=%i) = -1 // roar_buffer_shift_out() failed", inst, buf, len); return -1; } ROAR_DBG("cf_fishsound_read(inst=%p, buf=%p, len=%i) = %i", inst, buf, len, (int)stlen); return stlen; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_flac.c0000644000175000017500000002467312264733660017227 0ustar phiphi//codecfilter_flac.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #include #ifdef ROAR_HAVE_LIBFLAC FLAC__StreamDecoderReadStatus cf_flac_cb_read(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) { struct codecfilter_flac_inst * self = client_data; ssize_t ret; ROAR_DBG("cf_flac_cb_read(decoder=%p, buffer=%p, bytes=%p{%u}, client_data=%p) = ?", decoder, buffer, bytes, *bytes, client_data); ret = stream_vio_s_read(self->ss, buffer, *bytes); self->decoder.readret = ret; self->decoder.readc++; if (ret == -1) { *bytes = 0; #ifdef EAGAIN if ( errno == EAGAIN ) { ROAR_DBG("cf_flac_cb_read(decoder=%p, buffer=%p, bytes=%p{%u}, client_data=%p) = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE", decoder, buffer, bytes, *bytes, client_data); return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } #endif ROAR_DBG("cf_flac_cb_read(decoder=%p, buffer=%p, bytes=%p{%u}, client_data=%p) = FLAC__STREAM_DECODER_READ_STATUS_ABORT", decoder, buffer, bytes, *bytes, client_data); return FLAC__STREAM_DECODER_READ_STATUS_ABORT; } else { *bytes = ret; if ( ret == 0 && self->decoder.readc == 1 ) { ROAR_DBG("cf_flac_cb_read(decoder=%p, buffer=%p, bytes=%p{%u}, client_data=%p) = FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM", decoder, buffer, bytes, *bytes, client_data); return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; } ROAR_DBG("cf_flac_cb_read(decoder=%p, buffer=%p, bytes=%p{%u}, client_data=%p) = FLAC__STREAM_DECODER_READ_STATUS_CONTINUE", decoder, buffer, bytes, *bytes, client_data); return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } } FLAC__StreamDecoderWriteStatus cf_flac_cb_write(const FLAC__StreamDecoder * decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { struct codecfilter_flac_inst * self = client_data; struct roar_buffer * buf; struct roar_interleave is; size_t buflen = _32BIT * frame->header.blocksize * frame->header.channels; void * bufdata; int32_t * c; size_t i; int32_t shift = 32 - frame->header.bits_per_sample; ROAR_DBG("cf_flac_cb_write(decoder=%p, frame=%p, buffer=%p, client_data=%p) = ?", decoder, frame, buffer, client_data); if ( roar_interl_init(&is, frame->header.channels, 32) == -1 ) { ROAR_DBG("cf_flac_cb_write(decoder=%p, frame=%p, buffer=%p, client_data=%p) = FLAC__STREAM_DECODER_WRITE_STATUS_ABORT", decoder, frame, buffer, client_data); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } if ( roar_buffer_new_data(&buf, buflen, &bufdata) == -1 ) { ROAR_DBG("cf_flac_cb_write(decoder=%p, frame=%p, buffer=%p, client_data=%p) = FLAC__STREAM_DECODER_WRITE_STATUS_ABORT", decoder, frame, buffer, client_data); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } roar_interl_encode_ext(&is, (void**)buffer, bufdata, buflen); roar_interl_uninit(&is); if ( shift ) { buflen /= 4; for (c = bufdata, i = 0; i < buflen; i++) { c[i] <<= shift; } } if ( self->decoder.written == NULL ) { self->decoder.written = buf; } else { if ( roar_buffer_moveinto(self->decoder.written, &buf) == -1 ) { roar_buffer_free(buf); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } } ROAR_DBG("cf_flac_cb_write(decoder=%p, frame=%p, buffer=%p, client_data=%p) = FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE", decoder, frame, buffer, client_data); return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } void cf_flac_cb_metadata(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { struct codecfilter_flac_inst * self = client_data; const FLAC__StreamMetadata_VorbisComment * vc; FLAC__uint32 i; struct roar_stream_rpg rpg; const char * key, * value; char keycopy[ROAR_META_MAX_NAMELEN]; int type; float rpg_track = 0, rpg_album = 0, rpg_final = 0; if ( metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT ) { ROAR_DBG("cf_flac_cb_metadata(decoder=%p, metadata=%p, client_data=%p): have METADATA_TYPE_VORBIS_COMMENT", decoder, metadata, client_data); stream_meta_clear(ROAR_STREAM(self->ss)->id); vc = &(metadata->data.vorbis_comment); for (i = 0; i < vc->num_comments; i++) { //printf("c='%s'\n", vc->comments[i].entry); key = (const char *)vc->comments[i].entry; value = strstr(key, "="); if ( value == NULL ) continue; if ( (value - key + 1) > sizeof(keycopy) ) continue; memcpy(keycopy, key, value - key); keycopy[sizeof(keycopy)-1] = 0; keycopy[value - key] = 0; value++; //printf("keycopy='%s', value='%s'\n", keycopy, value); type = roar_meta_inttype(keycopy); if ( type == -1 ) continue; if ( stream_meta_add(ROAR_STREAM(self->ss)->id, type, "", value) == -1 ) { ROAR_WARN("cf_flac_cb_metadata(..., client_data=%p{ROAR_STREAM(.ss)->id=%i}): Can not add meta data: %s", self->ss, ROAR_STREAM(self->ss)->id, roar_error2str(roar_error)); } if ( strcmp(keycopy, "REPLAYGAIN_TRACK_PEAK") == 0 ) { rpg_track = 1/atof(value); /* } else if ( strcmp(key, "REPLAYGAIN_TRACK_GAIN") == 0 ) { rpg_track = powf(10, atof(value)/20); */ } else if ( strcmp(keycopy, "REPLAYGAIN_ALBUM_PEAK") == 0 ) { rpg_album = 1/atof(value); /* } else if ( strcmp(key, "REPLAYGAIN_ALBUM_GAIN") == 0 ) { rpg_album = powf(10, atof(value)/20); */ } } if ( streams_get_rpg(ROAR_STREAM(self->ss)->id, &rpg) != -1 ) { rpg_final = 0; switch (rpg.mode) { case ROAR_RPGMODE_NONE: rpg_final = 0.; break; case ROAR_RPGMODE_USER: rpg_final = -1.; break; case ROAR_RPGMODE_ALBUM: rpg_final = rpg_album; break; case ROAR_RPGMODE_TRACK: rpg_final = rpg_track; break; case ROAR_RPGMODE_ALBUMTRACK: rpg_final = rpg_album ? rpg_album : rpg_track; break; case ROAR_RPGMODE_TRACKALBUM: rpg_final = rpg_track ? rpg_track : rpg_album; break; } if ( rpg_final > 0 ) { self->ss->mixer.rpg_div = 2718; self->ss->mixer.rpg_mul = (float)rpg_final*2718; } else if ( !rpg_final ) { self->ss->mixer.rpg_div = 1; self->ss->mixer.rpg_mul = 1; } } stream_meta_finalize(ROAR_STREAM(self->ss)->id); } ROAR_DBG("cf_flac_cb_metadata(decoder=%p, metadata=%p, client_data=%p) = (void)", decoder, metadata, client_data); } void cf_flac_cb_error(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { ROAR_DBG("cf_flac_cb_error(decoder=%p, status=%i, client_data=%p) = (void)", decoder, (int)status, client_data); } int cf_flac_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_flac_inst * self; if ( ROAR_STREAM(info)->dir != ROAR_DIR_PLAY ) return -1; self = roar_mm_malloc(sizeof(struct codecfilter_flac_inst)); if (self == NULL) return -1; memset(self, 0, sizeof(struct codecfilter_flac_inst)); self->ss = info; self->decoder.decoder = FLAC__stream_decoder_new(); if ( self->decoder.decoder == NULL ) { roar_mm_free(self); return -1; } #ifndef ROAR_HAVE_FLAC_VERSION_1_2_1 FLAC__stream_decoder_set_read_callback(self->decoder.decoder, cf_flac_cb_read); FLAC__stream_decoder_set_write_callback(self->decoder.decoder, cf_flac_cb_write); FLAC__stream_decoder_set_metadata_callback(self->decoder.decoder, cf_flac_cb_metadata); FLAC__stream_decoder_set_error_callback(self->decoder.decoder, cf_flac_cb_error); FLAC__stream_decoder_set_client_data(self->decoder.decoder, self); #endif FLAC__stream_decoder_set_metadata_respond(self->decoder.decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); #ifdef ROAR_HAVE_FLAC_VERSION_1_2_1 FLAC__stream_decoder_init_stream(self->decoder.decoder, cf_flac_cb_read, NULL, NULL, NULL, NULL, cf_flac_cb_write, cf_flac_cb_metadata, cf_flac_cb_error, self); #else FLAC__stream_decoder_init(self->decoder.decoder); #endif *inst = self; return 0; } int cf_flac_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_flac_inst * self = inst; if ( self->decoder.decoder != NULL ) { FLAC__stream_decoder_delete(self->decoder.decoder); } roar_mm_free(self); return 0; } int cf_flac_write(CODECFILTER_USERDATA_T inst, char * buf, int len); int cf_flac_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_flac_inst * self = inst; struct roar_audio_info * info = &(ROAR_STREAM(self->ss)->info); struct roar_buffer_stats stats; size_t ret; FLAC__StreamDecoderState state; if ( self->decoder.written == NULL ) { stats.bytes = 0; } else { if ( roar_buffer_ring_stats(self->decoder.written, &stats) == -1 ) return -1; } self->decoder.readret = 1; self->decoder.readc = 0; while ( self->decoder.readret > 0 && stats.bytes < len ) { if ( !FLAC__stream_decoder_process_single(self->decoder.decoder) ) { break; } state = FLAC__stream_decoder_get_state(self->decoder.decoder); if ( state == FLAC__STREAM_DECODER_END_OF_STREAM || state == FLAC__STREAM_DECODER_ABORTED ) break; if ( self->decoder.written == NULL && state == FLAC__STREAM_DECODER_READ_FRAME ) { return -1; } if ( self->decoder.written == NULL ) { stats.bytes = 0; } else { if ( roar_buffer_ring_stats(self->decoder.written, &stats) == -1 ) return -1; } } if ( stats.bytes ) { ret = len; if ( roar_buffer_shift_out(&(self->decoder.written), buf, &ret) == -1 ) { return -1; } info->codec = ROAR_CODEC_DEFAULT; info->bits = 32; info->channels = FLAC__stream_decoder_get_channels(self->decoder.decoder); info->rate = FLAC__stream_decoder_get_sample_rate(self->decoder.decoder); return ret; } else { return self->decoder.readret == -1 ? -1 : 0; } } int cf_flac_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data); #endif //ll roaraudio-1.0beta11/roard/codecfilter_mulaw.c0000644000175000017500000000504012264733661017433 0ustar phiphi//codecfilter_mulaw.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * ckport: ignore-symbol: roardsp_conv_pcm162mulaw of target libroardsp0 * ckport: ignore-symbol: roardsp_conv_mulaw2pcm16 of target libroardsp0 */ #include "roard.h" #ifdef ROAR_SUPPORT_MULAW int cf_mulaw_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct roar_stream * s = ROAR_STREAM(info); (void)codec, (void)filter; *inst = (CODECFILTER_USERDATA_T) info; s->info.bits = 16; s->info.codec = ROAR_CODEC_DEFAULT; return 0; } int cf_mulaw_close(CODECFILTER_USERDATA_T inst) { (void)inst; return 0; } int cf_mulaw_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct roar_stream_server * s = ROAR_STREAM_SERVER(inst); if ( (len = stream_vio_s_read(s, buf, len/2)) < 1 ) { return len; } roardsp_conv_mulaw2pcm16((int16_t *)buf, buf, len); return len*2; } #ifdef ROAR_SUPPORT_MULAW_RW int cf_mulaw_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct roar_stream_server * s = ROAR_STREAM_SERVER(inst); char * out; // TODO: add a more effect way to use memory than allways alloc/freeing it. // maybe by keeping a buffer over instanzes or by using ca global buffer // with an refrenze counter so we can free it on last use len /= 2; if ( (out = (char*)roar_mm_malloc(len)) == NULL ) return -1; roardsp_conv_pcm162mulaw(out, (int16_t*)buf, len); len = stream_vio_s_write(s, out, len); roar_mm_free(out); if ( len > 0 ) { return len*2; } else { return -1; } } #endif #endif //ll roaraudio-1.0beta11/roard/codecfilter_raum.c0000644000175000017500000001003212264733662017250 0ustar phiphi//codecfilter_raum.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBRAUM #include // PCBs: int cf_raum_pcb_open (struct cont_fw_parent_inst * self, int codec, struct roar_stream_server * stream, struct roar_codecfilter * filter) { struct roar_stream * s = ROAR_STREAM(stream); RAUMState * state; int flags = 0; ROAR_DBG("cf_raum_pcb_open(*) = ?"); if ( stream == NULL ) return -1; switch (s->dir) { case ROAR_DIR_COMPLEX_IN: case ROAR_DIR_PLAY: flags = O_RDONLY; break; case ROAR_DIR_COMPLEX_OUT: case ROAR_DIR_MONITOR: case ROAR_DIR_OUTPUT: flags = O_WRONLY; break; default: return -1; } state = RAUMOpenVIO(&(self->vio), flags); if ( state == NULL ) return -1; cont_fw_set_uinst(self, state); ROAR_DBG("cf_raum_pcb_open(*) = 0"); return 0; } int cf_raum_pcb_close (struct cont_fw_parent_inst * self) { void * state; ROAR_DBG("cf_raum_pcb_close(*) = ?"); if ( cont_fw_get_uinst(self, &state) == -1 ) return -1; ROAR_DBG("cf_raum_pcb_close(*) = ?"); return RAUMClose(state); } int cf_raum_pcb_new_child(struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child) { struct roar_stream_server * ss; struct roar_stream * s; void * ps; RAUMStream * stream; int dir = ROAR_DIR_PLAY; ROAR_DBG("cf_raum_pcb_new_child(self=%p, child=%p) = ?", self, child); if ( streams_get(child->child, &ss) == -1 ) return -1; if ( (s = ROAR_STREAM(ss)) == NULL ) return -1; if ( cont_fw_get_uinst(self, &ps) == -1 ) return -1; if ( ps == NULL ) return -1; if ( (stream = RAUMStreamNewSimple(s->info.rate, s->info.channels, s->info.bits, s->info.codec, dir)) == NULL ) return -1; if ( RAUMAddStream(ps, stream) == -1 ) { RAUMStreamClose(stream); return -1; } child->u_inst = stream; ROAR_DBG("cf_raum_pcb_new_child(self=%p, child=%p) = 0", self, child); return 0; } // CCBs: ssize_t cf_raum_ccb_read (struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child, void *buf, size_t len) { ROAR_DBG("cf_raum_ccb_read(self=%p, child=%p, buf=%p, len=%lu) = ?", self, child, buf, (unsigned long)len); return RAUMStreamRead(child->u_inst, buf, len); } ssize_t cf_raum_ccb_write(struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child, void *buf, size_t len) { ROAR_DBG("cf_raum_ccb_write(self=%p, child=%p, buf=%p, len=%lu) = ?", self, child, buf, (unsigned long)len); return RAUMStreamWrite(child->u_inst, buf, len); } int cf_raum_ccb_close(struct cont_fw_parent_inst * self, struct cont_fw_child_vio_inst * child) { ROAR_DBG("cf_raum_ccb_close(self=%p, child=%p) = ?", self, child); return RAUMStreamClose(child->u_inst); } // SETUP: CONT_FW_SETUP_TYPE(cf_raum_setup) { ROAR_DBG("cf_raum_setup(*) = ?"); // PCBs: self->pcb.open = cf_raum_pcb_open; self->pcb.close = cf_raum_pcb_close; self->pcb.new_child = cf_raum_pcb_new_child; // CCBs: self->ccb.read = cf_raum_ccb_read; self->ccb.write = cf_raum_ccb_write; self->ccb.close = cf_raum_ccb_close; ROAR_DBG("cf_raum_setup(*) = 0"); return 0; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_roardmx.c0000644000175000017500000000764312264733662017776 0ustar phiphi//codecfilter_roardmx.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_LIGHT static inline int __read_sset(int id, struct roar_stream_server * ss, struct roar_roardmx_message * mes) { uint16_t channel; uint8_t value; int i, c; // we ignore errors here at the moment as 0 not < -1 c = roar_roardmx_message_numchannels(mes); ROAR_DBG("light_check_stream(id=%i): Number of subframes: %u", id, c); for (i = 0; i < c; i++) { if ( roar_roardmx_message_get_chanval(mes, &channel, &value, i) == -1 ) return -1; if ( g_light_state.channels < channel ) { ROAR_WARN("light_check_stream(id=%i): Writing on non extisting DMX channel %u", id, channel); continue; } else { g_light_state.state[channel] = value; g_light_state.changes[channel] = 0xFF; // the channel changed } } return 0; } static inline int __read_events(int id, struct roar_stream_server * ss, struct roar_roardmx_message * mes) { const uint8_t * events; size_t len; (void)id, (void)ss; if ( roar_roardmx_message_get_events(mes, &events, &len) == -1 ) return -1; return light_dmxevent_add(events, len); } int cf_light_roardmx_read(int id, struct roar_stream_server * ss) { struct roar_roardmx_message mes; unsigned char type; if ( roar_roardmx_message_recv(&mes, &(ss->vio)) == -1 ) return -1; if ( roar_roardmx_message_get_type(&mes, &type) == -1 ) return -1; switch (type) { case ROAR_ROARDMX_TYPE_SSET: return __read_sset(id, ss, &mes); break; case ROAR_ROARDMX_TYPE_EVENT: return __read_events(id, ss, &mes); break; } roar_err_set(ROAR_ERROR_NSTYPE); return -1; } static inline int __write_events(int id, struct roar_stream_server * ss) { struct roar_roardmx_message mes; const uint8_t * events; size_t len; if ( light_dmxevent_read(&events, &len) == -1 ) return -1; // check if we need to send events at all: if ( len == 0 ) return 0; // ok, now let's build the message: if ( roar_roardmx_message_new_event(&mes) == -1 ) return -1; if ( roar_roardmx_message_add_events(&mes, events, len) == -1 ) return -1; // and send it: if ( roar_roardmx_message_send(&mes, &(ss->vio)) == -1 ) return -1; return 0; } static inline int __write_channels(int id, struct roar_stream_server * ss) { struct roar_roardmx_message mes; int have_message = 0; int i; for (i = 0; i < g_light_state.channels; i++) { if ( g_light_state.changes[i] ) { if ( !have_message ) if ( roar_roardmx_message_new_sset(&mes) == -1 ) return -1; have_message = 2; if ( roar_roardmx_message_add_chanval(&mes, i, g_light_state.state[i]) == -1 ) { if ( roar_roardmx_message_send(&mes, &(ss->vio)) == -1 ) return -1; if ( roar_roardmx_message_new_sset(&mes) == -1 ) return -1; have_message = 1; } } } if ( have_message == 2 ) if ( roar_roardmx_message_send(&mes, &(ss->vio)) == -1 ) return -1; return 0; } int cf_light_roardmx_write(int id, struct roar_stream_server * ss) { if ( __write_events(id, ss) == -1 ) return -1; if ( __write_channels(id, ss) == -1 ) return -1; return 0; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_sndfile.c0000644000175000017500000001212712264733662017737 0ustar phiphi//codecfilter_sndfile.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBSNDFILE int cf_sndfile_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_sndfile_inst * obj; (void)codec, (void)filter; if ( (obj = (struct codecfilter_sndfile_inst *) roar_mm_malloc(sizeof(struct codecfilter_sndfile_inst))) == NULL ) return -1; memset(obj, 0, sizeof(struct codecfilter_sndfile_inst)); obj->stream = info; ROAR_STREAM(info)->info.codec = ROAR_CODEC_DEFAULT; *inst = (CODECFILTER_USERDATA_T) obj; /* s->info.bits = 16; s->info.codec = ROAR_CODEC_DEFAULT; */ ROAR_WARN("cf_sndfile_open(*) = 0"); return 0; } int cf_sndfile_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_sndfile_inst * obj = (struct codecfilter_sndfile_inst *) inst; if ( obj->state != NULL ) sf_close(obj->state); roar_mm_free(obj); return 0; } int cf_sndfile_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_sndfile_inst * obj = (struct codecfilter_sndfile_inst *) inst; struct roar_stream * s = ROAR_STREAM(obj->stream); int ret; if ( obj->opened ) { len /= obj->bytes; if ( obj->bytes == 2 ) { if ( (ret = sf_read_short(obj->state, (short*)buf, len)) == -1 ) return -1; } else if ( obj->bytes == 4 ) { if ( (ret = sf_read_int(obj->state, (int*)buf, len)) == -1 ) return -1; } else { errno = ENOSYS; return -1; } return ret * obj->bytes; } else { if ( (obj->state = sf_open_fd(s->fh, SFM_READ, &(obj->info), 0)) == NULL ) { ROAR_ERR("cf_sndfile_read(*): can not sf_open_fd(*)!"); return -1; } ROAR_WARN("cf_sndfile_read(*): obj->info={.format=0x%.8x, .samplerate=%i, .channels=%i}", obj->info.format, obj->info.samplerate, obj->info.channels); s->info.codec = ROAR_CODEC_DEFAULT; s->info.rate = obj->info.samplerate; s->info.channels = obj->info.channels; obj->bytes = 2; if ( (obj->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_24 || (obj->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_32 ) { obj->bytes = 4; } s->info.bits = obj->bytes * 8; obj->opened = 1; errno = EAGAIN; } return -1; } int cf_sndfile_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_sndfile_inst * obj = (struct codecfilter_sndfile_inst *) inst; struct roar_stream * s = ROAR_STREAM(obj->stream); int ret; ROAR_WARN("cf_sndfile_write(*): obj->opened=%i", obj->opened); if ( !obj->opened ) { if ( s->fh == -1 ) { errno = EAGAIN; return -1; } switch (s->info.codec) { case ROAR_CODEC_PCM_S_LE: case ROAR_CODEC_PCM_S_BE: switch (s->info.bits) { case 8: obj->info.format = SF_FORMAT_PCM_S8; break; case 16: obj->info.format = SF_FORMAT_PCM_16; break; case 24: obj->info.format = SF_FORMAT_PCM_24; break; case 32: obj->info.format = SF_FORMAT_PCM_32; break; } //obj->info.format |= s->info.codec == ROAR_CODEC_PCM_S_LE ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG; obj->info.format |= SF_ENDIAN_FILE; obj->info.format |= SF_FORMAT_WAV; break; default: ROAR_ERR("cf_sndfile_write(*): codec(%s) not supported!", roar_codec2str(s->info.bits)); return -1; break; } obj->info.samplerate = s->info.rate; obj->info.channels = s->info.channels; obj->info.sections = 1; obj->info.frames = 182592; // 2147483647; obj->info.seekable = 1; obj->info.format = 0x00010002; if ( (obj->state = sf_open_fd(s->fh, SFM_WRITE, &(obj->info), 0)) == NULL ) { ROAR_ERR("cf_sndfile_write(*): can not sf_open_fd(*)!"); ROAR_ERR("cf_sndfile_write(*): s->fh=%i", s->fh); ROAR_ERR("cf_sndfile_write(*): obj->info={.format=0x%.8x, .samplerate=%i, .channels=%i}", obj->info.format, obj->info.samplerate, obj->info.channels); return -1; } obj->opened = 1; // errno = EAGAIN; } ROAR_WARN("cf_sndfile_write(*): obj->opened=%i", obj->opened); ret = sf_write_raw(obj->state, (void*) buf, len); ROAR_WARN("cf_sndfile_write(inst=%p, buf=%p, len=%i) = %i", inst, buf, len, ret); return ret; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_speex.c0000644000175000017500000002642612264733662017446 0ustar phiphi//codecfilter_speex.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBSPEEX /* Format: (all numbers are in network byte order) MAGIC of site MAGIC_LEN MODE NUMMBER of size 2 Byte { // frames FRAME LENGTH of size 2 Byte FRAME DATA of size FRAME LENGTH Byte } */ #define _FS (_16BIT * (self->stereo ? 2 : 1)) #define _HAVE_CCFG(x) (self->codec_config != NULL && (self->codec_config->para_set & (x))) int cf_speex_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_speex_inst * self = roar_mm_malloc(sizeof(struct codecfilter_speex_inst)); struct roar_stream * s = ROAR_STREAM(info); *inst = NULL; if (!self) return -1; s->info.codec = ROAR_CODEC_DEFAULT; s->info.bits = 16; // speex hardcoded switch (s->info.channels) { case 1: self->stereo = 0; break; case 2: self->stereo = 1; break; default: roar_mm_free(self); return -1; } // do as much to preper the startup of stereo encoder as possible if ( self->stereo ) { self->stereo_callback.callback_id = SPEEX_INBAND_STEREO; self->stereo_callback.func = speex_std_stereo_request_handler; self->stereo_callback.data = &(self->stereo_state); } self->encoder = NULL; self->decoder = NULL; self->stream = info; self->cd = NULL; self->i_rest = NULL; self->fi_rest = 0; self->o_rest = NULL; self->fo_rest = 0; self->codec_config = roar_libroar_config_codec_get(ROAR_CODEC_ROAR_SPEEX, 0); speex_bits_init(&(self->bits)); *inst = (void*) self; return 0; } int cf_speex_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_speex_inst * self = (struct codecfilter_speex_inst *) inst; if (!self) return -1; if ( self->encoder ) speex_encoder_destroy(self->encoder); self->encoder = NULL; if ( self->decoder ) speex_decoder_destroy(self->decoder); self->decoder = NULL; speex_bits_destroy(&(self->bits)); if ( self->cd != NULL ) roar_mm_free(self->cd); if ( self->i_rest != NULL ) roar_mm_free(self->i_rest); roar_mm_free((void*)self); return 0; } int cf_speex_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_speex_inst * self = (struct codecfilter_speex_inst *) inst; int mode; uint16_t ui; int tmp; int still_todo = len / _FS; int ret = 0; int fs2; // = self->frame_size * _16BIT * channels; char magic[ROAR_SPEEX_MAGIC_LEN]; SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT; ROAR_DBG("cf_speex_read(inst=%p, buf=%p, len=%i) = ?", inst, buf, len); if ( ! self->decoder ) { ROAR_DBG("cf_speex_read(*): no decoder, starting one!"); if ( stream_vio_s_read(self->stream, magic, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN ) return 0; if ( memcmp(magic, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != 0 ) return -1; if ( stream_vio_s_read(self->stream, &ui, 2) != 2 ) return 0; mode = ROAR_NET2HOST16(ui); switch (mode) { case ROAR_SPEEX_MODE_NB: self->decoder = speex_decoder_init(&speex_nb_mode); break; case ROAR_SPEEX_MODE_WB: self->decoder = speex_decoder_init(&speex_wb_mode); break; case ROAR_SPEEX_MODE_UWB: self->decoder = speex_decoder_init(&speex_uwb_mode); break; default: return 0; } tmp=1; speex_decoder_ctl(self->decoder, SPEEX_SET_ENH, &tmp); if ( self->stereo ) { memcpy(&(self->stereo_state), &stereo, sizeof(self->stereo_state)); speex_decoder_ctl(self->decoder, SPEEX_SET_HANDLER, &(self->stereo_callback)); } speex_decoder_ctl(self->decoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size)); fs2 = self->frame_size * _FS; ROAR_DBG("cf_speex_read(*): frame_size=%i (%i bytes)", self->frame_size, fs2); if ( self->cd == NULL ) { self->cd = roar_mm_malloc(fs2); if ( self->cd == NULL ) return 0; } if ( self->i_rest == NULL ) { self->i_rest = roar_mm_malloc(fs2); if ( self->i_rest == NULL ) return 0; } } fs2 = self->frame_size * _FS; ROAR_DBG("cf_speex_read(*): Have a working decoder!"); ROAR_DBG("cf_speex_read(*): frame_size=%i (%i bytes)", self->frame_size, fs2); ROAR_DBG("cf_speex_read(*): i_rest is %i bytes after cd", ((void*)self->i_rest - (void*)self->cd)); if ( self->fi_rest ) { if ( self->fi_rest > (still_todo*_FS) ) { ROAR_DBG("cf_speex_read(*): using data from input rest buffer: len=%i (no need to read new data)", self->fi_rest); still_todo *= _FS; // we will set this to zero one way or another, // so we don't need to care about soring a 'wrong' value here. memcpy(buf, self->i_rest, still_todo); memmove(self->i_rest, self->i_rest + still_todo, self->fi_rest - still_todo); self->fi_rest -= still_todo; ret += still_todo; still_todo = 0; } else { ROAR_DBG("cf_speex_read(*): using data from input rest buffer: len=%i", self->fi_rest); memcpy(buf, self->i_rest, self->fi_rest); buf += self->fi_rest; still_todo -= self->fi_rest/_FS; ret += self->fi_rest; self->fi_rest = 0; } } while (still_todo) { ROAR_DBG("cf_speex_read(*): we sill need %i frames", still_todo); if ( stream_vio_s_read(self->stream, &ui, 2) != 2 ) return -1; ui = ROAR_NET2HOST16(ui); if ( ui > ROAR_SPEEX_MAX_CC ) return 0; if ( stream_vio_s_read(self->stream, self->cc, ui) != ui ) break; speex_bits_read_from(&(self->bits), self->cc, ui); speex_decode_int(self->decoder, &(self->bits), self->cd); if ( self->stereo) { speex_decode_stereo_int(self->cd, self->frame_size, &(self->stereo_state)); } if ( self->frame_size > still_todo ) { memcpy(buf, self->cd, still_todo*_FS); ret += still_todo*_FS; self->fi_rest = (self->frame_size - still_todo)*_FS; ROAR_DBG("cf_speex_read(*): self->fi_rest=%i, off=%i", self->fi_rest, still_todo*_FS); memcpy(self->i_rest, (self->cd)+(still_todo*_FS), self->fi_rest); still_todo = 0; } else { memcpy(buf, self->cd, fs2); buf += fs2; ret += fs2; still_todo -= self->frame_size; } } if ( still_todo ) { ROAR_DBG("cf_speex_read(*): could not read all reqquested data, returning %i byte less", still_todo*_FS); } ROAR_DBG("cf_speex_read(*) = %i", ret); return ret; } int cf_speex_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_speex_inst * self = (struct codecfilter_speex_inst *) inst; uint16_t mode = ROAR_SPEEX_MODE_UWB; int tmp; int fs2; int ret = 0; int need_extra; int sid; void * prethru; /* TODO: Befor this realy works there must be a working way to set the number of channels and bits for monetoring clients. Else this will produce some thing stange as a 'mono' file that realy contains stereo. */ ROAR_DBG("cf_speex_write(inst=%p, buf=%p, len=%i) = ?", inst, buf, len); if ( ! self->encoder ) { sid = ROAR_STREAM(self->stream)->id; if ( stream_prethru_destroy(sid) == -1 ) { return -1; } if ( stream_prethru_add_data(sid, &prethru, ROAR_SPEEX_MAGIC_LEN) == -1 ) { return -1; } memcpy(prethru, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN); if ( stream_vio_s_write(self->stream, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) != ROAR_SPEEX_MAGIC_LEN ) return -1; switch (mode) { case ROAR_SPEEX_MODE_NB: self->encoder = speex_encoder_init(&speex_nb_mode); break; case ROAR_SPEEX_MODE_WB: self->encoder = speex_encoder_init(&speex_wb_mode); break; case ROAR_SPEEX_MODE_UWB: self->encoder = speex_encoder_init(&speex_uwb_mode); break; default: return -1; } mode = ROAR_HOST2NET16(mode); if ( stream_prethru_add_data(sid, &prethru, 2) == -1 ) { return -1; } *(uint16_t*)prethru = mode; if ( stream_vio_s_write(self->stream, &mode, 2) != 2 ) return -1; if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_COMPLEXITY) ) { tmp = self->codec_config->complexity / 256; } else { tmp = 8; } speex_encoder_ctl(self->encoder, SPEEX_SET_COMPLEXITY, &tmp); if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_Q) ) { tmp = self->codec_config->q / 256; speex_encoder_ctl(self->encoder, SPEEX_SET_QUALITY, &tmp); } if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_VBR) ) { tmp = self->codec_config->vbr ? 1 : 0; speex_encoder_ctl(self->encoder, SPEEX_SET_VBR, &tmp); } if ( _HAVE_CCFG(ROAR_LIBROAR_CONFIG_PSET_DTX) ) { tmp = self->codec_config->dtx ? 1 : 0; speex_encoder_ctl(self->encoder, SPEEX_SET_DTX, &tmp); } speex_encoder_ctl(self->encoder, SPEEX_GET_FRAME_SIZE, &(self->frame_size)); fs2 = self->frame_size * _FS; if ( self->cd == NULL ) { self->cd = roar_mm_malloc(fs2 + 2); if ( self->cd == NULL ) return 0; } if ( self->o_rest == NULL ) { self->o_rest = roar_mm_malloc(fs2); if ( self->o_rest == NULL ) return 0; } } fs2 = self->frame_size * _FS; if ( self->fo_rest ) { // ignore the rest for the moment if ( (self->fo_rest + len) > fs2 ) { need_extra = fs2 - self->fo_rest; memcpy(self->o_rest + self->fo_rest, buf, need_extra); speex_bits_reset(&(self->bits)); if ( self->stereo ) speex_encode_stereo_int((spx_int16_t *) self->o_rest, self->frame_size, &(self->bits)); speex_encode_int(self->encoder, (spx_int16_t *) self->o_rest, &(self->bits)); tmp = mode = speex_bits_write(&(self->bits), self->cd + 2, fs2); mode = ROAR_HOST2NET16(mode); *(uint16_t*)(self->cd) = mode; if ( stream_vio_s_write(self->stream, self->cd, tmp + 2) != (tmp + 2) ) return -1; buf += need_extra; ret += need_extra; len -= need_extra; self->fo_rest = 0; } else { // just add the data to o_rest memcpy(self->o_rest + self->fo_rest, buf, len); self->fo_rest += len; return len; } } // TODO: do we realy need such a loop? while (len > fs2) { // ROAR_WARN("cf_speex_write(*): Discarding a full block of data as non-o_rest encoding is not supported!"); // ROAR_WARN("cf_speex_write(*): Block info: len=%i, fs2=%i", len, fs2); speex_bits_reset(&(self->bits)); if ( self->stereo ) speex_encode_stereo_int((spx_int16_t *) buf, self->frame_size, &(self->bits)); speex_encode_int(self->encoder, (spx_int16_t *) buf, &(self->bits)); tmp = mode = speex_bits_write(&(self->bits), self->cd + 2, fs2); mode = ROAR_HOST2NET16(mode); *(uint16_t*)(self->cd) = mode; if ( stream_vio_s_write(self->stream, self->cd, tmp + 2) != (tmp + 2) ) return -1; len -= fs2; buf += fs2; ret += fs2; } if ( len ) { // we still have some data, add this to o_rest memcpy(self->o_rest, buf, len); self->fo_rest = len; ret += len; } return ret; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_uniraum.c0000644000175000017500000005063312264733663020000 0ustar phiphi//codecfilter_wave.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBUNIRAUM #include #define MAX_STREAMS 4 struct codecfilter_uniraum_inst; struct codecfilter_uniraum_inst_stream { size_t refc; struct codecfilter_uniraum_inst * parent; struct roar_stream_server * ss; int stream; uniraum_stream_t * uniraumstream; uniraum_mapping_t * uniraummapping; uniraum_data_t * dataqueue; }; struct codecfilter_uniraum_inst { size_t refc; struct roar_stream_server * ss; struct roar_vio_calls vio; uniraum_file_t * file; struct codecfilter_uniraum_inst_stream stream[MAX_STREAMS]; size_t streams; int got_eof; int is_execed; }; static inline void __stream_ref(struct codecfilter_uniraum_inst_stream * self); static inline void __stream_unref(struct codecfilter_uniraum_inst_stream * self); static inline int __read_more_data(struct codecfilter_uniraum_inst * self, int stream); static inline void __stream_pushdata(struct codecfilter_uniraum_inst_stream * self); static inline void __stream_setup_vio(struct codecfilter_uniraum_inst_stream * self); static inline void __inst_ref(struct codecfilter_uniraum_inst * self) { self->refc++; } static inline void __inst_unref(struct codecfilter_uniraum_inst * self) { self->refc--; if ( self->refc ) return; uniraum_unref(self->file); self->file = NULL; roar_mm_free(self); } struct codecfilter_uniraum_inst_stream * __stream_get(struct codecfilter_uniraum_inst * self, int stream) { size_t i; for (i = 0; i < MAX_STREAMS; i++) { if ( self->stream[i].refc && self->stream[i].stream == stream ) { __stream_ref(&(self->stream[i])); return &(self->stream[i]); } } roar_err_set(ROAR_ERROR_NOENT); return NULL; } struct codecfilter_uniraum_inst_stream * __stream_new(struct codecfilter_uniraum_inst * self, int stream) { struct codecfilter_uniraum_inst_stream * ret; size_t i; ret = __stream_get(self, stream); if ( ret != NULL ) { __stream_unref(ret); roar_err_set(ROAR_ERROR_EXIST); return NULL; } for (i = 0; i < MAX_STREAMS; i++) { ret = &(self->stream[i]); if ( !ret->refc ) { memset(ret, 0, sizeof(*ret)); ret->refc = 1; ret->parent = self; ret->ss = NULL; ret->stream = stream; ret->uniraumstream = NULL; ret->uniraummapping = NULL; ret->dataqueue = NULL; if ( streams_new_virtual(ROAR_STREAM(self->ss)->id, &(ret->ss)) == -1 ) { ret->refc = 0; return NULL; } __stream_setup_vio(ret); __stream_ref(ret); self->streams++; return ret; } } roar_err_set(ROAR_ERROR_NOSPC); return NULL; } static inline void __stream_ref(struct codecfilter_uniraum_inst_stream * self) { self->refc++; } static inline void __stream_unref(struct codecfilter_uniraum_inst_stream * self) { self->refc--; if ( self->refc ) return; self->parent->streams--; __inst_unref(self->parent); uniraum_stream_unref(self->uniraumstream); uniraum_mapping_unref(self->uniraummapping); roar_buffer_free(self->dataqueue); roar_mm_free(self); } static ssize_t __v_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct codecfilter_uniraum_inst_stream * self = vio->inst; ssize_t done = 0; size_t len; int ret; ROAR_DBG("__v_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); while (count) { ROAR_DBG("__v_read(vio=%p, buf=?, count=?): %llu bytes left to do", vio, (long long unsigned int)count); len = count; if ( self->dataqueue == NULL ) { len = 0; } else if ( roar_buffer_shift_out(&(self->dataqueue), buf, &len) == -1 ) { ROAR_DBG("__v_read(vio=%p, buf=%p, count=?): roar_errorstring=%s", vio, buf, roar_errorstring); break; } if ( len == 0 ) { __stream_pushdata(self); len = count; if ( self->dataqueue == NULL ) { len = 0; } else if ( roar_buffer_shift_out(&(self->dataqueue), buf, &len) == -1 ) { ROAR_DBG("__v_read(vio=%p, buf=%p, count=?): roar_errorstring=%s", vio, buf, roar_errorstring); break; } ROAR_DBG("__v_read(vio=%p, buf=?, count=?) = ?", vio); if ( len == 0 ) { do { ret = __read_more_data(self->parent, self->stream); } while (ret == 0 && self->dataqueue == NULL); //__stream_pushdata(self); len = count; ROAR_DBG("__v_read(vio=%p, buf=?, count=?): self->dataqueue=%p, buf=%p", vio, self->dataqueue, buf); if ( roar_buffer_shift_out(&(self->dataqueue), buf, &len) == -1 ) { ROAR_DBG("__v_read(vio=%p, buf=?, count=?): roar_errorstring=%s", vio, roar_errorstring); break; } } } buf += len; count -= len; done += len; } ROAR_DBG("__v_read(vio=%p, buf=%p, count=?) = %lli", vio, buf, (long long int)done); return done; } static ssize_t __v_write (struct roar_vio_calls * vio, void *buf, size_t count) { // TODO: add support here to write a stream. roar_err_set(ROAR_ERROR_NOSYS); return -1; } static roar_off_t __v_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } static int __v_sync (struct roar_vio_calls * vio) { // TODO: add support here to flush the mapping of this stream and stuff. roar_err_set(ROAR_ERROR_NOSYS); return -1; } static int __v_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } static int __v_close (struct roar_vio_calls * vio) { // TODO: add support here to terminate the stream and write KICK command and sttuff. __stream_unref(vio->inst); roar_vio_clear_calls(vio); return 0; } static inline void __stream_setup_vio(struct codecfilter_uniraum_inst_stream * self) { struct roar_vio_calls * vio = &(self->ss->vio); roar_vio_clear_calls(vio); vio->inst = self; vio->read = __v_read; vio->write = __v_write; vio->lseek = __v_lseek; vio->sync = __v_sync; vio->ctl = __v_ctl; vio->close = __v_close; __stream_ref(self); } static inline void __stream_pushdata(struct codecfilter_uniraum_inst_stream * self) { uniraum_req_t * req = NULL; uniraum_data_t * data; int queue_filled; ROAR_DBG("__stream_pushdata(self=%p) = ?", self); do { ROAR_DBG("__stream_pushdata(self=%p) = ?", self); do { ROAR_DBG("__stream_pushdata(self=%p): self->uniraummapping=%p", self, self->uniraummapping); data = uniraum_mapping_dataout(self->uniraummapping); queue_filled = data != NULL; ROAR_DBG("__stream_pushdata(self=%p): queue_filled=%i", self, queue_filled); if ( queue_filled ) { if ( roar_buffer_moveintoqueue(&(self->dataqueue), &data) == -1 ) { ROAR_ERR("__stream_pushdata(self=%p): lost data (can not push into queue): %s", self, roar_errorstring); uniraum_data_unref(data); queue_filled = 0; } } } while (queue_filled); req = uniraum_stream_reqout(self->uniraumstream); ROAR_DBG("__stream_pushdata(self=%p): req=%p", self, req); if ( req != NULL ) { if ( uniraum_reqget_type(req) == ROAR_CMD_ADD_DATA ) { ROAR_DBG("__stream_pushdata(self=%p): self->uniraummapping=%p, req=%p is data.", self, self->uniraummapping, req); if ( uniraum_mapping_reqin(self->uniraummapping, req) == -1 ) { ROAR_ERR("__stream_pushdata(self=%p): Can not push data into mapping. Bad.", self); } } uniraum_requnref(req); } } while (req != NULL); } static inline int __handle_meta_data(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int stream) { struct codecfilter_uniraum_inst_stream * streamobj; int server_stream = -1; const char * key; const char * value; int mode; if ( stream == -1 ) { server_stream = ROAR_STREAM(self->ss)->id; } else { streamobj = __stream_get(self, stream); if ( streamobj == NULL ) return -1; server_stream = ROAR_STREAM(streamobj->ss)->id; __stream_unref(streamobj); } if ( uniraum_reqget_meta(in, &key, &value, &mode) == -1 ) { roar_err_set(uniraum_error(self->file)); return -1; } switch (mode) { case ROAR_META_MODE_SET: return stream_meta_set(server_stream, roar_meta_inttype(key), key, value); break; case ROAR_META_MODE_ADD: return stream_meta_add(server_stream, roar_meta_inttype(key), key, value); break; case ROAR_META_MODE_CLEAR: return stream_meta_clear(server_stream); break; case ROAR_META_MODE_FINALIZE: return stream_meta_finalize(server_stream); break; case ROAR_META_MODE_DELETE: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } roar_err_set(ROAR_ERROR_BADRQC); return -1; } static inline int __handle_req_global(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int type) { ROAR_DBG("__handle_req_global(self=%p, in=%p, type=%i) = ?", self, in, type); switch (type) { case ROAR_CMD_NOOP: case ROAR_CMD_CAPS: case ROAR_CMD_RAUM_SEEKTABLE: // NOOPs. return 0; break; case ROAR_CMD_QUIT: self->got_eof = 1; ROAR_DBG("__handle_req_global(self=%p, in=%p, type=%i) = 0 // EOF mark", self, in, type); return 0; break; case ROAR_CMD_SET_META: return __handle_meta_data(self, in, -1); break; default: ROAR_DBG("__handle_req_global(self=%p, in=%p, type=%i) = 0 // error=NSTYPE", self, in, type); roar_err_set(ROAR_ERROR_NSTYPE); return -1; break; } } static inline void __handle_req_stream_update_codec(struct roar_audio_info * info) { switch (info->codec) { case ROAR_CODEC_RAUM_VORBIS: info->codec = ROAR_CODEC_OGG_VORBIS; break; case ROAR_CODEC_RAUM_FLAC: break; } } static inline int __handle_req_stream(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int type, int stream) { struct codecfilter_uniraum_inst_stream * streamobj; struct roar_audio_info info; int stream_dir = -1; int ret = -1; int err; ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i) = ?", self, in, type, stream); if ( type == ROAR_CMD_NEW_STREAM ) { streamobj = __stream_new(self, stream); if ( streamobj == NULL ) return -1; streamobj->uniraumstream = uniraum_stream_new(in); ret = streamobj->uniraumstream == NULL ? -1 : 0; } else { streamobj = __stream_get(self, stream); if ( streamobj == NULL ) return -1; ret = uniraum_stream_reqin(streamobj->uniraumstream, in); ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i): ret=%i", self, in, type, stream, ret); } if ( ret == -1 ) { err = roar_error; __stream_unref(streamobj); roar_err_set(err); ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i) = -1 // error=%s", self, in, type, stream, roar_errorstring); return -1; } switch (type) { case ROAR_CMD_RAUM_SEEKTABLE: case ROAR_CMD_ADD_DATA: case ROAR_CMD_KICK: // NOOPs. ret = 0; break; case ROAR_CMD_SET_META: ret = __handle_meta_data(self, in, stream); break; case ROAR_CMD_EXEC_STREAM: self->is_execed = stream; ret = 0; break; case ROAR_CMD_NEW_STREAM: stream_dir = uniraum_stream_get_dir(streamobj->uniraumstream); info = ROAR_STREAM(streamobj->ss)->info = *uniraum_stream_get_auinfo(streamobj->uniraumstream); __handle_req_stream_update_codec(&(ROAR_STREAM(streamobj->ss)->info)); ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i): stream_dir=%i, codec=%s", self, in, type, stream, stream_dir, roar_codec2str(ROAR_STREAM(streamobj->ss)->info.codec)); streamobj->ss->codec_orgi = ROAR_STREAM(streamobj->ss)->info.codec; streams_set_dir(ROAR_STREAM(streamobj->ss)->id, stream_dir, 1); streams_set_fh(ROAR_STREAM(streamobj->ss)->id, -2); streamobj->uniraummapping = uniraum_mapping_new(stream, UNIRAUM_IN, ROAR_VIO_DFT_RAW, &info); break; case ROAR_CMD_SET_VOL: case ROAR_CMD_SET_STREAM_PARA: default: roar_err_set(ROAR_ERROR_NSTYPE); ret = -1; break; } err = roar_error; __stream_pushdata(streamobj); __stream_unref(streamobj); roar_err_set(err); ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i) = %i // error=%s", self, in, type, stream, ret, roar_errorstring); return ret; } static inline int __handle_req(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int type, int stream) { ROAR_DBG("__handle_req(self=%p, in=%p, type=%i, stream=%i) = ?", self, in, type, stream); if ( stream == -1 ) { return __handle_req_global(self, in, type); } else { return __handle_req_stream(self, in, type, stream); } } static inline int __read_more_data_execed(struct codecfilter_uniraum_inst * self) { /* ssize_t uniraum_read_execed (uniraum_file_t * state, void * buf, size_t len); uniraum_req_t * uniraum_reqdata(int stream, uniraum_pos_t pos, const void * data, size_t len); uniraum_req_t * uniraum_reqend_stream(int stream, uniraum_pos_t pos); */ uniraum_req_t * data = NULL; char buf[1024]; ssize_t ret; ROAR_DBG("__read_more_data_execed(self=%p) = ?", self); ret = uniraum_read_execed(self->file, buf, sizeof(buf)); if ( ret < 0 ) { ROAR_DBG("__read_more_data_execed(self=%p) = -1 // EOF?", self); self->got_eof = 1; roar_err_set(uniraum_error(self->file)); return -1; } else if ( ret == 0 ) { self->got_eof = 1; } else { data = uniraum_reqdata(self->is_execed, 0, buf, ret); } if ( data == NULL ) { ROAR_DBG("__read_more_data_execed(self=%p) = -1", self); roar_err_set(uniraum_error(self->file)); return -1; } __handle_req_stream(self, data, uniraum_reqget_type(data), self->is_execed); uniraum_requnref(data); ROAR_DBG("__read_more_data_execed(self=%p) = 0", self); return 0; } static inline int __read_more_data(struct codecfilter_uniraum_inst * self, int stream) { uniraum_req_t * in; int instream; int intype; int err; ROAR_DBG("__read_more_data(self=%p, stream=%i) = ?", self, stream); if ( self->got_eof ) { roar_err_set(ROAR_ERROR_NONE); return -1; } else if ( self->is_execed != -1 ) { if ( self->is_execed == stream ) { __read_more_data_execed(self); ROAR_DBG("__read_more_data(self=%p, stream=%i) = 0", self, stream); return 0; } else { roar_err_set(ROAR_ERROR_BADSTATE); return -1; } } ROAR_DBG("__read_more_data(self=%p, stream=%i) = ?", self, stream); do { in = uniraum_reqin(self->file); if ( in == NULL ) { err = uniraum_error(self->file); if ( err == ROAR_ERROR_AGAIN ) { if ( uniraum_read(self->file) == -1 ) { roar_err_set(uniraum_error(self->file)); ROAR_DBG("__read_more_data(self=%p, stream=%i): Can not read input data (EOF?): %s", self, stream, roar_errorstring); self->got_eof = 1; return -1; } in = uniraum_reqin(self->file); if ( in == NULL ) { roar_err_set(uniraum_error(self->file)); return -1; } } else { roar_err_set(err); return -1; } } intype = uniraum_reqget_type(in); instream = uniraum_reqget_stream(in); __handle_req(self, in, intype, instream); uniraum_requnref(in); } while ( self->is_execed == -1 && !self->got_eof && ((stream != -1 && stream != instream) || (stream == -1 && intype != ROAR_CMD_ADD_DATA)) ); ROAR_DBG("__read_more_data(self=%p, stream=%i) = 0", self, stream); return 0; } static ssize_t __s_read (struct roar_vio_calls * vio, void *buf, size_t count) { ROAR_DBG("__s_read(vio=%p, buf=%p, count=?) = ?", vio, buf); return stream_vio_s_read(((struct codecfilter_uniraum_inst*)vio->inst)->ss, buf, count); } static ssize_t __s_write (struct roar_vio_calls * vio, void *buf, size_t count) { return stream_vio_s_write(((struct codecfilter_uniraum_inst*)vio->inst)->ss, buf, count); } static roar_off_t __s_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } static int __s_sync (struct roar_vio_calls * vio) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } static int __s_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { return stream_vio_s_ctl(((struct codecfilter_uniraum_inst*)vio->inst)->ss, cmd, data); } static int __s_close (struct roar_vio_calls * vio) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } static inline void __init_s_vio(struct codecfilter_uniraum_inst * self) { roar_vio_clear_calls(&(self->vio)); self->vio.inst = self; self->vio.read = __s_read; self->vio.write = __s_write; self->vio.lseek = __s_lseek; self->vio.sync = __s_sync; self->vio.ctl = __s_ctl; self->vio.close = __s_close; } static inline int __open_file(struct codecfilter_uniraum_inst * self) { int dir; int flags; ROAR_DBG("__open_file(self=%p) = ?", self); if ( self->file != NULL ) { ROAR_DBG("__open_file(self=%p) = -1 // error=ALREADY", self); roar_err_set(ROAR_ERROR_ALREADY); return -1; } dir = streams_get_ssdir(ROAR_STREAM(self->ss)->id); switch (dir) { case STREAM_DIR_IN: flags = O_RDONLY; break; case STREAM_DIR_OUT: flags = O_WRONLY; break; case STREAM_DIR_BIDIR: flags = O_RDWR; break; default: roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } __init_s_vio(self); ROAR_DBG("__open_file(self=%p) = ?", self); self->file = uniraum_openvio(&(self->vio), flags); if ( self->file == NULL ) { roar_err_set(uniraum_error(NULL)); ROAR_DBG("__open_file(self=%p): Can not open uniraum file object: %s", self, roar_errorstring); return -1; } ROAR_DBG("__open_file(self=%p) = 0", self); return 0; } int cf_uniraum_open (CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_uniraum_inst * self; self = roar_mm_malloc(sizeof(struct codecfilter_uniraum_inst)); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct codecfilter_uniraum_inst)); self->refc = 1; self->ss = info; self->file = NULL; self->got_eof = 0; self->is_execed = -1; *inst = self; return 0; } int cf_uniraum_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_uniraum_inst * self = inst; __inst_unref(self); ROAR_DBG("cf_uniraum_close(inst=%p) = 0", inst); return 0; } int cf_uniraum_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_uniraum_inst * self = inst; if ( self->file == NULL ) if ( __open_file(self) == -1 ) return -1; roar_err_set(ROAR_ERROR_BADFH); return -1; } int cf_uniraum_read (CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_uniraum_inst * self = inst; ROAR_DBG("cf_uniraum_read(inst=%p, buf=%p, len=%i) = ?", inst, buf, len); if ( self == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( self->file == NULL ) if ( __open_file(self) == -1 ) return -1; if ( !self->streams ) __read_more_data(self, -1); if ( self->got_eof ) { ROAR_DBG("cf_uniraum_read(inst=%p, buf=%p, len=%i) = 0 // EOF", inst, buf, len); return 0; } else { ROAR_DBG("cf_uniraum_read(inst=%p, buf=%p, len=%i) = -1 // errno=EAGAIN", inst, buf, len); errno = EAGAIN; return -1; } } int cf_uniraum_flush(CODECFILTER_USERDATA_T inst) { struct codecfilter_uniraum_inst * self = inst; int r = uniraum_write(self->file); if ( r == -1 ) roar_err_set(uniraum_error(self->file)); return r; } int cf_uniraum_ctl (CODECFILTER_USERDATA_T inst, int cmd, void * data) { struct codecfilter_uniraum_inst * self = inst; int_least32_t type = cmd & ROAR_STREAM_CTL_TYPEMASK; cmd -= type; ROAR_DBG("cf_uniraum_ctl(*): cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); switch (cmd) { case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_META_UPDATE): if ( type != ROAR_STREAM_CTL_TYPE_VOID ) return -1; roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; default: ROAR_DBG("cf_uniraum_ctl(*): Unknown command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } } #endif //ll roaraudio-1.0beta11/roard/codecfilter_vorbis.c0000644000175000017500000004103112264733663017614 0ustar phiphi//codecfilter_vorbis.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #define ROAR_REQUIRE_LIBVORBISFILE #include "roard.h" #ifdef ROAR_HAVE_LIBVORBISFILE #define FIFAC ((float)((uint64_t)1<<(ROAR_VORBIS_BITS-1))) int _g_cf_vorbis_vfvio_return_err (void) { return -1; } ov_callbacks _g_cf_vorbis_vfvio = { .read_func = cf_vorbis_vfvio_read, .seek_func = (int (*)(void *, ogg_int64_t, int )) _g_cf_vorbis_vfvio_return_err, .close_func = (int (*)(void * )) _g_cf_vorbis_vfvio_return_err, .tell_func = (long (*)(void * )) _g_cf_vorbis_vfvio_return_err }; size_t cf_vorbis_vfvio_read (void *ptr, size_t size, size_t nmemb, void *datasource) { ssize_t r; r = stream_vio_s_read(ROAR_STREAM_SERVER(datasource), ptr, size*nmemb); ROAR_DBG("cf_vorbis_vfvio_read(ptr=%p, size=%lu, nmemb=%lu, datasource=%p): r=%i", ptr, (unsigned long int)size, (unsigned long int)nmemb, datasource, r); if ( r == -1 ) { ROAR_DBG("cf_vorbis_vfvio_read(ptr=%p, size=%lu, nmemb=%lu, datasource=%p) = 0 // roar_error=%i(%s)", ptr, (unsigned long int)size, (unsigned long int)nmemb, datasource, roar_error, roar_error2str(roar_error)); return 0; } if ( r > 0 ) { roar_err_clear_all(); } r /= size; ROAR_DBG("cf_vorbis_vfvio_read(ptr=%p, size=%lu, nmemb=%lu, datasource=%p) = %i", ptr, (unsigned long int)size, (unsigned long int)nmemb, datasource, r); return r; } int cf_vorbis_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_vorbis_inst * self = roar_mm_malloc(sizeof(struct codecfilter_vorbis_inst)); struct roar_stream * s = ROAR_STREAM(info); (void)codec, (void)filter; if ( self == NULL ) return -1; self->current_section = -1; self->last_section = -1; self->opened = 0; self->got_it_running = 0; self->stream = info; // self->outlen = ROAR_OUTPUT_BUFFER_SAMPLES * s->info.channels * s->info.bits / 8; // optimal size #ifdef ROAR_HAVE_LIBVORBISENC self->encoding = 0; self->encoder.v_base_quality = 0.3; self->encoder.srn = -1; #endif ROAR_DBG("cf_vorbis_open(*): info->id=%i", ROAR_STREAM(info)->id); *inst = (CODECFILTER_USERDATA_T) self; #if ROAR_CODEC_DEFAULT == ROAR_CODEC_PCM_S_LE self->bigendianp = 0; s->info.codec = ROAR_CODEC_DEFAULT; #else self->bigendianp = 1; s->info.codec = ROAR_CODEC_PCM_S_BE; // force because ROAR_CODEC_DEFAULT can be something non-BE, too. #endif s->info.bits = 16; if ( s->dir == ROAR_DIR_PLAY ) { return 0; } else if ( s->dir == ROAR_DIR_MONITOR || s->dir == ROAR_DIR_OUTPUT ) { #ifdef ROAR_HAVE_LIBVORBISENC // set up the encoder here // this is delayed to the write function /* if ( cf_vorbis_encode_start(self) == -1 ) { roar_mm_free(self); return -1; } */ s->info.bits = ROAR_VORBIS_BITS; #else roar_mm_free(self); return -1; #endif } else { roar_mm_free(self); return -1; } return 0; } int cf_vorbis_close(CODECFILTER_USERDATA_T inst) { struct codecfilter_vorbis_inst * self = (struct codecfilter_vorbis_inst *) inst; if ( self == NULL ) return -1; if ( self->got_it_running ) ov_clear(&(self->vf)); #ifdef ROAR_HAVE_LIBVORBISENC if ( self->encoding ) { cf_vorbis_encode_end(self); } #endif roar_mm_free(self); return 0; } int cf_vorbis_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { #ifdef ROAR_HAVE_LIBVORBISENC struct codecfilter_vorbis_inst * self = (struct codecfilter_vorbis_inst *) inst; struct roar_stream * s = ROAR_STREAM(self->stream); ogg_packet header; ogg_packet header_comm; ogg_packet header_code; float ** encbuf; int i, c; int chans; int end; int sid; void * prethrubuf; #if ROAR_VORBIS_BITS == 8 int8_t * data = (int8_t *) buf; #elif ROAR_VORBIS_BITS == 16 int16_t * data = (int16_t *) buf; #elif ROAR_VORBIS_BITS == 32 int32_t * data = (int32_t *) buf; #else #error value of ROAR_VORBIS_BITS not supported #endif if ( ! self->opened ) { if ( !self->encoding ) { if ( cf_vorbis_encode_start(self) == -1 ) { return -1; } } sid = ROAR_STREAM(self->stream)->id; vorbis_analysis_headerout(&(self->encoder.vd), &(self->encoder.vc), &header, &header_comm, &header_code); ogg_stream_packetin(&(self->encoder.os), &header); ogg_stream_packetin(&(self->encoder.os), &header_comm); ogg_stream_packetin(&(self->encoder.os), &header_code); stream_prethru_destroy(sid); while (ogg_stream_flush(&(self->encoder.os), &(self->encoder.og))) { if ( stream_vio_s_write(self->stream, self->encoder.og.header, self->encoder.og.header_len) != self->encoder.og.header_len || stream_vio_s_write(self->stream, self->encoder.og.body, self->encoder.og.body_len ) != self->encoder.og.body_len ) { roar_mm_free(self); // TODO: do we need addional cleanup? return -1; } // we ignore errors at the moment... if ( stream_prethru_add_data(sid, &prethrubuf, self->encoder.og.header_len + self->encoder.og.body_len) != -1 ) { memcpy(prethrubuf, self->encoder.og.header, self->encoder.og.header_len); memcpy(prethrubuf + self->encoder.og.header_len, self->encoder.og.body, self->encoder.og.body_len ); } } self->opened = 1; } else { encbuf = vorbis_analysis_buffer(&(self->encoder.vd), len /* TODO: need to lookup the menaing of this */); chans = s->info.channels; end = len*8/(ROAR_VORBIS_BITS*chans); if ( chans == 1 ) { // use optimized code for (i = 0; i < end; i++) encbuf[0][i] = data[i]/FIFAC; } else if ( chans == 2 ) { // use optimized code for (i = 0; i < end; i++) { encbuf[0][i] = data[2*i ]/FIFAC; encbuf[1][i] = data[2*i+1]/FIFAC; } } else { // use generic multi channel code for (i = 0; i < end; i++) { for (c = 0; c < chans; c++) { encbuf[c][i] = data[chans*i+c]/FIFAC; } } } vorbis_analysis_wrote(&(self->encoder.vd), i); if ( cf_vorbis_encode_flushout(self) == -1 ) return -1; } return len; // we assume every thing was written (at least into our dsp anaylises buffer #else roar_err_set(ROAR_ERROR_NOSYS); roar_err_to_errno(); return -1; #endif } int cf_vorbis_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_vorbis_inst * self = (struct codecfilter_vorbis_inst *) inst; long r; long todo = len; long done = 0; int ret; ROAR_DBG("cf_vorbis_read(inst=%p, buf=%p, len=%i) = ?", inst, buf, len); self->opened++; if ( self->opened == 16 ) { ROAR_DBG("cf_vorbis_read(*): opening..."); if ( (ret = ov_open_callbacks((void*)self->stream, &(self->vf), NULL, 0, _g_cf_vorbis_vfvio)) < 0 ) { ROAR_DBG("cf_vorbis_read(*): ret=%i", ret); ROAR_DBG("cf_vorbis_read(*) = 0"); return 0; } ROAR_DBG("cf_vorbis_read(*) = -1 // errno=EAGAIN"); roar_err_set(ROAR_ERROR_AGAIN); roar_err_to_errno(); return -1; } if ( self->opened < 16 ) { ROAR_DBG("cf_vorbis_read(*) = -1 // errno=EAGAIN"); roar_err_set(ROAR_ERROR_AGAIN); roar_err_to_errno(); return -1; } self->got_it_running = 1; while (todo) { r = ov_read(&(self->vf), buf+done, todo, self->bigendianp, 2, 1, &(self->current_section)); ROAR_DBG("cf_vorbis_read(*): r=%li", r); if ( r == OV_HOLE ) { ROAR_DBG("cf_vorbis_read(*): Hole in stream"); } else if ( r < 1 ) { break; } else { if ( self->last_section != self->current_section ) if ( cf_vorbis_update_stream(self) == -1 ) return 0; self->last_section = self->current_section; todo -= r; done += r; } } ROAR_DBG("ov_read(*) = %li", (long int)done); if ( done == 0 ) { // do some EOF handling... return 0; } else { return len; } } int cf_vorbis_update_stream (struct codecfilter_vorbis_inst * self) { #ifdef ROAR_SUPPORT_META vorbis_info *vi = ov_info(&(self->vf), -1); char **ptr = ov_comment(&(self->vf), -1)->user_comments; char key[ROAR_META_MAX_NAMELEN] = {0}, value[LIBROAR_BUFFER_MSGDATA] = {0}; struct roar_stream * s = ROAR_STREAM(self->stream); struct roar_stream_rpg rpg; int type; int j, h = 0; float rpg_track = 0, rpg_album = 0, rpg_final; int meta_ok; s->info.channels = vi->channels; s->info.rate = vi->rate; s->info.bits = 16; #if ROAR_CODEC_DEFAULT == ROAR_CODEC_PCM_S_LE s->info.codec = ROAR_CODEC_DEFAULT; #else s->info.codec = ROAR_CODEC_PCM_S_BE; #endif stream_meta_clear(s->id); while(*ptr){ meta_ok = 1; for (j = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) { if ( j == ROAR_META_MAX_NAMELEN ) { ROAR_ERR("cf_vorbis_update_stream(*): invalid meta data on stream %i: meta data key too long", s->id); meta_ok = 0; j = 0; break; } key[j] = (*ptr)[j]; } key[j] = 0; if ( meta_ok ) { for (j++, h = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) { if ( h == LIBROAR_BUFFER_MSGDATA ) { ROAR_ERR("update_stream(*): invalid meta data on stream %i: meta data value for key '%s' too long", s->id, key); meta_ok = 0; h = 0; break; } value[h++] = (*ptr)[j]; } value[h] = 0; } if ( meta_ok ) { type = roar_meta_inttype(key); if ( type != -1 ) stream_meta_set(s->id, type, "", value); ROAR_DBG("cf_vorbis_update_stream(*): Meta %-16s: %s", key, value); if ( strcmp(key, "REPLAYGAIN_TRACK_PEAK") == 0 ) { rpg_track = 1/atof(value); /* } else if ( strcmp(key, "REPLAYGAIN_TRACK_GAIN") == 0 ) { rpg_track = powf(10, atof(value)/20); */ } else if ( strcmp(key, "REPLAYGAIN_ALBUM_PEAK") == 0 ) { rpg_album = 1/atof(value); /* } else if ( strcmp(key, "REPLAYGAIN_ALBUM_GAIN") == 0 ) { rpg_album = powf(10, atof(value)/20); */ } } ptr++; } if ( streams_get_rpg(ROAR_STREAM(self->stream)->id, &rpg) != -1 ) { rpg_final = 0; switch (rpg.mode) { case ROAR_RPGMODE_NONE: rpg_final = 0.; break; case ROAR_RPGMODE_USER: rpg_final = -1.; break; case ROAR_RPGMODE_ALBUM: rpg_final = rpg_album; break; case ROAR_RPGMODE_TRACK: rpg_final = rpg_track; break; case ROAR_RPGMODE_ALBUMTRACK: rpg_final = rpg_album ? rpg_album : rpg_track; break; case ROAR_RPGMODE_TRACKALBUM: rpg_final = rpg_track ? rpg_track : rpg_album; break; } if ( rpg_final > 0 ) { self->stream->mixer.rpg_div = 2718; self->stream->mixer.rpg_mul = (float)rpg_final*2718; } else if ( !rpg_final ) { self->stream->mixer.rpg_div = 1; self->stream->mixer.rpg_mul = 1; } } stream_meta_finalize(s->id); #endif //printf("RPG: mul=%i, div=%i\n", self->stream->mixer.rpg_mul, self->stream->mixer.rpg_div); return 0; } int cf_vorbis_encode_start (struct codecfilter_vorbis_inst * self) { #ifdef ROAR_HAVE_LIBVORBISENC int srn = self->encoder.srn; // this value is allrady inited... #ifdef ROAR_SUPPORT_META int len = 0; int i; int types[ROAR_META_MAX_PER_STREAM]; #endif int sid = ROAR_STREAM(self->stream)->id; float v_base_quality = self->encoder.v_base_quality; char val[LIBROAR_BUFFER_MSGDATA]; val[LIBROAR_BUFFER_MSGDATA-1] = 0; memset(&(self->encoder), 0, sizeof(self->encoder)); self->encoding = 1; self->encoder.srn = srn + 1; self->encoder.v_base_quality = v_base_quality; vorbis_info_init(&(self->encoder.vi)); vorbis_comment_init(&(self->encoder.vc)); vorbis_comment_add_tag(&(self->encoder.vc), "SERVER", "RoarAudio"); vorbis_comment_add_tag(&(self->encoder.vc), "ENCODER", "RoarAudio Vorbis codecfilter"); #ifdef ROAR_SUPPORT_META if ( (len = stream_meta_list(sid, types, ROAR_META_MAX_PER_STREAM)) != -1 ) { for (i = 0; i < len; i++) { //int stream_meta_get (int id, int type, char * name, char * val, size_t len); if ( stream_meta_get(sid, types[i], NULL, val, LIBROAR_BUFFER_MSGDATA-1) == 0 ) vorbis_comment_add_tag(&(self->encoder.vc), (char * /* remove this later, it has been fixed upstream */)roar_meta_strtype(types[i]), val); } } #endif ROAR_DBG("cf_vorbis_encode_start(*): q=%f", v_base_quality); if( vorbis_encode_init_vbr(&(self->encoder.vi), (long) ROAR_STREAM(self->stream)->info.channels, (long) ROAR_STREAM(self->stream)->info.rate, v_base_quality) != 0 ) { ROAR_ERR("cf_vorbis_encode_start(*): Can not vorbis_encode_init_vbr(*)!"); vorbis_info_clear(&(self->encoder.vi)); // TODO: do we need to free vc also? return -1; } vorbis_analysis_init(&(self->encoder.vd), &(self->encoder.vi)); vorbis_block_init(&(self->encoder.vd), &(self->encoder.vb)); ROAR_DBG("cf_vorbis_encode_start(*): srn=%i", self->encoder.srn); // "RA"<<16 + PID<<8 + Stream ID ogg_stream_init(&(self->encoder.os), (((0x5241 + self->encoder.srn) & 0xffff)<<16) + ( (getpid() & 0x00ff)<< 8) + ( sid & 0x00ff)); return 0; #else return -1; #endif } int cf_vorbis_encode_end (struct codecfilter_vorbis_inst * self) { #ifdef ROAR_HAVE_LIBVORBISENC if ( self->encoding ) { // try to flush up to an EOS page... vorbis_analysis_buffer(&(self->encoder.vd), 2*ROAR_MAX_CHANNELS); vorbis_analysis_wrote(&(self->encoder.vd), 0); cf_vorbis_encode_flushout(self); // clean up... ogg_stream_clear(&(self->encoder.os)); vorbis_block_clear(&(self->encoder.vb)); vorbis_dsp_clear(&(self->encoder.vd)); vorbis_info_clear(&(self->encoder.vi)); self->opened = 0; } return 0; #else return -1; #endif } int cf_vorbis_encode_flushout(struct codecfilter_vorbis_inst * self) { #ifdef ROAR_HAVE_LIBVORBISENC while ( vorbis_analysis_blockout(&(self->encoder.vd), &(self->encoder.vb)) == 1 ) { vorbis_analysis(&(self->encoder.vb), &(self->encoder.op)); vorbis_bitrate_addblock(&(self->encoder.vb)); while ( vorbis_bitrate_flushpacket(&(self->encoder.vd), &(self->encoder.op)) ) { ogg_stream_packetin(&(self->encoder.os), &(self->encoder.op)); while( ogg_stream_pageout(&(self->encoder.os), &(self->encoder.og)) ) { if ( stream_vio_s_write(self->stream, self->encoder.og.header, self->encoder.og.header_len) == -1 || stream_vio_s_write(self->stream, self->encoder.og.body, self->encoder.og.body_len ) == -1 ) { return -1; } } } } return 0; #else return -1; #endif } int cf_vorbis_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data) { struct codecfilter_vorbis_inst * self = (struct codecfilter_vorbis_inst *) inst; int_least32_t type = cmd & ROAR_STREAM_CTL_TYPEMASK; cmd -= type; switch (cmd) { case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_META_UPDATE): if ( type != ROAR_STREAM_CTL_TYPE_VOID ) return -1; ROAR_DBG("cf_vorbis_ctl(*): stoping stream..."); if ( cf_vorbis_encode_end(self) == -1 ) return -1; ROAR_DBG("cf_vorbis_ctl(*): restarting stream..."); if ( cf_vorbis_encode_start(self) == -1 ) return -1; return 0; break; case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_SET_Q): if ( type != ROAR_STREAM_CTL_TYPE_FLOAT ) return -1; ROAR_DBG("cf_vorbis_ctl(*): setting quality to q=%f", *(float*)data); self->encoder.v_base_quality = *(float*)data / 10; if ( self->encoding ) { ROAR_DBG("cf_vorbis_ctl(*): we are allready encoding, restart..."); ROAR_DBG("cf_vorbis_ctl(*): stoping stream..."); if ( cf_vorbis_encode_end(self) == -1 ) return -1; ROAR_DBG("cf_vorbis_ctl(*): restarting stream..."); if ( cf_vorbis_encode_start(self) == -1 ) return -1; } return 0; break; default: ROAR_DBG("cf_vorbis_ctl(*): Unknown command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); return -1; } return -1; } #endif //ll roaraudio-1.0beta11/roard/codecfilter_wave.c0000644000175000017500000001653712264733664017270 0ustar phiphi//codecfilter_wave.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_CF_WAVE int cf_wave_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct codecfilter_wave_inst * self = roar_mm_malloc(sizeof(struct codecfilter_wave_inst)); struct roar_stream * s = ROAR_STREAM(info); if ( !self ) return -1; self->stream = info; self->vstream = NULL; self->opened = 0; *inst = (CODECFILTER_USERDATA_T) self; memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); return 0; } int cf_wave_close(CODECFILTER_USERDATA_T inst) { // struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst; if ( !inst ) return -1; roar_mm_free(inst); return 0; } int cf_wave_read(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst; int r = -1; char tbuf[44]; struct roar_stream * ps = ROAR_STREAM(self->stream); struct roar_stream * s; struct roar_audio_info info; uint16_t tmp16; uint32_t tmp32; int codec = -1; int vid, fh; if ( self->opened ) { return stream_vio_s_read(self->stream, buf, len); } else { if (stream_vio_s_read(self->stream, tbuf, 44) != 44) { return -1; } // test the header, is this really a RIFF WAVE stream? if ( strncmp(tbuf, "RIFF", 4) != 0 ) return -1; if ( strncmp(tbuf+8, "WAVEfmt ", 8) != 0 ) return -1; if ( strncmp(tbuf+36, "data", 4) != 0 ) return -1; // TODO: write better code here! if ( (fh = streams_get_fh(ps->id)) == -1 ) { return -1; } if ( (vid = streams_new_virtual(ps->id, &(self->vstream))) == -1 ) { return -1; } ROAR_DBG("cf_wave_read(*): self->vstream=%p", self->vstream); s = ROAR_STREAM(self->vstream); memcpy(&tmp32, tbuf+24, 4); s->info.rate = ROAR_LE2HOST32(tmp32); memcpy(&tmp16, tbuf+22, 2); s->info.channels = ROAR_LE2HOST16(tmp16); memcpy(&tmp16, tbuf+34, 2); s->info.bits = ROAR_LE2HOST16(tmp16); memcpy(&tmp16, tbuf+20, 2); switch (ROAR_LE2HOST16(tmp16)) { case ROAR_RIFF_WAVE_CID_PCM: if ( s->info.bits == 8 ) { codec = ROAR_CODEC_PCM_U_LE; } else { codec = ROAR_CODEC_PCM_S_LE; } break; case ROAR_RIFF_WAVE_CID_ALAW: codec = ROAR_CODEC_ALAW; break; case ROAR_RIFF_WAVE_CID_MULAW: codec = ROAR_CODEC_MULAW; break; case ROAR_RIFF_WAVE_CID_RSOUND: memcpy(&tmp16, tbuf+42, 2); switch (ROAR_LE2HOST16(tmp16)) { case ROAR_RIFF_WAVE_RSID_S16_LE: s->info.bits = 16; codec = ROAR_CODEC_PCM_S_LE; break; case ROAR_RIFF_WAVE_RSID_S16_BE: s->info.bits = 16; codec = ROAR_CODEC_PCM_U_BE; break; case ROAR_RIFF_WAVE_RSID_U16_LE: s->info.bits = 16; codec = ROAR_CODEC_PCM_U_LE; break; case ROAR_RIFF_WAVE_RSID_U16_BE: s->info.bits = 16; codec = ROAR_CODEC_PCM_U_BE; break; case ROAR_RIFF_WAVE_RSID_S8: s->info.bits = 8; codec = ROAR_CODEC_PCM_S_LE; break; case ROAR_RIFF_WAVE_RSID_U8: s->info.bits = 8; codec = ROAR_CODEC_PCM_U_LE; break; default: return -1; } break; case ROAR_RIFF_WAVE_CID_IEEE_FLOAT: default: return -1; } s->info.codec = codec; self->vstream->codec_orgi = codec; memcpy(&info, &(s->info), sizeof(struct roar_audio_info)); if ( streams_set_fh(vid, fh) == -1 ) { return -1; } /* if ( roar_vio_open_pass(&(self->vstream->vio), &(self->stream->vio)) == -1 ) { return -1; } */ memcpy(&(self->vstream->vio), &(self->stream->vio), sizeof(struct roar_vio_calls)); if ( streams_set_null_io(ps->id) == -1 ) { return -1; } memcpy(&(ps->info), &info, sizeof(struct roar_audio_info)); self->opened = 1; errno = EAGAIN; return -1; } return r; } int cf_wave_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst; struct roar_stream * s = ROAR_STREAM(self->stream); void * header; int32_t tmp32; int16_t tmp16; int16_t bits; int16_t codec; int sid; ROAR_DBG("cf_wave_write(inst=%p, buf=%p, len=%i) = ?", inst, buf, len); ROAR_DBG("cf_wave_write(inst=%p, buf=%p, len=%i): self->opened=%i", inst, buf, len, self->opened); if ( self->opened ) { return stream_vio_s_write(self->stream, buf, len); } else { if ( s->fh == -1 ) { errno = EAGAIN; return -1; } sid = ROAR_STREAM(self->stream)->id; if ( stream_prethru_destroy(sid) == -1 ) { return -1; } if ( stream_prethru_add_data(sid, &header, 44) == -1 ) { return -1; } memcpy(header , "RIFF\367\377\377\177WAVEfmt \020", 17); memcpy(header+36, "data\313\377\377\177", 8); switch (s->info.codec) { case ROAR_CODEC_PCM_S_LE: codec = 0x0001; break; default: ROAR_ERR("cf_wave_write(*) Codec not supported!"); return -1; break; } ROAR_DBG("cf_wave_write(*) Codec supported!"); bits = s->info.bits; memcpy(header+24, &(s->info.rate ), 4); memcpy(header+22, &(s->info.channels), 2); memcpy(header+34, &bits, 2); tmp16 = s->info.channels * bits / 8; memcpy(header+32, &tmp16, 2); tmp32 = tmp16 * s->info.rate; memcpy(header+28, &tmp32, 4); memcpy(header+20, &codec, 2); if ( stream_vio_s_write(self->stream, header, 44) != 44 ) return -1; self->opened = 1; errno = EAGAIN; // return -1; len = stream_vio_s_write(self->stream, buf, len); cf_wave_close(inst); ROAR_STREAM_SERVER(s)->codecfilter = -1; return len; // return stream_vio_s_write(self->stream, buf, len); } return -1; } int cf_wave_ctl(CODECFILTER_USERDATA_T inst, int cmd, void * data) { struct codecfilter_wave_inst * self = (struct codecfilter_wave_inst *) inst; int_least32_t type = cmd & ROAR_STREAM_CTL_TYPEMASK; cmd -= type; ROAR_DBG("cf_wave_ctl(*): command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); switch (cmd) { case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_VIRTUAL_DELETE): streams_delete(ROAR_STREAM(self->stream)->id); return 0; break; default: ROAR_DBG("cf_wave_ctl(*): Unknown command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); return -1; } return -1; } #endif //ll roaraudio-1.0beta11/roard/commands.c0000644000175000017500000001411712264733664015554 0ustar phiphi//commands.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #if !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_MINIMAL) #define _NAME(x) (x) #else #define _NAME(x) ((char*)NULL) #endif struct roar_command g_commands[COMMAND_MAX_COMMANDS] = { {ROAR_CMD_NOOP, _NAME("NOOP"), req_on_noop, ACCLEV_NONE}, {ROAR_CMD_IDENTIFY, _NAME("IDENTIFY"), req_on_identify, ACCLEV_NONE}, {ROAR_CMD_AUTH, _NAME("AUTH"), req_on_auth, ACCLEV_IDENTED}, {ROAR_CMD_WHOAMI, _NAME("WHOAMI"), req_on_whoami, ACCLEV_NONE}, {ROAR_CMD_NEW_STREAM, _NAME("NEW_STREAM"), req_on_new_stream, ACCLEV_USER}, #ifdef ROAR_SUPPORT_META {ROAR_CMD_SET_META, _NAME("SET_META"), req_on_set_meta, ACCLEV_PWRUSER}, {ROAR_CMD_GET_META, _NAME("GET_META"), req_on_get_meta, ACCLEV_GUEST}, {ROAR_CMD_LIST_META, _NAME("LIST_META"), req_on_list_meta, ACCLEV_GUEST}, #endif {ROAR_CMD_EXEC_STREAM, _NAME("EXEC_STREAM"), req_on_exec_stream, ACCLEV_PWRUSER}, {ROAR_CMD_QUIT, _NAME("QUIT"), req_on_quit, ACCLEV_NONE}, {ROAR_CMD_CON_STREAM, _NAME("CON_STREAM"), req_on_con_stream, ACCLEV_PWRUSER}, {ROAR_CMD_PASSFH, _NAME("PASSFH"), req_on_passfh, ACCLEV_PWRUSER}, {ROAR_CMD_GETTIMEOFDAY, _NAME("GETTIMEOFDAY"), req_on_gettimeofday, ACCLEV_NONE}, {ROAR_CMD_SERVER_INFO, _NAME("SERVER_INFO"), req_on_server_info, ACCLEV_NONE}, // allow this early so the client // can decide early if this server // provieds all needed features {ROAR_CMD_SERVER_OINFO, _NAME("SERVER_OINFO"), req_on_server_oinfo, ACCLEV_IDENTED}, // same as above {ROAR_CMD_CAPS, _NAME("CAPS"), req_on_caps, ACCLEV_IDENTED}, // and again the same {ROAR_CMD_GET_STANDBY, _NAME("GET_STANDBY"), req_on_get_standby, ACCLEV_GUEST}, {ROAR_CMD_SET_STANDBY, _NAME("SET_STANDBY"), req_on_set_standby, ACCLEV_PWRUSER}, // should this be set to ACCLEV_ALL? {ROAR_CMD_EXIT, _NAME("EXIT"), req_on_exit, ACCLEV_ALL}, {ROAR_CMD_LIST_CLIENTS, _NAME("LIST_CLIENTS"), req_on_list_clients, ACCLEV_GUEST}, {ROAR_CMD_LIST_STREAMS, _NAME("LIST_STREAMS"), req_on_list_streams, ACCLEV_GUEST}, {ROAR_CMD_GET_CLIENT, _NAME("GET_CLIENT"), req_on_get_client, ACCLEV_GUEST}, {ROAR_CMD_GET_STREAM, _NAME("GET_STREAM"), req_on_get_stream, ACCLEV_GUEST}, {ROAR_CMD_KICK, _NAME("KICK"), req_on_kick, ACCLEV_PWRUSER}, {ROAR_CMD_ATTACH, _NAME("ATTACH"), req_on_attach, ACCLEV_PWRUSER}, {ROAR_CMD_SET_VOL, _NAME("SET_VOL"), req_on_set_vol, ACCLEV_PWRUSER}, {ROAR_CMD_GET_VOL, _NAME("GET_VOL"), req_on_get_vol, ACCLEV_GUEST}, {ROAR_CMD_GET_STREAM_PARA, _NAME("GET_STREAM_PARA"), req_on_get_stream_para, ACCLEV_GUEST}, {ROAR_CMD_SET_STREAM_PARA, _NAME("SET_STREAM_PARA"), req_on_set_stream_para, ACCLEV_PWRUSER}, {ROAR_CMD_ADD_DATA, _NAME("ADD_DATA"), req_on_add_data, ACCLEV_PWRUSER}, {ROAR_CMD_BEEP, _NAME("BEEP"), req_on_beep, ACCLEV_USER}, {ROAR_CMD_WAIT, _NAME("WAIT"), req_on_wait, ACCLEV_USER}, {ROAR_CMD_EOL, _NAME("END OF LIST"), NULL, ACCLEV_NONE} }; int command_get_id_by_cmd (int command) { int i; int cmd; for (i = 0; i < COMMAND_MAX_COMMANDS; i++) { if ( (cmd = g_commands[i].cmd) == ROAR_CMD_EOL ) break; if ( cmd == command ) return i; } return -1; } int command_exec (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { int cmd = command_get_id_by_cmd(mes->cmd); int (*func)(int client, struct roar_message * mes, char ** data, uint32_t flags[2]); #ifdef DEBUG int ret; #endif if ( cmd == -1 ) return -1; // NOTE: This is optimized for speed here, so we do not call clients_get(). // we maybe should do but current just don't. /client/ must be valid anyway. if ( g_commands[cmd].minacclev > g_clients[client]->acclev ) { ROAR_WARN("command_exec(client=%i, mes=%p{.cmd=%i,...}, data=%p, flags=%p) = -1 // client not allowed to use command %s", client, mes, (int)mes->cmd, data, flags, g_commands[cmd].name); return -1; } if ( (func = g_commands[cmd].handler) == NULL ) { ROAR_WARN("command_exec(client=%i, mes=%p{.cmd=%i,...}, data=%p, flags=%p) = -1 // unknown command", client, mes, (int)mes->cmd, data, flags); return -1; } ROAR_DBG("command_exec(*): Execing command %i(%s) via %p", cmd, g_commands[cmd].name, func); #ifdef DEBUG ROAR_DBG("command_exec(client=%i, mes=%p{.cmd=%i,...}, data=%p{%p}, flags=%p): func=%p", client, mes, (int)mes->cmd, data, *data, flags, func); ret = func(client, mes, data, flags); ROAR_DBG("command_exec(client=%i, mes=%p{.cmd=%i,...}, data=%p{%p}, flags=%p) = %i", client, mes, (int)mes->cmd, data, *data, flags, ret); return ret; #else return func(client, mes, data, flags); #endif } int command_get_name (int command, const char ** name) { int cmd = command_get_id_by_cmd(command); if ( cmd == -1 ) { *name = NULL; return -1; } *name = g_commands[cmd].name; return 0; } //ll roaraudio-1.0beta11/roard/container_framework.c0000644000175000017500000002325112264733664020011 0ustar phiphi//container_framework.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #define _DECL() struct cont_fw_child_vio_inst * inst #define _CHECK() if ( vio == NULL ) \ return -1 #define _CINST() if ( (inst = vio->inst) == NULL ) \ return -1 #define _PREP() _CHECK(); \ _CINST() #define _BASIC() _DECL(); \ _PREP() // Parent: int cont_fw_new (struct cont_fw_parent_inst ** inst) { struct cont_fw_parent_inst * self; if ( inst == NULL ) return -1; if ( (self = roar_mm_malloc(sizeof(struct cont_fw_parent_inst))) == NULL ) { *inst = NULL; return -1; } memset(self, 0, sizeof(struct cont_fw_parent_inst)); self->stream.id = -1; self->state = ROAR_STREAMSTATE_INITING; if ( cont_pvio_open(&(self->vio), self) == -1 ) { roar_mm_free(self); return -1; } *inst = self; return 0; } int cont_fw_delete (struct cont_fw_parent_inst * inst) { int i; ROAR_DBG("cont_fw_delete(inst=%p) = ?", inst); if ( inst == NULL ) return -1; ROAR_DBG("cont_fw_delete(inst=%p) = ?", inst); // check if there are streams to close... for (i = 0; i < CONT_FW_MAX_CHILDS; i++) { if ( inst->child[i] != NULL ) { ROAR_DBG("cont_fw_delete(inst=%p) = -1 // there are still open childs", inst); return -1; } } ROAR_DBG("cont_fw_delete(inst=%p) = ?", inst); if ( inst->pcb.close != NULL ) inst->pcb.close(inst); roar_mm_free(inst); ROAR_DBG("cont_fw_delete(inst=%p) = 0", inst); return 0; } int cont_fw_set_uinst(struct cont_fw_parent_inst * inst, void * u_inst) { if ( inst == NULL ) return -1; inst->u_inst = u_inst; return 0; } int cont_fw_get_uinst(struct cont_fw_parent_inst * inst, void ** u_inst) { if ( inst == NULL || u_inst == NULL ) return -1; *u_inst = inst->u_inst; return 0; } // VIO Client: int cont_fw_new_child(struct cont_fw_parent_inst * inst, int id) { struct cont_fw_child_vio_inst * self; struct roar_stream_server * ss; int i; int cid = -1; ROAR_DBG("cont_fw_new_child(inst=%p, id=%i) = ?", inst, id); if ( inst == NULL || id == -1 ) return -1; if ( streams_get(id, &ss) == -1 ) return -1; for (i = 0; i < CONT_FW_MAX_CHILDS; i++) { if ( inst->child[i] == NULL ) { cid = i; break; } } if ( cid == -1 ) return -1; if ( (self = roar_mm_malloc(sizeof(struct cont_fw_child_vio_inst))) == NULL ) return -1; memset(self, 0, sizeof(struct cont_fw_child_vio_inst)); self->parent = inst; self->child = id; self->u_inst = NULL; inst->child[i] = self; if ( inst->pcb.new_child != NULL ) { if ( inst->pcb.new_child(inst, self) == -1 ) { inst->child[i] = NULL; roar_mm_free(self); return -1; } } // no error possible here. cont_fw_init_vio(&(ss->vio), self); // ss->ready = 1; streams_set_fh(id, -2); // update some internal structures ROAR_DBG("cont_fw_new_child(inst=%p, id=%i) = 0", inst, id); return 0; } int cont_fw_init_vio(struct roar_vio_calls * vio, void * inst) { if ( vio == NULL ) return -1; memset(vio, 0, sizeof(struct roar_vio_calls)); vio->flags = ROAR_VIO_FLAGS_NONE; vio->refc = 1; vio->inst = inst; vio->read = cont_fw_read; vio->write = cont_fw_write; vio->sync = cont_fw_sync; vio->close = cont_fw_close; return 0; } ssize_t cont_fw_read (struct roar_vio_calls * vio, void *buf, size_t count) { _BASIC(); if ( inst->parent->ccb.read != NULL ) return inst->parent->ccb.read(inst->parent, inst, buf, count); return -1; } ssize_t cont_fw_write (struct roar_vio_calls * vio, void *buf, size_t count) { _BASIC(); if ( inst->parent->ccb.write != NULL ) return inst->parent->ccb.write(inst->parent, inst, buf, count); return -1; } roar_off_t cont_fw_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence); int cont_fw_sync (struct roar_vio_calls * vio) { _BASIC(); if ( inst->parent->ccb.flush != NULL ) return inst->parent->ccb.flush(inst->parent, inst); return 0; } int cont_fw_close (struct roar_vio_calls * vio) { _DECL(); int r = 0; int i; _PREP(); if ( cont_fw_sync(vio) == -1 ) r = -1; if ( inst->parent->ccb.close != NULL ) if ( inst->parent->ccb.close(inst->parent, inst) == -1 ) r = -1; for (i = 0; i < CONT_FW_MAX_CHILDS; i++) { if ( inst->parent->child[i] == inst ) { inst->parent->child[i] = NULL; } } roar_mm_free(inst); return r; } int cont_fw_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data); // VIO Parent: int cont_pvio_open (struct roar_vio_calls * vio, void * inst) { memset(vio, 0, sizeof(struct roar_vio_calls)); vio->flags = ROAR_VIO_FLAGS_NONE; vio->refc = 1; vio->inst = inst; vio->read = cont_pvio_read; vio->write = cont_pvio_write; vio->lseek = cont_pvio_lseek; vio->sync = cont_pvio_sync; vio->ctl = cont_pvio_ctl; vio->close = cont_pvio_close; return 0; } ssize_t cont_pvio_read (struct roar_vio_calls * vio, void *buf, size_t count) { return stream_vio_s_read(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream, buf, count); } ssize_t cont_pvio_write (struct roar_vio_calls * vio, void *buf, size_t count) { ROAR_DBG("cont_pvio_write(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (unsigned long) count); return stream_vio_s_write(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream, buf, count); } roar_off_t cont_pvio_lseek (struct roar_vio_calls * vio, roar_off_t offset, int whence) { return roar_vio_lseek(&(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream->vio), offset, whence); } int cont_pvio_sync (struct roar_vio_calls * vio) { return roar_vio_sync(&(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream->vio)); } int cont_pvio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { return roar_vio_ctl(&(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream->vio), cmd, data); } int cont_pvio_close (struct roar_vio_calls * vio) { return roar_vio_close(&(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream->vio)); } // CF: int cont_fw_cf_open(CODECFILTER_USERDATA_T * inst, int codec, struct roar_stream_server * info, struct roar_codecfilter * filter) { struct cont_fw_parent_inst * self; CONT_FW_SETUP_TYPE((*setup)); ROAR_DBG("cont_fw_cf_open(*) = ?"); if ( cont_fw_new(&self) == -1 ) return -1; self->stream.codec = codec; self->stream.id = ROAR_STREAM(info)->id; self->stream.stream = info; self->stream.filter = filter; ROAR_DBG("cont_fw_cf_open(*) = ?"); if ( (setup = filter->setup) != NULL ) { if ( setup(self, codec, filter) == -1 ) { cont_fw_delete(self); return -1; } } ROAR_DBG("cont_fw_cf_open(*) = ?"); *inst = self; ROAR_DBG("cont_fw_cf_open(*) = 0"); return 0; } int cont_fw_cf_close(CODECFILTER_USERDATA_T inst) { ROAR_DBG("cont_fw_cf_close(*) = ?"); return cont_fw_delete(inst); } int cont_fw_cf_pause(CODECFILTER_USERDATA_T inst, int newstate); // no direct read or writing... int cont_fw_cf_write(CODECFILTER_USERDATA_T inst, char * buf, int len) { struct cont_fw_parent_inst * self = (void*)inst; ROAR_DBG("cont_fw_cf_write(*) = ?"); if ( self->state == ROAR_STREAMSTATE_INITING ) { if ( self->pcb.open != NULL ) { if ( self->pcb.open(self, self->stream.codec, self->stream.stream, self->stream.filter) == -1 ) { return -1; } } self->state = ROAR_STREAMSTATE_NEW; ROAR_DBG("cont_fw_cf_write(*) = 0"); return 0; } else { ROAR_DBG("cont_fw_cf_write(*) = -1"); return -1; } } int cont_fw_cf_read (CODECFILTER_USERDATA_T inst, char * buf, int len) { ROAR_DBG("cont_fw_cf_read(*) = -1"); return -1; } int cont_fw_cf_flush(CODECFILTER_USERDATA_T inst) { struct cont_fw_parent_inst * self = (void*)inst; ROAR_DBG("cont_fw_cf_flush(*) = ?"); if ( self->pcb.flush != NULL ) return self->pcb.flush(self); return 0; } int cont_fw_cf_delay(CODECFILTER_USERDATA_T inst, uint_least32_t * delay); int cont_fw_cf_ctl (CODECFILTER_USERDATA_T inst, int cmd, void * data) { struct cont_fw_parent_inst * self = (void*)inst; int_least32_t type = cmd & ROAR_STREAM_CTL_TYPEMASK; ROAR_DBG("cont_fw_cf_ctl(*) = ?"); cmd -= type; ROAR_DBG("cont_fw_cf_ctl(*): command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); if ( data == NULL && type != ROAR_STREAM_CTL_TYPE_VOID ) return -1; switch (cmd) { case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_VIRTUAL_DELETE): return 0; break; case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_VIRTUAL_NEW): if ( type != ROAR_STREAM_CTL_TYPE_INT ) return -1; return cont_fw_new_child(self, *(int*)data); break; default: ROAR_DBG("cont_fw_cf_ctl(*): Unknown command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x", cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd)); return -1; } return -1; } //ll roaraudio-1.0beta11/roard/driver.c0000644000175000017500000003102312264733665015242 0ustar phiphi//driver.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" struct roar_driver g_driver[] = { { "null", "null audio driver", NULL, STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, NULL}, #ifdef ROAR_HAVE_ESD { "esd", "EsounD audio driver", "localhost, remote.host.dom", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_esd_open_vio}, #endif { "roar", "RoarAudio driver", "localhost, remote.host.dom", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM|ROAR_SUBSYS_MIDI|ROAR_SUBSYS_LIGHT|ROAR_SUBSYS_COMPLEX, NULL, NULL, driver_roar_open_vio}, #ifndef ROAR_WITHOUT_VIO_DSTR { "dstr", "VIO DSTR driver", "/some/file", STREAM_DIR_OUT, DRV_FLAG_FHSEC, ROAR_SUBSYS_WAVEFORM|ROAR_SUBSYS_MIDI|ROAR_SUBSYS_LIGHT|ROAR_SUBSYS_RAW|ROAR_SUBSYS_COMPLEX, NULL, NULL, driver_dstr_open_vio}, #endif #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) #ifndef ROAR_DEFAULT_OSS_DEV #define ROAR_DEFAULT_OSS_DEV "no default device" #endif { "oss", "Open Sound System", ROAR_DEFAULT_OSS_DEV, STREAM_DIR_BIDIR, DRV_FLAG_FHSEC, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_oss_open}, #endif #ifdef ROAR_HAVE_LIBAO { "ao", "libao audio driver", "DRIVER", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_ao_open_vio}, #endif #ifdef ROAR_HAVE_LIBSHOUT {"shout", "libshout streaming", "http://user:pw@host:port/mount.ogg", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_shout_open_vio}, #endif #ifdef ROAR_HAVE_LIBSNDIO {"sndio", "OpenBSD sndio", "/dev/audio, /tmp/aucat-/default", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM|ROAR_SUBSYS_MIDI, NULL, NULL, driver_sndio_open}, #endif #ifdef ROAR_HAVE_LIBRSOUND {"rsound", "RSound", "servername", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_rsound_open}, #endif #ifdef _DRIVER_PORTAUDIO_CAN_OPERATE {"portaudio", "PortAudio", NULL, STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_portaudio_open}, #endif #ifdef ROAR_HAVE_LIBASOUND {"alsa", "ALSA", "???", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_alsa_open_vio}, #endif #ifdef ROAR_HAVE_LIBWINMM {"wmm", "Win32 MM", "???", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_wmm_open_vio}, #endif #ifndef ROAR_WITHOUT_DCOMP_DMX {"dmx", "DMX512 driver", "/dev/dmx", STREAM_DIR_OUT, DRV_FLAG_FHSEC, ROAR_SUBSYS_LIGHT, NULL, NULL, driver_dmx_open_vio}, #endif #if !defined(ROAR_WITHOUT_DCOMP_PWMLED) && !defined(ROAR_WITHOUT_VIO_DSTR) {"pwmled", "PWM LED driver", "/dev/ttyS0", STREAM_DIR_OUT, DRV_FLAG_FHSEC, ROAR_SUBSYS_LIGHT, NULL, NULL, driver_pwmled_open_vio}, #endif #ifdef ROAR_HAVE_DRIVER_I2CDMX {"i2cdmx", "I^2C DMX Interface driver", "/dev/i2c-1", STREAM_DIR_BIDIR, DRV_FLAG_NONE, ROAR_SUBSYS_LIGHT, NULL, NULL, driver_i2cdmx_open_vio}, #endif #ifdef ROAR_HAVE_DRIVER_SYSCLOCK {"sysclock", "System Clock Clock Source", NULL, STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_sysclock_open_vio}, #endif #ifndef ROAR_WITHOUT_DCOMP_CDRIVER {"cdriver", "RoarAudio Client driver", "driver#device", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_cdriver_open}, #endif #ifdef ROAR_HAVE_LIBPULSE {"pulsesimple", "PulseAudio Simple", "server", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_pulsesimple_open}, #endif #ifdef ROAR_HAVE_LIBJACK #if 0 // this is currently just a driver stub. {"jack", "JACK", "???", STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_jack_open_vio}, #endif #endif #ifdef ROAR_HAVE_LIBARTSC {"artsc", "aRts plain C API", NULL, STREAM_DIR_OUT, DRV_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, NULL, driver_artsc_open_vio}, #endif {NULL, NULL, NULL, STREAM_DIR_NONE, DRV_FLAG_NONE, 0, NULL, NULL, NULL} // end of list }; void print_driverlist (enum output_format format) { int i; char subsys[7] = " "; char mode[5] = " "; switch (format) { case FORMAT_NATIVE: printf(" Driver Mode Flag Subsys - Description (devices)\n"); printf("---------------------------------------------------------------\n"); break; case FORMAT_WIKI: printf("||=Driver =||=Mode =||=Flag =||=Subsys =||=Description =||=Devices =||\n"); break; case FORMAT_CSV: printf("Driver,Mode,Flag,Subsys,Description,Devices\n"); break; default: roar_err_set(ROAR_ERROR_NOTSUP); return; } for (i = 0; g_driver[i].name != NULL; i++) { strncpy(subsys, " ", 6); strncpy(mode, " ", 4); if ( g_driver[i].mode & STREAM_DIR_IN ) mode[0] = 'r'; if ( g_driver[i].mode & STREAM_DIR_OUT ) mode[1] = 'w'; if ( g_driver[i].subsystems & ROAR_SUBSYS_WAVEFORM ) subsys[0] = 'W'; if ( g_driver[i].subsystems & ROAR_SUBSYS_MIDI ) subsys[1] = 'M'; if ( g_driver[i].subsystems & ROAR_SUBSYS_CB ) subsys[2] = 'C'; if ( g_driver[i].subsystems & ROAR_SUBSYS_LIGHT ) subsys[3] = 'L'; if ( g_driver[i].subsystems & ROAR_SUBSYS_RAW ) subsys[4] = 'R'; if ( g_driver[i].subsystems & ROAR_SUBSYS_COMPLEX ) subsys[5] = 'X'; switch (format) { case FORMAT_NATIVE: if ( g_driver[i].devices != NULL ) { printf(" %-12s %4s %c%c%c%c %6s - %s (devices: %s)\n", g_driver[i].name, mode, ' ', /* unused Flag */ g_driver[i].flags & DRV_FLAG_FHSEC ? 's' : ' ', g_driver[i].open != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? 'S' : ' ', g_driver[i].vio_init != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? 'V' : ' ', subsys, g_driver[i].desc, g_driver[i].devices); } else { printf(" %-12s %4s %c%c%c%c %6s - %s\n", g_driver[i].name, mode, ' ', /* unused Flag */ g_driver[i].flags & DRV_FLAG_FHSEC ? 's' : ' ', g_driver[i].open != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? 'S' : ' ', g_driver[i].vio_init != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? 'V' : ' ', subsys, g_driver[i].desc); } break; case FORMAT_WIKI: printf("||=%-12s =|| %s || %s%s%s ||%s ||%s ||%s ||\n", g_driver[i].name, mode[0] == ' ' ? mode+1 : mode, g_driver[i].flags & DRV_FLAG_FHSEC ? "s" : " ", g_driver[i].open != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? "S" : " ", g_driver[i].vio_init != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? "V" : " ", subsys, g_driver[i].desc, g_driver[i].devices == NULL ? "" : g_driver[i].devices); break; case FORMAT_CSV: printf("%s,%s,%s%s%s,%s,%s,%s\n", g_driver[i].name, mode, g_driver[i].flags & DRV_FLAG_FHSEC ? "s" : " ", g_driver[i].open != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? "S" : " ", g_driver[i].vio_init != NULL || (g_driver[i].open == NULL && g_driver[i].vio_init == NULL) ? "V" : " ", subsys, g_driver[i].desc, g_driver[i].devices == NULL ? "" : g_driver[i].devices); break; } } } int driver_openvio(struct roar_vio_calls * calls, int * driver_id, char * driver /* NOTE: this is not part of struct roar_driver's def! */, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { int i; #ifdef ROAR_DRIVER_DEFAULT if ( driver == NULL ) driver = ROAR_DRIVER_DEFAULT; #else if ( driver == NULL ) return -1; #endif #ifdef ROAR_DRIVER_DEVICE if ( device == NULL ) device = ROAR_DRIVER_DEVICE; #endif ROAR_DBG("driver_openvio(*): searching for driver '%s'...", driver); for (i = 0; g_driver[i].name != NULL; i++) { if ( strcmp(g_driver[i].name, driver) == 0 ) { ROAR_DBG("driver_openvio(*): found driver: id = %i", i); *driver_id = i; ROAR_DBG("driver_openvio(*): driver found: %s -> %i", driver, i); if ( g_driver[i].vio_init == NULL ) { if ( g_driver[i].open == NULL ) { // this is the null driver memset(calls, 0, sizeof(struct roar_vio_calls)); calls->flags = ROAR_VIO_FLAGS_NONE; calls->refc = 1; calls->read = roar_vio_null_rw; calls->write = roar_vio_null_rw; return 0; } ROAR_WARN("driver_openvio(*): driver(%s) uses old non-vio interface!", driver); ROAR_ERR("driver_openvio(calls=%p, driver_id={%i}, driver='%s', device='%s', info=%p, fh=%i): not a VIO driver!", calls, i, driver, device, info, fh); return -1; } // if this driver does not support input we need to check if it is used in input mode. if ( !(g_driver[i].mode & STREAM_DIR_IN) ) { if ( sstream == NULL ) return -1; if ( streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_RECSOURCE) ) { if ( streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF) == 1 ) { if ( streams_reset_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_RECSOURCE) == -1 ) return -1; } else { ROAR_WARN("driver_openvio(*): driver(%s) is not abled to record data and autoconf flag is not set.", driver); return -1; } } } ROAR_DBG("driver_openvio(*): Opening VIO driver %s(%i)...", driver, i); return g_driver[i].vio_init(calls, device, info, fh, sstream); } } return -1; } int driver_closevio(struct roar_vio_calls * calls, int driver) { ROAR_DBG("driver_closevio(calls=%p, driver=%i) = ?", calls, driver); if ( driver == -1 ) return -1; if ( g_driver[driver].close ) return g_driver[driver].close((DRIVER_USERDATA_T)calls); if ( calls->close != NULL ) roar_vio_close(calls); return 0; } int driver_set_volume(int stream, struct roar_mixer_settings * mixer) { struct roar_stream_server * ss; if ( (ss = g_streams[stream]) == NULL ) return -1; if ( !streams_get_flag(stream, ROAR_FLAG_HWMIXER) ) return 0; if ( ss->driver_id == -1 ) return -1; return roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_VOLUME, (void*)mixer); } #ifndef ROAR_WITHOUT_DCOMP_CDRIVER int driver_cdriver_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { char * driver; char * delm; int ret; (void)sstream; ROAR_DBG("driver_cdriver_open(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = ?", inst, device, info, fh, sstream); if ( fh != -1 ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } if (device == NULL) { driver = NULL; } else { driver = roar_mm_strdup(device); if ( (delm = strstr(driver, "#")) == NULL ) { device = NULL; } else { *delm = 0; device = strstr(device, "#") + 1; } } ROAR_DBG("driver_cdriver_open(*): CALL roar_cdriver_open(inst=%p, driver='%s', device='%s', info=%p, dir=ROAR_DIR_PLAY)", inst, driver, device, info); ret = roar_cdriver_open(inst, driver, device, info, ROAR_DIR_PLAY); ROAR_DBG("driver_cdriver_open(*): RET %i", ret); if ( driver != NULL ) roar_mm_free(driver); return ret; } #endif int driver_dummy_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { (void)vio; switch (cmd) { case ROAR_VIO_CTL_NONBLOCK: if ( *(const int*)data == ROAR_SOCKET_BLOCK ) return 0; roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } } //ll roaraudio-1.0beta11/roard/driver_alsa.c0000644000175000017500000002713412264733665016252 0ustar phiphi//driver_alsa.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBASOUND #define ALSA_PCM_NEW_HW_PARAMS_API static snd_pcm_format_t driver_alsa_roar_fmt_to_alsa(struct roar_audio_info * info) { snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN; switch (info->codec) { case ROAR_CODEC_PCM_S_LE: switch (info->bits) { case 8: format = SND_PCM_FORMAT_S8; break; case 16: format = SND_PCM_FORMAT_S16_LE; break; case 24: format = SND_PCM_FORMAT_S24_3LE; break; case 32: format = SND_PCM_FORMAT_S32_LE; break; } break; case ROAR_CODEC_PCM_S_BE: switch (info->bits) { case 8: format = SND_PCM_FORMAT_S8; break; case 16: format = SND_PCM_FORMAT_S16_BE; break; case 24: format = SND_PCM_FORMAT_S24_3BE; break; case 32: format = SND_PCM_FORMAT_S32_BE; break; } break; case ROAR_CODEC_PCM_U_LE: switch (info->bits) { case 8: format = SND_PCM_FORMAT_U8; break; case 16: format = SND_PCM_FORMAT_U16_LE; break; case 24: format = SND_PCM_FORMAT_U24_3LE; break; case 32: format = SND_PCM_FORMAT_U32_LE; break; } break; case ROAR_CODEC_PCM_U_BE: switch (info->bits) { case 8: format = SND_PCM_FORMAT_U8; break; case 16: format = SND_PCM_FORMAT_U16_BE; break; case 24: format = SND_PCM_FORMAT_U24_3BE; break; case 32: format = SND_PCM_FORMAT_U32_BE; break; } break; case ROAR_CODEC_ALAW: format = SND_PCM_FORMAT_A_LAW; break; case ROAR_CODEC_MULAW: format = SND_PCM_FORMAT_MU_LAW; break; case ROAR_CODEC_GSM: format = SND_PCM_FORMAT_GSM; break; } return format; } static int driver_alsa_set_params(roar_alsa_t * device) { unsigned int buffer_time = 32000; // 32ms buffer if possible. // *_buffer_time_near() will pick something as close as possible. snd_pcm_uframes_t frames = ROAR_OUTPUT_BUFFER_SAMPLES; int rc; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); if ( snd_pcm_hw_params_malloc(&device->params) < 0 ) return -1; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); if ( snd_pcm_hw_params_any(device->handle, device->params) < 0 ) goto error; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); if ( snd_pcm_hw_params_set_access(device->handle, device->params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0 ) goto error; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); if ( snd_pcm_hw_params_set_format(device->handle, device->params, device->format) < 0) goto error; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); ROAR_DBG("driver_alsa_set_params(device=%p): device->info.channels=%i", device, device->info.channels); if ( snd_pcm_hw_params_set_channels(device->handle, device->params, device->info.channels) < 0 ) goto error; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); if ( snd_pcm_hw_params_set_rate(device->handle, device->params, device->info.rate, 0) < 0 ) goto error; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); if ( snd_pcm_hw_params_set_buffer_time_near(device->handle, device->params, &buffer_time, NULL) < 0 ) goto error; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); if ( snd_pcm_hw_params_set_period_size_near(device->handle, device->params, &frames, NULL) < 0 ) goto error; ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); rc = snd_pcm_hw_params(device->handle, device->params); if (rc < 0) { ROAR_ERR("driver_alsa_open_vio(*): unable to set hw parameters: %s", snd_strerror(rc)); goto error; } ROAR_DBG("driver_alsa_set_params(device=%p) = ?", device); snd_pcm_hw_params_free(device->params); ROAR_DBG("driver_alsa_set_params(device=%p) = 0", device); return 0; error: snd_pcm_hw_params_free(device->params); ROAR_DBG("driver_alsa_set_params(device=%p) = -1", device); return -1; } int driver_alsa_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { roar_alsa_t * interface; char * alsa_dev; int rc; int autoconf; ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = ?", inst, device, info, fh, sstream); if ( fh != -1 ) return -1; if ( (interface = roar_mm_calloc(1, sizeof(roar_alsa_t))) == NULL ) return -1; ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = ?", inst, device, info, fh, sstream); if ( device == NULL ) { alsa_dev = "default"; } else { alsa_dev = device; } ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = ?", inst, device, info, fh, sstream); rc = snd_pcm_open(&(interface->handle), alsa_dev, SND_PCM_STREAM_PLAYBACK, 0); if ( rc < 0 ) { ROAR_ERR("driver_alsa_open_vio(*): Unable to open PCM device: %s", snd_strerror(rc)); roar_mm_free(interface); return -1; } // Setting sample format, yay. interface->format = driver_alsa_roar_fmt_to_alsa(info); ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = ?", inst, device, info, fh, sstream); // We did not find a codec if ( interface->format == SND_PCM_FORMAT_UNKNOWN ) { autoconf = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF); if ( autoconf == -1 ) { ROAR_ERR("driver_alsa_open_vio(*): Could not get autoconf flag."); goto init_error; } if ( autoconf ) { info->bits = 16; #if ROAR_CODEC_DEFAULT == ROAR_CODEC_PCM_S_LE interface->format = SND_PCM_FORMAT_S16_LE; info->codec = ROAR_CODEC_PCM_S_LE; #elif ROAR_CODEC_DEFAULT == ROAR_CODEC_PCM_S_BE interface->format = SND_PCM_FORMAT_S16_BE; info->codec = ROAR_CODEC_PCM_S_BE; #else ROAR_ERR("driver_alsa_open_vio(*): ALSA only support little- or big-endian sample format. Please select -oO codec=pcm_s_le or pcm_s_be"); goto init_error; #endif ROAR_WARN("driver_alsa_open_vio(*): Supplied codec type not available. Using 16 bit sample format."); } else { ROAR_ERR("driver_alsa_open_vio(*): can not set requested codec, set codec manually with -oO codec=."); goto init_error; } } memcpy(&(interface->info), info, sizeof(struct roar_audio_info)); ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = ?", inst, device, info, fh, sstream); if ( driver_alsa_set_params(interface) < 0 ) goto init_error; ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = ?", inst, device, info, fh, sstream); memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = (void*) interface; inst->write = driver_alsa_write; inst->close = driver_alsa_close; inst->sync = driver_alsa_sync; inst->ctl = driver_alsa_ctl; ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = 0", inst, device, info, fh, sstream); return 0; init_error: snd_pcm_close(interface->handle); roar_mm_free(interface); return -1; } int driver_alsa_close(struct roar_vio_calls * vio) { roar_alsa_t * device = vio->inst; if ( device->handle != NULL ) { snd_pcm_drain(device->handle); snd_pcm_close(device->handle); } roar_mm_free(device); return 0; } static ssize_t driver_alsa_write_int(struct roar_vio_calls * vio, void *buf, size_t size) { roar_alsa_t * device = vio->inst; snd_pcm_sframes_t write_size = snd_pcm_bytes_to_frames(device->handle, size); snd_pcm_sframes_t rc; ROAR_DBG("driver_alsa_write(vio=%p, buf=%p, size=%llu) = ?", vio, buf, (long long unsigned int)size); rc = snd_pcm_writei(device->handle, buf, write_size); if ( rc == -EPIPE || rc == -EINTR || rc == -ESTRPIPE ) { if ( snd_pcm_recover(device->handle, rc, 1) < 0 ) return -1; return size; } else if (rc < 0) { ROAR_ERR("driver_alsa_write(*): Error from snd_pcm_writei(*): %s", snd_strerror(rc)); return -1; } return snd_pcm_frames_to_bytes(device->handle, rc); } ssize_t driver_alsa_write(struct roar_vio_calls * vio, void *buf, size_t size) { char* mutable_buf = (char*)buf; ssize_t have = 0; ssize_t ret; while (size) { ret = driver_alsa_write_int(vio, mutable_buf, size); if ( ret < 0 ) return -1; have += ret; mutable_buf += ret; size -= ret; } return have; } int driver_alsa_sync(struct roar_vio_calls * vio) { roar_alsa_t * device = vio->inst; return snd_pcm_drain(device->handle); } /* Stop the driver, set new params, and restart */ /* Not been able to test this function. */ /* Assuming that params can be reset after halting the PCM device */ static int driver_alsa_reopen_device(roar_alsa_t * device) { if ( snd_pcm_drop(device->handle) < 0 ) { ROAR_ERR("driver_alsa_reopen_device(*): snd_pcm_drop() failed."); return -1; } if ( driver_alsa_set_params(device) < 0 ) { ROAR_ERR("driver_alsa_reopen_device(*): driver_alsa_set_params() failed."); return -1; } return 0; } /* Not completely tested. * Tested: * ROAR_VIO_CTL_GET_DELAY * ROAR_VIO_CTL_SET_SSTREAMID * ROAR_VIO_CTL_SET_SSTREAM */ int driver_alsa_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { roar_alsa_t * device = vio->inst; snd_pcm_sframes_t alsa_delay; ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); switch (cmd) { case ROAR_VIO_CTL_GET_DELAY: if ( snd_pcm_delay(device->handle, &alsa_delay) < 0 ) return -1; else { *(uint_least32_t *)data = snd_pcm_frames_to_bytes(device->handle, alsa_delay); ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_DELAY(0x%.8x), data=%p): %i bytes.", vio, cmd, data, (int)(*(uint_least32_t*)data)); } break; case ROAR_VIO_CTL_SET_SSTREAMID: device->ssid = *(int *)data; ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_SSTREAMID(0x%.8x), data=%p): ssid=%i", vio, cmd, data, device->ssid); break; case ROAR_VIO_CTL_SET_SSTREAM: device->sstream = data; ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_SSTREAM(0x%.8x), data=%p): sstream=%p", vio, cmd, data, device->sstream); break; case ROAR_VIO_CTL_GET_AUINFO: ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_AUINFO(0x%.8x), data=%p) = ?", vio, cmd, data); memcpy(data, &(device->info), sizeof(struct roar_audio_info)); break; case ROAR_VIO_CTL_SET_AUINFO: ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_AUINFO(0x%.8x), data=%p) = ?", vio, cmd, data); memcpy(&(device->info), data, sizeof(struct roar_audio_info)); return driver_alsa_reopen_device(device); break; case ROAR_VIO_CTL_NONBLOCK: if ( *(int*)data == ROAR_SOCKET_BLOCK ) return 0; roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; default: return -1; } return 0; } #endif roaraudio-1.0beta11/roard/driver_ao.c0000644000175000017500000001051212264733665015721 0ustar phiphi//driver_ao.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBAO static int _driver_ao_usage_counter = 0; void driver_ao_init (void) { if ( _driver_ao_usage_counter++ == 0 ) ao_initialize(); #ifdef ROAR_HAVE_AO_APPEND_GLOBAL_OPTION ao_append_global_option("client_name", "roard"); #endif } void driver_ao_uninit (void) { if ( _driver_ao_usage_counter-- == 1 ) ao_shutdown(); } int driver_ao_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { //int driver_ao_open(DRIVER_USERDATA_T * inst, char * device, struct roar_audio_info * info) { ao_device * aodevice; ao_sample_format format; int driver; int autoconfig = 0; ROAR_WARN("The libao driver is obsolete, use another!"); if ( fh != -1 ) return -1; if ( sstream != NULL ) { autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF); } driver_ao_init(); if ( device == NULL ) { driver = ao_default_driver_id(); } else { if ( (driver = ao_driver_id(device)) == -1 ) { ROAR_ERR("Can not open audio device via libao's driver '%s'", device); driver_ao_uninit(); return -1; } } memset(&format, 0, sizeof(format)); format.bits = info->bits; format.channels = info->channels; format.rate = info->rate; if ( info->bits == 8 ) { ROAR_WARN("This is the libao driver in 8 bit mode, It's not known to me if I need to provide data in signed or in unsigned mode. If your musik sounds strange try -oO codec=pcm_s_le or -oO codec=pcm_u_be"); /* NOTE: the following is only true for EsounD driver, not for OSS driver, don't know for the others switch (info->codec) { case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_BE: case ROAR_CODEC_PCM_U_PDP: format.byte_format = AO_FMT_NATIVE; break; default: ROAR_ERR("Can not open audio device via libao: codec not supported. You may want to try -oO codec=pcm_u_le or -oO codec=pcm,bits=16"); driver_ao_uninit(); return -1; break; } */ } switch (info->codec) { case ROAR_CODEC_PCM_S_LE: format.byte_format = AO_FMT_LITTLE; break; case ROAR_CODEC_PCM_S_BE: format.byte_format = AO_FMT_BIG; break; default: if ( autoconfig ) { format.byte_format = AO_FMT_NATIVE; info->codec = ROAR_CODEC_DEFAULT; } else { ROAR_ERR("Can not open audio device via libao: codec not supported. You may want to try -oO codec=pcm"); driver_ao_uninit(); return -1; } break; } aodevice = ao_open_live(driver, &format, NULL /* no options */); if ( aodevice == NULL && autoconfig ) { format.byte_format = AO_FMT_NATIVE; format.bits = 16; info->codec = ROAR_CODEC_DEFAULT; info->bits = 16; aodevice = ao_open_live(driver, &format, NULL /* no options */); } if ( aodevice == NULL ) { ROAR_ERR("Can not open audio device via libao."); driver_ao_uninit(); return -1; } memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = (void*) aodevice; inst->write = driver_ao_write; inst->close = driver_ao_close; inst->ctl = driver_dummy_ctl; return 0; } int driver_ao_close(struct roar_vio_calls * vio) { ao_close((ao_device*)vio->inst); driver_ao_uninit(); return 0; } ssize_t driver_ao_write(struct roar_vio_calls * vio, void *buf, size_t count) { if ( ao_play((ao_device*)(vio->inst), buf, count) == 0 ) return -1; return count; } #endif //ll roaraudio-1.0beta11/roard/driver_artsc.c0000644000175000017500000001162712264733666016447 0ustar phiphi//driver_artsc.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBARTSC #define INIT +1 #define SHUTDOWN -1 static int driver_artsc_init_shutdown (int action) { static int state = 0; if ( action != INIT && action != SHUTDOWN ) return -1; if ( state == 0 && action == INIT ) { if ( arts_init() != 0 ) return -1; } else if ( state == 1 && action == SHUTDOWN ) { arts_free(); } state += action; return 0; } int driver_artsc_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct roar_artsc * self = NULL; int autoconfig = 0; (void)sstream; ROAR_WARN("The aRtsc driver is obsolete/broken, use another!"); ROAR_DBG("driver_artsc_open_vio(*) = ?"); if ( fh != -1 || device != NULL ) return -1; if ( sstream != NULL ) { autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF); } ROAR_DBG("driver_artsc_open_vio(*) = ?"); self = roar_mm_malloc(sizeof(struct roar_artsc)); if ( self == NULL ) return -1; memset(self, 0, sizeof(struct roar_artsc)); ROAR_DBG("driver_artsc_open_vio(*) = ?"); if ( driver_artsc_init_shutdown(INIT) == -1 ) { roar_mm_free(self); return -1; } ROAR_DBG("driver_artsc_open_vio(*) = ?"); if ( info->codec != ROAR_CODEC_DEFAULT ) { if ( autoconfig ) { info->codec = ROAR_CODEC_DEFAULT; } else { return -1; } } if ( info->bits != 16 ) { if ( autoconfig ) { info->bits = 16; } } self->info = info; self->stream = arts_play_stream(info->rate, info->bits, info->channels, "roard"); ROAR_DBG("driver_artsc_open_vio(*) = ?"); if ( self->stream == NULL && autoconfig ) { info->bits = 16; self->stream = arts_play_stream(info->rate, info->bits, info->channels, "roard"); } ROAR_DBG("driver_artsc_open_vio(*) = ?"); if ( self->stream == NULL ) { roar_mm_free(self); driver_artsc_init_shutdown(SHUTDOWN); ROAR_DBG("driver_artsc_open_vio(*) = -1"); return -1; } ROAR_DBG("driver_artsc_open_vio(*) = ?"); memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = (void*) self; inst->write = driver_artsc_write; inst->close = driver_artsc_close; inst->ctl = driver_artsc_ctl; ROAR_DBG("driver_artsc_open_vio(*) = 0"); return 0; } ssize_t driver_artsc_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct roar_artsc * self = vio->inst; int ret; ROAR_DBG("driver_artsc_write(*) = ?"); ret = arts_write(self->stream, buf, count); if ( ret >= 0 ) { ROAR_DBG("driver_artsc_write(*) = %i", ret); return ret; } ROAR_DBG("driver_artsc_write(*) = -1"); return -1; } int driver_artsc_close (struct roar_vio_calls * vio) { struct roar_artsc * self = vio->inst; arts_close_stream(self->stream); roar_mm_free(self); return driver_artsc_init_shutdown(SHUTDOWN); } int driver_artsc_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct roar_artsc * self = vio->inst; ssize_t bps; int ret; uint_least32_t tmp; switch (cmd) { case ROAR_VIO_CTL_GET_DBLKSIZE: ret = arts_stream_get(self->stream, ARTS_P_PACKET_SIZE); if ( ret > 0 ) { *(uint_least32_t *)data = ret; return 0; } break; case ROAR_VIO_CTL_GET_DELAY: ret = arts_stream_get(self->stream, ARTS_P_TOTAL_LATENCY); if ( ret < 0 ) return -1; bps = roar_info2bitspersec(self->info); if ( bps < 0 ) return -1; tmp = bps / (ssize_t)8; tmp *= ret; tmp /= (uint_least32_t)1000; *(uint_least32_t *)data = tmp; return 0; case ROAR_VIO_CTL_NONBLOCK: switch (*(int*)data) { case ROAR_SOCKET_NONBLOCK: ret = arts_stream_set(self->stream, ARTS_P_BLOCKING, 0); if ( ret == 0 ) return 0; return -1; break; case ROAR_SOCKET_BLOCK: ret = arts_stream_set(self->stream, ARTS_P_BLOCKING, 1); if ( ret == 1 ) return 0; return -1; break; } break; default: return -1; } return -1; } #endif //ll roaraudio-1.0beta11/roard/driver_dmx.c0000644000175000017500000000602312264733666016115 0ustar phiphi//driver_dmx.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_DMX int driver_dmx_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct roar_vio_defaults def; struct roar_vio_calls * vio; int err; const char * dev = device; char * dev_default_dmx4linux = NULL; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY, 0644) == -1 ) return -1; vio = roar_mm_malloc(sizeof(struct roar_vio_calls)); if ( vio == NULL ) return -1; roar_vio_clear_calls(vio); if ( fh == -1 ) { if ( dev == NULL ) dev = roar_env_get("DMX"); if ( dev == NULL ) { dev_default_dmx4linux = roar_libroar_get_path("dev-default-dmx4linux", 0, NULL, NULL); dev = dev_default_dmx4linux; } if ( roar_vio_open_dstr(vio, dev, &def, 1) == -1 ) { err = roar_error; roar_mm_free(vio); if ( dev_default_dmx4linux != NULL ) roar_mm_free(dev_default_dmx4linux); roar_error = err; return -1; } if ( dev_default_dmx4linux != NULL ) roar_mm_free(dev_default_dmx4linux); } else { if ( roar_vio_open_fh(vio, fh) == -1 ) { err = roar_error; roar_mm_free(vio); roar_error = err; return -1; } } vio->flags |= ROAR_VIO_FLAGS_FREESELF; roar_vio_open_pass(inst, vio); inst->write = driver_dmx_write; inst->ctl = driver_dmx_ctl; info->codec = ROAR_CODEC_DMX512; if ( sstream != NULL ) driver_dmx_ctl(inst, ROAR_VIO_CTL_SET_SSTREAM, sstream); return 0; } ssize_t driver_dmx_write (struct roar_vio_calls * vio, void *buf, size_t count) { if ( vio == NULL || buf == NULL ) return -1; if ( count != 512 ) return -1; if ( roar_vio_lseek(vio->inst, 0, SEEK_SET) == (roar_off_t)-1 ) return -1; return roar_vio_write(vio->inst, buf, count); } int driver_dmx_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if ( vio == NULL ) return -1; switch (cmd) { case ROAR_VIO_CTL_SET_SSTREAM: ROAR_STREAM(data)->dir = ROAR_DIR_LIGHT_OUT; ROAR_STREAM_SERVER(data)->codec_orgi = ROAR_CODEC_DMX512; break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; } return 0; } #endif //ll roaraudio-1.0beta11/roard/driver_dstr.c0000644000175000017500000000326712264733666016310 0ustar phiphi//driver_dstr.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_VIO_DSTR int driver_dstr_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct roar_vio_defaults def; if ( fh == -1 ) { if ( device == NULL ) return -1; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY|O_CREAT|O_TRUNC, 0644) == -1 ) return -1; if ( roar_vio_open_dstr(inst, device, &def, 1) == -1 ) return -1; } else { if ( roar_vio_open_fh(inst, fh) == -1 ) return -1; } if ( sstream != NULL ) _LIBROAR_IGNORE_RET(roar_vio_ctl(inst, ROAR_VIO_CTL_SET_SSTREAM, sstream)); return 0; } #endif //ll roaraudio-1.0beta11/roard/driver_esd.c0000644000175000017500000000350012264733667016076 0ustar phiphi//driver_esd.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_ESD int driver_esd_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { esd_format_t format = ESD_STREAM | ESD_PLAY; const char * name = "roard"; (void)sstream; if ( fh != -1 ) return -1; if ( info->bits >= 16 ) { info->bits = 16; format |= ESD_BITS16; info->codec = ROAR_CODEC_PCM_S; } else if ( info->bits < 16 ) { info->bits = 8; format |= ESD_BITS8; info->codec = ROAR_CODEC_PCM_U; } if ( info->channels >= 2 ) { info->channels = 2; format |= ESD_STEREO; } else { info->channels = 1; format |= ESD_MONO; } fh = esd_play_stream_fallback(format, info->rate, device, name); // test for error. if ( fh == -1 ) return -1; roar_vio_open_fh_socket(inst, fh); roar_vio_shutdown(inst, ROAR_VIO_SHUTDOWN_READ); return 0; } #endif //ll roaraudio-1.0beta11/roard/driver_i2cdmx.c0000644000175000017500000002333012264733667016514 0ustar phiphi//driver_i2cdmx.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_DRIVER_I2CDMX #include #include #define DEFAULT_DEVICE "/dev/i2c-1" #define DEV_TYPE 0x01 /* RI2C_DEV_BRIDGE */ #define DEV_SUBTYPE 0x01 /* RI2C_SUBTYPE_BRIDGE_CONVERTER */ #define DEVSTATUS_READY 0x01 /* RI2C_STATUS0_DEVICE_READY */ #define CAPS0_DMX512 0x10 /* RI2C_CAPS0_BRIDGE_DMX512 */ #define MIN_ADDR 0x20 #define MAX_ADDR 0x70 #define MAX_BUSSES 8 #define ADDR_IFVERSION 0 #define ADDR_DEVSTATUS 1 #define ADDR_COMMAND 2 #define ADDR_DEVERROR 3 #define ADDR_BANK 4 #define ADDR_DATA 5 #define ADDR_VENDOR (ADDR_BANK+2) #define ADDR_TYPE (ADDR_BANK+3) #define ADDR_SUBTYPE (ADDR_BANK+4) #define ADDR_PVENDOR (ADDR_BANK+10) #define ADDR_PTYPE (ADDR_BANK+11) #define ADDR_PSUBTYPE (ADDR_BANK+12) #define ADDR_CAPS0 (ADDR_BANK+13) #define COMMAND_DEVINFO 0x00 #define COMMAND_DMX 0x3f struct driver_i2cdmx { struct roar_vio_calls vio; uint8_t slave; size_t startaddr; size_t len; }; static inline int __i2c_set_slave(struct driver_i2cdmx * self) { struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SLAVE, .argp = (void*)(int)self->slave}; return roar_vio_ctl(&(self->vio), ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); } static inline int16_t __i2c_read(struct driver_i2cdmx * self, size_t off) { union i2c_smbus_data data = {.byte = 0}; struct i2c_smbus_ioctl_data args = {.read_write = I2C_SMBUS_READ, .command = off, .size = I2C_SMBUS_BYTE_DATA, .data = &data}; struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SMBUS, .argp = &args}; int ret = roar_vio_ctl(&(self->vio), ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); if ( ret == -1 ) return (int16_t)-1; return (int16_t)(uint16_t)(uint8_t)data.byte; } static inline int __i2c_write(struct driver_i2cdmx * self, size_t off, const uint8_t value) { union i2c_smbus_data data = {.byte = value}; struct i2c_smbus_ioctl_data args = {.read_write = I2C_SMBUS_WRITE, .command = off, .size = I2C_SMBUS_BYTE_DATA, .data = &data}; struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SMBUS, .argp = &args}; return roar_vio_ctl(&(self->vio), ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); } static inline int __i2c_command(struct driver_i2cdmx * self, uint8_t command) { int16_t ret; if ( __i2c_write(self, ADDR_COMMAND, command) == -1 ) return -1; ret = __i2c_read(self, ADDR_DEVERROR); if ( ret == (int16_t)-1 ) return -1; if ( ret == ROAR_ERROR_NONE ) return 0; roar_err_set(ret); return -1; } static inline int __i2c_start_dmx(struct driver_i2cdmx * self) { return __i2c_command(self, COMMAND_DMX); } static int __open_test_device_type(int16_t vendor, int16_t type, int16_t subtype) { if ( vendor == -1 || type == -1 || subtype == -1 ) return -1; if ( vendor != ROAR_VID_ROARAUDIO || type != DEV_TYPE || subtype != DEV_SUBTYPE ) { roar_err_set(ROAR_ERROR_TYPEMM); return -1; } return 0; } static int __open_test_device(struct driver_i2cdmx * self) { int16_t ret; int16_t vendor, type, subtype; #define __check_response(resp,test,error) if ( (resp) == (int16_t)-1 ) return -1; if ( !(test) ) { roar_err_set((error)); return -1; } // test for device interface version ret = __i2c_read(self, ADDR_IFVERSION); __check_response(ret, ret == 0, ROAR_ERROR_NSVERSION); // test for device overall status ret = __i2c_read(self, ADDR_DEVSTATUS); __check_response(ret, ret & DEVSTATUS_READY, ROAR_ERROR_BADSTATE); // Request device infos if ( __i2c_command(self, COMMAND_DEVINFO) == -1 ) return -1; // Check device infos // first check device type, then parent device type: vendor = __i2c_read(self, ADDR_VENDOR); type = __i2c_read(self, ADDR_TYPE); subtype = __i2c_read(self, ADDR_SUBTYPE); if ( __open_test_device_type(vendor, type, subtype) == -1 ) { vendor = __i2c_read(self, ADDR_PVENDOR); type = __i2c_read(self, ADDR_PTYPE); subtype = __i2c_read(self, ADDR_PSUBTYPE); if ( __open_test_device_type(vendor, type, subtype) == -1 ) return -1; } // check for DMX512 support: ret = __i2c_read(self, ADDR_CAPS0); __check_response(ret, ret & CAPS0_DMX512, ROAR_ERROR_TYPEMM); return 0; } static int __open_scan_devices(struct driver_i2cdmx * self) { uint8_t i; for (i = MIN_ADDR; i < MAX_ADDR; i++) { self->slave = i; if ( __i2c_set_slave(self) == -1 ) continue; if ( __open_test_device(self) == -1 ) continue; return 0; } self->slave = 0; roar_err_set(ROAR_ERROR_NOENT); return -1; } static int __open_device_and_slave(struct driver_i2cdmx * self, int autoconf, const char * device) { char filename[40]; char * p; int need_autoconf = 0; int ret; int err; // test if the device exist. if ( roar_vio_open_dstr_simple(&(self->vio), device, ROAR_VIOF_READWRITE) == 0 ) { need_autoconf = 1; } else { // the device doesn't exist. We guss it is in form $device/$slaveid. strncpy(filename, device, sizeof(filename)); p = strrchr(filename, '/'); if ( p == NULL ) { // it doesn't seem to be in the given form so it seems it was just a device name of an missingd evice. roar_err_set(ROAR_ERROR_NOENT); return -1; } *p = 0; p++; // now we have the device name in filename, and the slave ID in p. self->slave = atoi(p); // little test to protect the user from doing dumb things. if ( self->slave == 0 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( roar_vio_open_dstr_simple(&(self->vio), filename, ROAR_VIOF_READWRITE) == -1 ) return -1; } // ok, the bus is now open. Let's open the device: if ( need_autoconf ) { ret = __open_scan_devices(self); } else { ret = __i2c_set_slave(self); if ( ret == 0 ) ret = __open_test_device(self); } if ( ret == -1 ) { err = roar_error; roar_vio_close(&(self->vio)); roar_err_set(err); } return ret; } static int __open_scan_busses(struct driver_i2cdmx * self) { char filename[20]; int i; int ret; for (i = 0; i < MAX_BUSSES; i++) { snprintf(filename, sizeof(filename), "/dev/i2c-%i", i); ret = __open_device_and_slave(self, 1, filename); if ( ret == 0 ) return 0; } roar_err_set(ROAR_ERROR_NOENT); return -1; } static int __i2c_write_channel(struct driver_i2cdmx * self, size_t channel, uint8_t value) { size_t bank, offset; bank = channel/32; offset = bank*32; if ( __i2c_write(self, ADDR_BANK, bank) == -1 ) return -1; return __i2c_write(self, ADDR_DATA+channel-offset, value); } static ssize_t __vio_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_i2cdmx * self; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } self = vio->inst; if ( __i2c_start_dmx(self) == -1 ) return -1; roar_err_set(ROAR_ERROR_NOSYS); return -1; } static ssize_t __vio_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_i2cdmx * self; size_t i; size_t endaddr; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } self = vio->inst; if ( count != 512 ) { roar_err_set(ROAR_ERROR_INVAL); return -1; } if ( __i2c_start_dmx(self) == -1 ) return -1; for (i = self->startaddr, endaddr = self->startaddr + self->len; i < endaddr; i++) if ( __i2c_write_channel(self, i, ((uint8_t*)buf)[i]) == -1 ) return -1; return count; } static int __vio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct driver_i2cdmx * self; if ( vio == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } self = vio->inst; switch (cmd) { case ROAR_VIO_CTL_SET_SSTREAM: if ( ROAR_STREAM(data)->dir != ROAR_DIR_LIGHT_OUT && ROAR_STREAM(data)->dir != ROAR_DIR_LIGHT_IN ) { ROAR_STREAM(data)->dir = ROAR_DIR_LIGHT_OUT; } ROAR_STREAM_SERVER(data)->codec_orgi = ROAR_CODEC_DMX512; break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; } return 0; } static int __vio_close (struct roar_vio_calls * vio) { struct driver_i2cdmx * self = vio->inst; roar_vio_close(&(self->vio)); roar_mm_free(self); return 0; } int driver_i2cdmx_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_i2cdmx * self; int autoconf = 1; int ret; if ( fh != -1 ) { roar_err_set(ROAR_ERROR_NOSYS); return -1; } self = roar_mm_malloc(sizeof(struct driver_i2cdmx)); if ( self == NULL ) { return -1; } memset(self, 0, sizeof(*self)); self->startaddr = 0; self->len = info->channels; info->bits = 8; info->codec = ROAR_CODEC_DMX512; if ( device == NULL && !autoconf ) { device = DEFAULT_DEVICE; } if ( device == NULL ) { ret = __open_scan_busses(self); } else { ret = __open_device_and_slave(self, autoconf, device); } if ( ret == -1 ) { roar_mm_free_noerror(self); return -1; } roar_vio_clear_calls(inst); inst->inst = self; inst->read = __vio_read; inst->write = __vio_write; inst->close = __vio_close; inst->ctl = __vio_ctl; return 0; } #endif roaraudio-1.0beta11/roard/driver_jack.c0000644000175000017500000001777312264733667016254 0ustar phiphi//driver_jack.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * Copyright (C) Nedko Arnaudov - 2010 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBJACK static void unregister_ports(struct driver_jack * self) { while(self->channels--) { if ( self->ports_in != NULL ) if ( self->ports_in [self->channels] != NULL ) jack_port_unregister(self->client, self->ports_in [self->channels]); if ( self->ports_out[self->channels] != NULL ) jack_port_unregister(self->client, self->ports_out[self->channels]); } } int driver_jack_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_jack * self; char port_name[128]; jack_nframes_t new_rate; int autoconfig = 0; int recsource = 0; // we are not FH Safe, return error if fh != -1: if ( fh != -1 ) return -1; if ( sstream != NULL ) { autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF); recsource = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_RECSOURCE); } // set up VIO: memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->read = driver_jack_read; inst->write = driver_jack_write; inst->lseek = NULL; // no seeking on this device inst->sync = driver_jack_sync; inst->ctl = driver_jack_ctl; inst->close = driver_jack_close; // set up internal struct: if ( (self = roar_mm_malloc(sizeof(struct driver_jack))) == NULL ) return -1; memset(self, 0, sizeof(struct driver_jack)); inst->inst = self; if ( (self->client = jack_client_open("roard", JackNullOption, NULL)) == NULL ) { roar_mm_free(self); return -1; } new_rate = jack_get_sample_rate(self->client); // need to check if we need to change stream's parameters: if ( info->rate != new_rate || info->bits != 32 || info->codec != ROAR_CODEC_DEFAULT ) { if ( autoconfig ) { // we are allowed to change the parameters info->rate = new_rate; info->bits = 32; info->codec = ROAR_CODEC_DEFAULT; } else { // we are not allowed to change the parameters ROAR_WARN("driver_jack_open_vio(*): Can not open jack driver with given parameters, try -oO ...,autoconf"); goto free_close; } } if ( recsource ) if ( (self->ports_in = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL ) goto free_close; if ( (self->ports_out = roar_mm_malloc(sizeof(jack_port_t *) * info->channels)) == NULL ) goto free_ins; // NULL ports so we do not segfaul if something goes wrong. if ( self->ports_in != NULL ) memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels); memset(self->ports_in, 0, sizeof(jack_port_t *) * info->channels); for (self->channels = 0; self->channels < info->channels; self->channels++) { if ( recsource ) { snprintf(port_name, sizeof(port_name), "in_%03u", self->channels); if ( (self->ports_in [self->channels] = jack_port_register(self->client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL ) goto unregister_ports; } snprintf(port_name, sizeof(port_name), "out_%03u", self->channels); if ( (self->ports_out[self->channels] = jack_port_register(self->client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL ) { jack_port_unregister(self->client, self->ports_in[self->channels]); goto unregister_ports; } } if (jack_activate(self->client) != 0) goto unregister_ports; return 0; unregister_ports: unregister_ports(self); free_ins: if ( self->ports_in != NULL ) roar_mm_free(self->ports_in); free_close: jack_client_close(self->client); roar_mm_free(self); return -1; // error } ssize_t driver_jack_read (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_jack * self = vio->inst; // read up to count bytes into buf. // return the number of bits read. return -1; } ssize_t driver_jack_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_jack * self = vio->inst; // write up to count bytes from buf. // return the number of written bytes. return -1; } int driver_jack_sync (struct roar_vio_calls * vio) { struct driver_jack * self = vio->inst; // init to sync data to device. // sync does not need to be complet when this function returns. return 0; } int driver_jack_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct driver_jack * self = vio->inst; // function for a lot control features. switch (cmd) { case ROAR_VIO_CTL_GET_NAME: if ( data == NULL ) return -1; *(char**)data = "driver_jack"; return 0; break; case ROAR_VIO_CTL_GET_FH: case ROAR_VIO_CTL_GET_READ_FH: case ROAR_VIO_CTL_GET_WRITE_FH: case ROAR_VIO_CTL_GET_SELECT_FH: case ROAR_VIO_CTL_GET_SELECT_READ_FH: case ROAR_VIO_CTL_GET_SELECT_WRITE_FH: /* Return FH if possible: *(int*)data = FH...; */ roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_SET_NOSYNC: vio->sync = NULL; return 0; break; case ROAR_VIO_CTL_NONBLOCK: // control if read and write calls should block untill all data is read or written. // state is in *(int*)data and could be: // ROAR_SOCKET_BLOCK - Block untill the data is read or written // ROAR_SOCKET_NONBLOCK - Return as soon as possible roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_GET_AUINFO: case ROAR_VIO_CTL_SET_AUINFO: // get or set audio info, data is a struct roar_audio_info*. roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_GET_DBLKSIZE: case ROAR_VIO_CTL_SET_DBLKSIZE: // get or set block size used, data is uint_least32_t*, number of bytes. roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_GET_DBLOCKS: case ROAR_VIO_CTL_SET_DBLOCKS: // get or set number of blocks used, data is uint_least32_t*. roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_SET_SSTREAM: // set server stream object for this stream, data is struct roar_stream_server* roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_SET_SSTREAMID: // set stream ID for this stream, data is int* roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_SET_VOLUME: // set volume for this device, data is struct roar_mixer_settings* roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; case ROAR_VIO_CTL_GET_DELAY: // get delay of this stream, data is uint_least32_t*, in bytes // there is more about delay. please ask. roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } roar_err_set(ROAR_ERROR_BADRQC); return -1; } int driver_jack_close (struct roar_vio_calls * vio) { struct driver_jack * self = vio->inst; // close and free everything in here... jack_deactivate(self->client); unregister_ports(self); jack_client_close(self->client); roar_mm_free(self); return 0; } #endif //ll roaraudio-1.0beta11/roard/driver_oss.c0000644000175000017500000003720212264733667016135 0ustar phiphi//driver_oss.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) #define _get(vio,obj) (((struct driver_oss*)((vio)->inst))->obj) int driver_oss_init_vio(struct roar_vio_calls * vio, struct driver_oss * inst) { if ( vio == NULL ) return -1; memset(vio, 0, sizeof(struct roar_vio_calls)); vio->flags = ROAR_VIO_FLAGS_NONE; vio->refc = 1; vio->write = driver_oss_write; vio->read = driver_oss_read; vio->sync = driver_oss_sync; vio->ctl = driver_oss_ctl; vio->close = driver_oss_close_vio; vio->inst = (void*) inst; return 0; } int driver_oss_open_device(struct driver_oss * self) { int flags = 0; int rw = 0; int fh = self->fh; char * device = self->device; if ( fh != -1 ) return 0; #ifdef ROAR_DEFAULT_OSS_DEV if ( device == NULL ) device = ROAR_DEFAULT_OSS_DEV; #endif if ( device == NULL ) { ROAR_ERR("driver_oss_open_device(*): no default device found, you need to specify one manuelly"); return -1; } if ( self->ssid != -1 ) { rw = streams_get_flag(self->ssid, ROAR_FLAG_RECSOURCE); } if ( rw ) { flags |= O_RDWR; } else { flags |= O_WRONLY; } if ( (fh = open(device, flags, 0644)) == -1 ) { ROAR_ERR("driver_oss_open_device(*): Can not open OSS device: %s: %s", device, strerror(errno)); return -1; } self->fh = fh; self->need_config = 1; return 0; } int driver_oss_config_device(struct driver_oss * self) { int fh = self->fh; struct roar_audio_info * info = &(self->info); int tmp, ctmp; char * es; int autoconfig = 0; int need_update_server = 0; if ( fh == -1 ) return -1; if ( self->ssid != -1 ) { autoconfig = streams_get_flag(self->ssid, ROAR_FLAG_AUTOCONF); } ROAR_DBG("driver_oss_config_device(self=%p): ssid=%i, autoconfig=%i", self, self->ssid, autoconfig); #ifdef SNDCTL_DSP_CHANNELS tmp = info->channels; if ( ioctl(fh, SNDCTL_DSP_CHANNELS, &tmp) == -1 ) { ROAR_ERR("driver_oss_config_device(*): can not set number of channels"); return -1; } if ( tmp != info->channels ) { if ( autoconfig ) { need_update_server = 1; self->info.channels = tmp; } else { ROAR_ERR("driver_oss_config_device(*): can not set requested numer of channels, OSS suggested %i channels, to use this restart with -oO channels=%i or set codec manuelly via -oO channels=num", tmp, tmp); return -1; } } #else switch (info->channels) { case 1: tmp = 0; break; case 2: tmp = 1; break; default: return -1; } if ( ioctl(fh, SNDCTL_DSP_STEREO, &tmp) == -1 ) { ROAR_ERR("driver_oss_config_device(*): can not set number of channels"); return -1; } #endif if ( autoconfig ) { if ( info->bits > 16 ) { info->bits = 32; need_update_server = 1; } if ( info->bits == 32 ) { switch (info->codec) { #ifndef AFMT_S32_LE case ROAR_CODEC_PCM_S_LE: #endif #ifndef AFMT_S32_BE case ROAR_CODEC_PCM_S_BE: #endif case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_BE: info->bits = 16; need_update_server = 1; break; } } } switch (info->codec) { case ROAR_CODEC_PCM_S_LE: switch (info->bits) { case 8: tmp = AFMT_S8; break; case 16: tmp = AFMT_S16_LE; break; // case 24: tmp = AFMT_S24_PACKED; break; #ifdef AFMT_S32_LE case 32: tmp = AFMT_S32_LE; break; #endif default: return -1; } break; case ROAR_CODEC_PCM_S_BE: switch (info->bits) { case 8: tmp = AFMT_S8; break; case 16: tmp = AFMT_S16_BE; break; // case 24: tmp = AFMT_S24_PACKED; break; #ifdef AFMT_S32_BE case 32: tmp = AFMT_S32_BE; break; #endif default: return -1; } break; case ROAR_CODEC_PCM_U_LE: switch (info->bits) { case 8: tmp = AFMT_U8; break; case 16: tmp = AFMT_U16_LE; break; default: return -1; } break; case ROAR_CODEC_PCM_U_BE: switch (info->bits) { case 8: tmp = AFMT_U8; break; case 16: tmp = AFMT_U16_BE; break; default: return -1; } case ROAR_CODEC_ALAW: tmp = AFMT_A_LAW; break; case ROAR_CODEC_MULAW: tmp = AFMT_MU_LAW; break; #ifdef AFMT_VORBIS case ROAR_CODEC_OGG_VORBIS: tmp = AFMT_VORBIS; break; #endif default: return -1; break; } ctmp = tmp; #ifdef SNDCTL_DSP_SETFMT if ( ioctl(fh, SNDCTL_DSP_SETFMT, &tmp) == -1 ) { #else if ( ioctl(fh, SNDCTL_DSP_SAMPLESIZE, &tmp) == -1 ) { #endif ROAR_ERR("driver_oss_config_device(*): can not set sample format"); return -1; } if ( tmp != ctmp ) { if ( autoconfig ) { need_update_server = 1; switch (tmp) { case AFMT_S8 : self->info.bits = 8; self->info.codec = ROAR_CODEC_PCM; break; case AFMT_U8 : self->info.bits = 8; self->info.codec = ROAR_CODEC_PCM_U_LE; break; case AFMT_S16_LE: self->info.bits = 16; self->info.codec = ROAR_CODEC_PCM_S_LE; break; case AFMT_S16_BE: self->info.bits = 16; self->info.codec = ROAR_CODEC_PCM_S_BE; break; case AFMT_U16_LE: self->info.bits = 16; self->info.codec = ROAR_CODEC_PCM_U_LE; break; case AFMT_U16_BE: self->info.bits = 16; self->info.codec = ROAR_CODEC_PCM_U_BE; break; #ifdef AFMT_S32_LE case AFMT_S32_LE: self->info.bits = 32; self->info.codec = ROAR_CODEC_PCM_S_LE; break; #endif #ifdef AFMT_S32_BE case AFMT_S32_BE: self->info.bits = 32; self->info.codec = ROAR_CODEC_PCM_S_BE; break; #endif /* case AFMT_A_LAW : self->info.bits = 8; self->info.codec = ROAR_CODEC_ALAW; break; case AFMT_MU_LAW: self->info.bits = 8; self->info.codec = ROAR_CODEC_MULAW; break; #ifdef AFMT_VORBIS case AFMT_VORBIS: self->info.codec = ROAR_CODEC_OGG_VORBIS; break; #endif */ case AFMT_A_LAW: case AFMT_MU_LAW: #ifdef AFMT_VORBIS case AFMT_VORBIS: #endif ROAR_WARN("driver_oss_config_device(*): Auto config failed: OSS Codec %i needs a codecfilter!", tmp); ROAR_ERR("driver_oss_config_device(*): can not set requested codec, set codec manuelly via -oO codec=somecodec"); return -1; break; default: ROAR_WARN("driver_oss_config_device(*): Auto config failed: unknown OSS Codec %i", tmp); ROAR_ERR("driver_oss_config_device(*): can not set requested codec, set codec manuelly via -oO codec=somecodec"); return -1; break; } } else { es = NULL; switch (tmp) { case AFMT_S8 : es = "bits=8,codec=pcm"; break; case AFMT_U8 : es = "bits=8,codec=pcm_u_le"; break; case AFMT_S16_LE: es = "bits=16,codec=pcm_s_le"; break; case AFMT_S16_BE: es = "bits=16,codec=pcm_s_be"; break; case AFMT_U16_LE: es = "bits=16,codec=pcm_u_le"; break; case AFMT_U16_BE: es = "bits=16,codec=pcm_u_be"; break; #ifdef AFMT_S32_LE case AFMT_S32_LE: es = "bits=32,codec=pcm_s_le"; break; #endif #ifdef AFMT_S32_BE case AFMT_S32_BE: es = "bits=32,codec=pcm_s_be"; break; #endif case AFMT_A_LAW : es = "codec=alaw"; break; case AFMT_MU_LAW: es = "codec=mulaw"; break; #ifdef AFMT_VORBIS case AFMT_VORBIS: es = "codec=ogg_vorbis"; break; #endif } if ( es != NULL ) { ROAR_ERR("driver_oss_config_device(*): can not set requested codec, OSS retruned another codec than requested, to use this restart with -oO %s or set codec manuelly via -oO codec=somecodec", es); } else { ROAR_ERR("driver_oss_config_device(*): can not set requested codec, set codec manuelly via -oO codec=somecodec"); } return -1; } } tmp = info->rate; if ( ioctl(fh, SNDCTL_DSP_SPEED, &tmp) == -1 ) { ROAR_ERR("driver_oss_config_device(*): can not set sample rate"); return -1; } if ( tmp != info->rate ) { if ( autoconfig ) { need_update_server = 1; self->info.rate = tmp; } else { ROAR_WARN("driver_oss_config_device(*): Device does not support requested sample rate: req=%iHz, sug=%iHz", info->rate, tmp); if ( tmp < info->rate * 0.98 || tmp > info->rate * 1.02 ) { ROAR_ERR("driver_oss_config_device(*): sample rate out of acceptable accuracy"); return -1; } } } // latency things: #ifdef SNDCTL_DSP_SETFRAGMENT // defaults if ( self->blocksize < 1 ) self->blocksize = 2048; if ( self->blocks < 1 ) self->blocks = 4; switch (self->blocksize) { case 1<< 4: tmp = 4; break; case 1<< 5: tmp = 5; break; case 1<< 6: tmp = 6; break; case 1<< 7: tmp = 7; break; case 1<< 8: tmp = 8; break; case 1<< 9: tmp = 9; break; case 1<<10: tmp = 10; break; case 1<<11: tmp = 11; break; case 1<<12: tmp = 12; break; case 1<<13: tmp = 13; break; case 1<<14: tmp = 14; break; case 1<<15: tmp = 15; break; case 1<<16: tmp = 16; break; default: tmp = 11; ROAR_WARN("driver_oss_config_device(*): blocksize of %i byte is not a valid value. trying 2KB", self->blocksize); break; } ROAR_DBG("driver_oss_config_device(*): blocksize=%i(N=%i), blocks=%i", self->blocksize, tmp, self->blocks); tmp |= self->blocks << 16; if ( ioctl(fh, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1 ) { ROAR_WARN("driver_oss_ctl(*): Can not set fragment size, sorry :("); } #endif if ( need_update_server ) { if ( self->stream == NULL ) { streams_get(self->ssid, &(self->stream)); } if ( self->stream == NULL ) { ROAR_ERR("driver_oss_config_device(*): Auto config failed: can not set new values for stream: no stream object known"); return -1; } memcpy(&(ROAR_STREAM(self->stream)->info), info, sizeof(struct roar_audio_info)); } ROAR_DBG("driver_oss_config_device(*): self->ssid=%i, fh=%i", self->ssid, fh); streams_set_fh(self->ssid, -2); self->need_config = 0; ROAR_DBG("driver_oss_config_device(*) = 0"); return 0; } #define er() close(self->fh); if ( self->device ) roar_mm_free(self->device); roar_mm_free(self); return -1 int driver_oss_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_oss * self = NULL; if ( (self = roar_mm_malloc(sizeof(struct driver_oss))) == NULL ) { ROAR_ERR("driver_oss_open(*): Can not roar_mm_malloc() instance data: %s", strerror(errno)); return -1; } memset(self, 0, sizeof(struct driver_oss)); memcpy(&(self->info), info, sizeof(struct roar_audio_info)); self->ssid = -1; self->fh = fh; if ( sstream != NULL ) self->ssid = ROAR_STREAM(sstream)->id; if ( fh != -1 ) { self->fh_savemode = 1; } else { self->fh_savemode = 0; } if ( device != NULL ) self->device = roar_mm_strdup(device); if ( driver_oss_init_vio(inst, self) == -1 ) { ROAR_ERR("driver_oss_open(*): Can not init vio interface"); er(); } if ( driver_oss_open_device(self) == -1 ) { ROAR_ERR("driver_oss_open(*): Can not open audio device"); er(); } ROAR_DBG("driver_oss_open(*): OSS devices opened :)"); if ( sstream != NULL ) driver_oss_ctl(inst, ROAR_VIO_CTL_SET_SSTREAM, sstream); return 0; } #undef er int driver_oss_reopen_device(struct driver_oss * self) { // we need to reject in fh save mode. if ( self->fh_savemode ) return -1; #ifdef SNDCTL_DSP_SYNC ioctl(self->fh, SNDCTL_DSP_SYNC, NULL); #endif close(self->fh); if ( driver_oss_open_device(self) == -1 ) return -1; self->need_config = 1; return 0; } int driver_oss_close(DRIVER_USERDATA_T inst) { return roar_vio_close((struct roar_vio_calls *)inst); } int driver_oss_close_vio(struct roar_vio_calls * vio) { close(_get(vio,fh)); if ( _get(vio,device) != NULL ) roar_mm_free(_get(vio,device)); roar_mm_free(vio->inst); return 0; } int driver_oss_sync(struct roar_vio_calls * vio) { #ifdef SNDCTL_DSP_SYNC return ioctl(_get(vio,fh), SNDCTL_DSP_SYNC, NULL); #else return 0; #endif } int driver_oss_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct driver_oss * self = vio->inst; #ifdef SNDCTL_DSP_GETODELAY int d; #endif ROAR_DBG("driver_oss_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data); if ( vio == NULL ) return -1; switch (cmd) { case ROAR_VIO_CTL_GET_DELAY: #ifdef SNDCTL_DSP_GETODELAY if ( ioctl(_get(vio,fh), SNDCTL_DSP_GETODELAY, &d) == -1 ) return -1; ROAR_DBG("driver_oss_ctl(*): delay=%i byte", d); *(uint_least32_t *)data = d; #else return -1; #endif break; case ROAR_VIO_CTL_SET_DBLOCKS: #ifdef SNDCTL_DSP_SETFRAGMENT if ( !self->need_config ) { ROAR_WARN("driver_oss_ctl(*): possible late ROAR_VIO_CTL_SET_DBLOCKS, setting anyway."); } self->blocks = *(uint_least32_t *)data; #else return -1; #endif break; case ROAR_VIO_CTL_SET_DBLKSIZE: #ifdef SNDCTL_DSP_SETFRAGMENT if ( !self->need_config ) { ROAR_WARN("driver_oss_ctl(*): possible late ROAR_VIO_CTL_SET_DBLKSIZE, setting anyway."); } self->blocksize = *(uint_least32_t *)data; #else return -1; #endif break; case ROAR_VIO_CTL_GET_DBLKSIZE: if ( !self->blocksize ) return -1; *(uint_least32_t *)data = self->blocksize; break; case ROAR_VIO_CTL_SET_SSTREAMID: self->ssid = *(int *)data; break; case ROAR_VIO_CTL_SET_SSTREAM: self->stream = data; break; case ROAR_VIO_CTL_GET_AUINFO: memcpy(data, &(self->info), sizeof(struct roar_audio_info)); break; case ROAR_VIO_CTL_SET_AUINFO: memcpy(&(self->info), data, sizeof(struct roar_audio_info)); return driver_oss_reopen_device(self); break; #ifdef SNDCTL_DSP_SETPLAYVOL case ROAR_VIO_CTL_SET_VOLUME: switch (self->info.channels) { case 1: d = ROAR_MIXER(data)->mixer[0] * 100 / ROAR_MIXER(data)->scale; d |= d << 8; break; case 2: d = ROAR_MIXER(data)->mixer[0] * 100 / ROAR_MIXER(data)->scale; d |= (ROAR_MIXER(data)->mixer[0] * 100 / ROAR_MIXER(data)->scale) << 8; break; default: return -1; } return ioctl(_get(vio,fh), SNDCTL_DSP_SETPLAYVOL, &d); break; #endif case ROAR_VIO_CTL_NONBLOCK: if ( roar_socket_nonblock(_get(vio,fh), *(int*)data) == -1 ) { return -1; } if ( *(int*)data == ROAR_SOCKET_NONBLOCK ) { return 0; } roar_vio_sync(vio); break; default: return -1; } return 0; } ssize_t driver_oss_write (struct roar_vio_calls * vio, void *buf, size_t count) { ROAR_DBG("driver_oss_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); if ( _get(vio,fh) == -1 ) return -1; if ( _get(vio,need_config) ) { if ( driver_oss_config_device(vio->inst) == -1 ) { return -1; } } return write(_get(vio,fh), buf, count); } ssize_t driver_oss_read (struct roar_vio_calls * vio, void *buf, size_t count) { ROAR_DBG("driver_oss_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); if ( _get(vio,fh) == -1 ) return -1; if ( _get(vio,need_config) ) { if ( driver_oss_config_device(vio->inst) == -1 ) { ROAR_DBG("driver_oss_read(vio=%p, buf=%p, count=%llu) = -1", vio, buf, (long long unsigned int)count); return -1; } } ROAR_DBG("driver_oss_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); return read(_get(vio,fh), buf, count); } #endif //ll roaraudio-1.0beta11/roard/driver_portaudio.c0000644000175000017500000001672512264733667017346 0ustar phiphi//driver_portaudio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * Copyright (C) Hans-Kristian 'maister' Arntzen - 2010-2011 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef _DRIVER_PORTAUDIO_CAN_OPERATE int driver_portaudio_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_portaudio * self; PaSampleFormat fmt; #ifdef ROAR_HAVE_LIBPABLIO long flags = PABLIO_WRITE; #elif defined(ROAR_HAVE_PA19_VERSION_19) PaStreamParameters params; const PaDeviceInfo * dev_info = NULL; #endif PaError err; int autoconfig = 0; if ( fh != -1 ) return -1; if ( sstream != NULL ) { autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF); } switch (info->bits) { case 8: switch (info->codec) { case ROAR_CODEC_PCM_S_LE: case ROAR_CODEC_PCM_S_BE: case ROAR_CODEC_PCM_S_PDP: fmt = paInt8; break; case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_BE: case ROAR_CODEC_PCM_U_PDP: fmt = paUInt8; break; default: if ( autoconfig ) { info->codec = ROAR_CODEC_DEFAULT; fmt = paInt8; } else { return -1; } break; } break; case 16: if ( info->codec != ROAR_CODEC_DEFAULT ) { if ( autoconfig ) { info->codec = ROAR_CODEC_DEFAULT; } else { return -1; } } fmt = paInt16; break; #ifdef paPackedInt24 case 24: if ( info->codec != ROAR_CODEC_DEFAULT ) { if ( autoconfig ) { info->codec = ROAR_CODEC_DEFAULT; } else { return -1; } } fmt = paPackedInt24; break; #endif case 32: if ( info->codec != ROAR_CODEC_DEFAULT ) { if ( autoconfig ) { info->codec = ROAR_CODEC_DEFAULT; } else { return -1; } } fmt = paInt32; break; default: if ( autoconfig ) { info->codec = ROAR_CODEC_DEFAULT; info->bits = 16; fmt = paInt16; } else { return -1; } break; } if ( (self = roar_mm_malloc(sizeof(struct driver_portaudio))) == NULL ) return -1; memset(self, 0, sizeof(struct driver_portaudio)); memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = self; inst->close = driver_portaudio_close; inst->write = driver_portaudio_write; inst->ctl = driver_dummy_ctl; Pa_Initialize(); #ifdef ROAR_HAVE_LIBPABLIO switch (info->channels) { case 1: flags |= PABLIO_MONO; break; case 2: flags |= PABLIO_STEREO; break; default: if ( autoconfig ) { info->channels = 2; flags |= PABLIO_STEREO; } else { roar_mm_free(self); Pa_Terminate(); return -1; } } err = OpenAudioStream(&(self->ostream), info->rate, fmt, flags); if ( err != paNoError && autoconfig ) { if ( (flags & PABLIO_MONO) == PABLIO_MONO ) { flags -= PABLIO_MONO; flags |= PABLIO_STEREO; info->channels = 2; } fmt = paInt16; info->codec = ROAR_CODEC_DEFAULT; info->bits = 16; err = OpenAudioStream(&(self->ostream), info->rate, fmt, flags); } if ( err != paNoError ) { roar_mm_free(self); Pa_Terminate(); return -1; } return 0; #elif defined(ROAR_HAVE_PA19_VERSION_19) err = paNoError; params.device = Pa_GetDefaultOutputDevice(); params.channelCount = info->channels; params.sampleFormat = fmt; if ( params.device != paNoDevice ) dev_info = Pa_GetDeviceInfo(params.device); if ( dev_info != NULL ) { params.suggestedLatency = dev_info->defaultLowOutputLatency; } else { err = paNoDevice; } params.hostApiSpecificStreamInfo = NULL; // TODO: FIXME: use libroar for this. self->framesize = info->bits * info->channels / 8; // Sets up blocking I/O stream. if ( err == paNoError ) { err = Pa_OpenStream(&(self->stream), NULL, ¶ms, info->rate, 128 /*FIXME:frames*/, paClipOff, NULL, NULL ); } if ( err != paNoError && err != paNoDevice && autoconfig ) { params.sampleFormat = paInt16; params.channelCount = 2; info->codec = ROAR_CODEC_DEFAULT; info->bits = 16; info->channels = 2; err = Pa_OpenStream(&(self->stream), NULL, ¶ms, info->rate, 128 /*FIXME:frames*/, paClipOff, NULL, NULL ); } if ( err != paNoError ) { ROAR_ERR("driver_portaudio_open(*): Could not open PortAudio device: \"%s\".", Pa_GetErrorText(err)); roar_mm_free(self); return -1; } err = Pa_StartStream(self->stream); if ( err != paNoError ) { ROAR_ERR("driver_portaudio_open(*): Could not start stream: \"%s\".", Pa_GetErrorText(err)); roar_mm_free(self); return -1; } return 0; #else return -1; #endif } int driver_portaudio_close (struct roar_vio_calls * vio) { struct driver_portaudio * self = vio->inst; // TODO: cleanup common code. #ifdef ROAR_HAVE_LIBPABLIO CloseAudioStream(self->ostream); Pa_Terminate(); roar_mm_free(self); return 0; #elif defined(ROAR_HAVE_PA19_VERSION_19) if ( (self != NULL) && (self->stream != NULL) ) { Pa_StopStream(self->stream); Pa_CloseStream(self->stream); } roar_mm_free(self); Pa_Terminate(); return 0; #else return -1; #endif } ssize_t driver_portaudio_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_portaudio * self = vio->inst; #ifdef ROAR_HAVE_PA19_VERSION_19 size_t write_frames = count / self->framesize; PaError err; #endif ROAR_DBG("driver_portaudio_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); #ifdef ROAR_HAVE_LIBPABLIO count /= self->ostream->bytesPerFrame; // TODO: FIXME: do not access private members ROAR_DBG("driver_portaudio_write(vio=%p, buf=%p, count=%llu) = ? // PABLIO mode", vio, buf, (long long unsigned int)count); return WriteAudioStream(self->ostream, buf, count) * self->ostream->bytesPerFrame; #elif defined(ROAR_HAVE_PA19_VERSION_19) ROAR_DBG("driver_portaudio_write(vio=%p, buf=%p, size=%llu) = ?", vio, buf, (long long unsigned int)size); // I'm not 100% sure if you could write arbitrary number of frames to Pa_WriteStream(), but it seems to be backend dependent. err = Pa_WriteStream(self->stream, buf, write_frames); if ( err < 0 && err != paOutputUnderflowed ) return -1; // PA always seems to write requested size, or it will error out. return count; #else return -1; #endif } #endif //ll roaraudio-1.0beta11/roard/driver_pulsesimple.c0000644000175000017500000001155512264733667017676 0ustar phiphi//driver_pulsesimple.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBPULSE int driver_pulsesimple_open (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_pulsesimple * self; const char * subdev = NULL; int pulseerror = -1; pa_stream_direction_t dir = PA_STREAM_PLAYBACK; pa_sample_spec ss; int autoconfig = 0; int needauto = 0; // pa_sample_format_t format; /**< The sample format */ if ( fh != -1 ) return -1; if ( sstream != NULL ) { autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF); } switch (info->codec) { case ROAR_CODEC_ALAW: ss.format = PA_SAMPLE_ALAW; break; case ROAR_CODEC_MULAW: ss.format = PA_SAMPLE_ULAW; break; case ROAR_CODEC_PCM_S_LE: switch (info->bits) { case 16: ss.format = PA_SAMPLE_S16LE; break; default: needauto = 1; break; } break; case ROAR_CODEC_PCM_S_BE: switch (info->bits) { case 16: ss.format = PA_SAMPLE_S16BE; break; default: needauto = 1; break; } break; case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_BE: case ROAR_CODEC_PCM_U_PDP: if ( info->bits == 8 ) { ss.format = PA_SAMPLE_U8; } else { needauto = 1; } break; default: needauto = 1; break; } if ( needauto ) { if ( !autoconfig ) { return -1; } info->bits = 16; info->codec = ROAR_CODEC_DEFAULT; ss.format = PA_SAMPLE_S16NE; } ss.rate = info->rate; ss.channels = info->channels; if ( (self = roar_mm_malloc(sizeof(struct driver_pulsesimple))) == NULL ) return -1; self->handle = pa_simple_new(device, "roard", dir, subdev, "RoarAudio Sound Server", &ss, NULL, NULL, &pulseerror); if ( self->handle == NULL && autoconfig ) { info->bits = 16; info->codec = ROAR_CODEC_DEFAULT; ss.format = PA_SAMPLE_S16NE; self->handle = pa_simple_new(device, "roard", dir, subdev, "RoarAudio Sound Server", &ss, NULL, NULL, &pulseerror); } if ( self->handle == NULL ) { ROAR_ERR("driver_pulsesimple_open(inst=%p, device='%s', info=%p, fh=%i, sstream=%p): can not open device: %s", inst, device, info, fh, sstream, pa_strerror(pulseerror)); roar_mm_free(self); ROAR_DBG("driver_pulsesimple_open(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = -1", inst, device, info, fh, sstream); return -1; } memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = self; inst->close = driver_pulsesimple_close; inst->write = driver_pulsesimple_write; inst->sync = driver_pulsesimple_sync; inst->ctl = driver_pulsesimple_ctl; return 0; } int driver_pulsesimple_close (struct roar_vio_calls * vio) { struct driver_pulsesimple * self = vio->inst; ROAR_DBG("driver_pulsesimple_close(vio=%p) = ?", vio); pa_simple_free(self->handle); roar_mm_free(self); return 0; } ssize_t driver_pulsesimple_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_pulsesimple * self = vio->inst; ROAR_DBG("driver_pulsesimple_write(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count); return pa_simple_write(self->handle, buf, count, NULL) == 0 ? count : -1; } int driver_pulsesimple_sync (struct roar_vio_calls * vio) { struct driver_pulsesimple * self = vio->inst; ROAR_DBG("driver_pulsesimple_sync(vio=%p) = ?", vio); return pa_simple_drain(self->handle, NULL); } int driver_pulsesimple_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct driver_pulsesimple * self = vio->inst; (void)self; ROAR_DBG("driver_pulsesimple_ctl(vio=%p) = ?", vio); switch (cmd) { case ROAR_VIO_CTL_NONBLOCK: if ( *(int*)data == ROAR_SOCKET_BLOCK ) return 0; roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; } roar_err_set(ROAR_ERROR_NOSYS); return -1; } #endif //ll roaraudio-1.0beta11/roard/driver_pwmled.c0000644000175000017500000000722512264733670016615 0ustar phiphi//driver_pwmled.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #if !defined(ROAR_WITHOUT_DCOMP_PWMLED) && !defined(ROAR_WITHOUT_VIO_DSTR) int driver_pwmled_open_vio (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct roar_vio_defaults def; struct driver_pwmled * self = roar_mm_malloc(sizeof(struct driver_pwmled)); if ( self == NULL ) return -1; if ( fh == -1 ) { if ( device == NULL ) device = "/dev/ttyS0"; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY, 0644) == -1 ) { roar_mm_free(self); return -1; } if ( roar_vio_open_dstr(&(self->vio), device, &def, 1) == -1 ) { roar_mm_free(self); return -1; } inst->inst = self; } else { /* if ( roar_vio_open_fh(inst, fh) == -1 ) return -1; */ roar_mm_free(self); return -1; } inst->read = NULL; inst->write = driver_pwmled_write; inst->lseek = NULL; inst->sync = NULL; inst->ctl = driver_pwmled_ctl; inst->close = driver_pwmled_close; info->codec = ROAR_CODEC_DMX512; if ( info->rate == g_sa->rate ) { self->rate = 9600; } else { self->rate = info->rate; } self->channel = 0; if ( roar_light_pwm_new(&(self->state), 16) == -1 ) { roar_mm_free(self); return -1; } if ( sstream != NULL ) driver_pwmled_ctl(inst, ROAR_VIO_CTL_SET_SSTREAM, sstream); return 0; } int driver_pwmled_close (struct roar_vio_calls * vio) { int ret = roar_vio_close(&(((struct driver_pwmled*)(vio->inst))->vio)); if ( vio->inst != NULL ) roar_mm_free(vio->inst); return ret; } // TODO: this function should be optimized. ssize_t driver_pwmled_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_pwmled * self; int value; if ( vio == NULL || buf == NULL ) return -1; if ( count != 512 ) return -1; self = vio->inst; value = ((unsigned char*)buf)[self->channel] / 15; if ( roar_light_pwm_set(&(self->state), value) == -1 ) return -1; // ROAR_WARN("driver_pwmled_write(*): value=%i", value); if ( value ) { // bit per word, bit per byte return roar_light_pwm_send(&(self->state), &(self->vio), self->rate/11/8/100) == 0 ? count : -1; } return count; } int driver_pwmled_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct driver_pwmled * self; if ( vio == NULL ) return -1; self = vio->inst; switch (cmd) { case ROAR_VIO_CTL_SET_SSTREAM: ROAR_STREAM(data)->dir = ROAR_DIR_LIGHT_OUT; ROAR_STREAM_SERVER(data)->codec_orgi = ROAR_CODEC_DMX512; break; case ROAR_VIO_CTL_SET_DMXSCHAN: if ( *(uint16_t*)data > 511 ) return -1; self->channel = *(uint16_t*)data; break; default: return -1; } return 0; } #endif //ll roaraudio-1.0beta11/roard/driver_roar.c0000644000175000017500000000424312264733670016265 0ustar phiphi//driver_roar.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #define MIXER_ID -1 int driver_roar_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { int dir = ROAR_DIR_PLAY; if ( fh != -1 ) { // this is a connection to a roard, no roar_simple_*() interface avalible for this case return -1; } if ( sstream != NULL ) { switch (ROAR_STREAM(sstream)->dir) { case ROAR_DIR_OUTPUT: dir = ROAR_DIR_PLAY; break; case ROAR_DIR_MIDI_OUT: dir = ROAR_DIR_MIDI_IN; break; case ROAR_DIR_LIGHT_OUT: dir = ROAR_DIR_LIGHT_IN; break; // TODO: we need to know a real pos id for raw streams... // case ROAR_DIR_RAW_OUT: dir = ROAR_DIR_RAW_IN; break; case ROAR_DIR_COMPLEX_OUT: dir = ROAR_DIR_COMPLEX_IN; break; default: return -1; } } if ( roar_vio_simple_stream(inst, info->rate, info->channels, info->bits, info->codec, device, dir, "roard", MIXER_ID) == -1 ) { if ( streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF) ) { if ( roar_profile2info(info, "default") == -1 ) return -1; if ( roar_vio_simple_stream(inst, info->rate, info->channels, info->bits, info->codec, device, dir, "roard", MIXER_ID) == -1 ) { return -1; } } return -1; } return 0; } //ll roaraudio-1.0beta11/roard/driver_rsound.c0000644000175000017500000001122012264733670016625 0ustar phiphi//driver_rsound.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #define _DRV_NEED_RSOUND_H #include "roard.h" #ifdef ROAR_HAVE_LIBRSOUND int driver_rsound_open (struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { rsound_t * self = NULL; int autoconfig = 0; int tmp, tmp2; if ( fh != -1 ) return -1; if ( ROAR_STREAM(sstream)->id != -1 ) { autoconfig = streams_get_flag(ROAR_STREAM(sstream)->id, ROAR_FLAG_AUTOCONF); } if ( rsd_init(&self) == -1 ) { ROAR_DBG("driver_rsound_open(*): rsd_init(&self) failed."); return -1; } if ( device != NULL ) { if ( rsd_set_param(self, RSD_HOST, device) == -1 ) { ROAR_DBG("driver_rsound_open(*): rsd_set_param(self, RSD_HOST, device) failed."); rsd_free(self); return -1; } } tmp = info->channels; if ( rsd_set_param(self, RSD_CHANNELS, &tmp) == -1 ) { ROAR_DBG("driver_rsound_open(*): rsd_set_param(self, RSD_CHANNELS, &tmp) failed."); rsd_free(self); return -1; } if ( tmp != info->channels ) { rsd_free(self); return -1; } tmp = info->rate; if ( rsd_set_param(self, RSD_SAMPLERATE, &tmp) == -1 ) { ROAR_DBG("driver_rsound_open(*): rsd_set_param(self, RSD_SAMPLERATE, &tmp) failed."); rsd_free(self); return -1; } if ( tmp != info->rate ) { rsd_free(self); return -1; } tmp = -1; // unknown by RSound if ( info->bits > 16 && autoconfig ) { info->bits = 32; } switch (info->codec) { case ROAR_CODEC_PCM_S_LE: switch (info->bits) { case 8: tmp = RSD_S8; break; case 16: tmp = RSD_S16_LE; break; #ifdef RSD_S32_LE case 32: tmp = RSD_S32_LE; break; #endif } break; case ROAR_CODEC_PCM_S_BE: switch (info->bits) { case 8: tmp = RSD_S8; break; case 16: tmp = RSD_S16_BE; break; #ifdef RSD_S32_BE case 32: tmp = RSD_S32_BE; break; #endif } break; case ROAR_CODEC_PCM_S_PDP: switch (info->bits) { case 8: tmp = RSD_S8; break; } break; case ROAR_CODEC_PCM_U_LE: switch (info->bits) { case 8: tmp = RSD_U8; break; case 16: tmp = RSD_U16_LE; break; #ifdef RSD_U32_LE case 32: tmp = RSD_U32_LE; break; #endif } break; case ROAR_CODEC_PCM_U_BE: switch (info->bits) { case 8: tmp = RSD_U8; break; case 16: tmp = RSD_U16_BE; break; #ifdef RSD_U32_BE case 32: tmp = RSD_U32_BE; break; #endif } break; case ROAR_CODEC_PCM_U_PDP: switch (info->bits) { case 8: tmp = RSD_U8; break; } break; } #ifdef RSD_S16_NE if ( tmp == -1 && autoconfig ) { info->bits = 16; info->codec = ROAR_CODEC_DEFAULT; tmp = RSD_S16_NE; } #endif if ( tmp == -1 ) { ROAR_DBG("driver_rsound_open(*): Codec/Bits not supported by RSound"); rsd_free(self); return -1; } tmp2 = tmp; if ( rsd_set_param(self, RSD_FORMAT, &tmp) == -1 ) { ROAR_DBG("driver_rsound_open(*): rsd_set_param(self, RSD_FORMAT, &tmp={0x%x->0x%x}) failed.", tmp2, tmp); rsd_free(self); return -1; } if ( tmp != tmp2 ) { rsd_free(self); return -1; } if ( rsd_start(self) == -1 ) { ROAR_DBG("driver_rsound_open(*): rsd_start(self) failed."); rsd_free(self); return -1; } memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = self; inst->close = driver_rsound_close; inst->write = driver_rsound_write; inst->ctl = driver_dummy_ctl; return 0; } int driver_rsound_close (struct roar_vio_calls * vio) { int r = 0; if ( rsd_stop(vio->inst) == -1 ) r = -1; if ( rsd_free(vio->inst) == -1 ) r = -1; return r; } ssize_t driver_rsound_write (struct roar_vio_calls * vio, void *buf, size_t count) { size_t ret; ret = rsd_write(vio->inst, buf, count); if ( ret == 0 ) return -1; return ret; } #endif //ll roaraudio-1.0beta11/roard/driver_shout.c0000644000175000017500000001423612264733670016467 0ustar phiphi//driver_shout.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBSHOUT struct driver_shout { shout_t * shout; int blocking; }; static int _driver_shout_usage_counter = 0; int driver_shout_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_shout * self = NULL; const char * s_server = NULL; const char * s_mount = NULL; const char * s_user = NULL; const char * s_pw = NULL; int s_port = -1; const char * s_desc = NULL; const char * s_genre = NULL; const char * s_name = NULL; const char * s_url = NULL; int s_public = 0; char * a; shout_t * shout; switch (info->codec) { case ROAR_CODEC_DEFAULT: info->codec = ROAR_CODEC_OGG_VORBIS; break; case ROAR_CODEC_OGG_VORBIS: case ROAR_CODEC_OGG_SPEEX: case ROAR_CODEC_OGG_FLAC: case ROAR_CODEC_OGG_GENERAL: // ok, no errors here break; default: ROAR_ERR("This driver only supports Ogg/* (most common is Ogg/Vorbis), current codec is %s", roar_codec2str(info->codec)); return -1; break; } if ( device != NULL ) { // device sould be an URL in this form: // [http[s]://][user[:pw]@]host[:port][/mp.ogg] if ( (a = strstr(device, "://")) != NULL ) { *a = 0; if ( strcmp(device, "http") ) { return -1; } device = a + 3; } // [user[:pw]@]host[:port][/mp.ogg] if ( (a = strstr(device, "@")) != NULL ) { *a = 0; s_user = device; device = a + 1; } if ( s_user != NULL ) { if ( (a = strstr(s_user, ":")) != NULL ) { *a = 0; s_pw = a+1; } } if ( s_user != NULL && ! *s_user ) s_user = NULL; if ( s_pw != NULL && ! *s_pw ) s_pw = NULL; // host[:port][/mp.ogg] if ( (a = strstr(device, "/")) != NULL ) { *a = 0; s_server = device; device = a + 1; } else { s_server = device; device += strlen(device); } if ( (a = strstr(s_server, ":")) != NULL ) { *a = 0; s_port = atoi(a+1); } if ( ! *s_server ) s_server = NULL; // [/mp.ogg] if ( *device ) { s_mount = device; } } ROAR_DBG("driver_shout_open_vio(*): user='%s', pw='%s', server='%s', port=%i, mount='%s'", s_user, s_pw, s_server, s_port, s_mount); if ( s_server == NULL ) s_server = "localhost"; if ( s_mount == NULL ) s_mount = "/roar.ogg"; if ( s_pw == NULL ) s_pw = "hackme"; if ( s_user == NULL ) s_user = "source"; if ( s_port == -1 ) s_port = 8000; if ( _driver_shout_usage_counter++ == 0 ) shout_init(); if (!(shout = shout_new())) { ROAR_ERR("Can not clreate shout object"); return 1; } if (shout_set_host(shout, s_server) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting hostname: %s", shout_get_error(shout)); return 1; } if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting protocol: %s", shout_get_error(shout)); return 1; } if (shout_set_port(shout, s_port) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting port: %s", shout_get_error(shout)); return 1; } if (shout_set_password(shout, s_pw) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting password: %s", shout_get_error(shout)); return 1; } if (shout_set_mount(shout, s_mount) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting mount: %s", shout_get_error(shout)); return 1; } if (shout_set_user(shout, s_user) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting user: %s", shout_get_error(shout)); return 1; } if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting format: %s", shout_get_error(shout)); return 1; } shout_set_public(shout, s_public); if (s_desc != NULL) shout_set_description(shout, s_desc); if (s_genre != NULL) shout_set_genre(shout, s_genre); if (s_name != NULL) shout_set_name(shout, s_name); if (s_url != NULL) shout_set_url(shout, s_url); if (shout_open(shout) != SHOUTERR_SUCCESS) { ROAR_ERR("Can not open connection via libshout!"); return -1; } self = roar_mm_malloc(sizeof(struct driver_shout)); if ( self == NULL ) { shout_close(shout); return -1; } memset(self, 0, sizeof(struct driver_shout)); self->shout = shout; self->blocking = ROAR_SOCKET_BLOCK; memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = (void*)self; inst->write = driver_shout_write; inst->close = driver_shout_close; inst->ctl = driver_dummy_ctl; return 0; } int driver_shout_close(struct roar_vio_calls * vio) { struct driver_shout * self = vio->inst; shout_close(self->shout); roar_mm_free(self); if ( _driver_shout_usage_counter-- == 1 ) shout_shutdown(); return 0; } ssize_t driver_shout_write(struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_shout * self = vio->inst; if (shout_send(self->shout, (unsigned char*)buf, count) != SHOUTERR_SUCCESS) return -1; if ( self->blocking == ROAR_SOCKET_BLOCK ) shout_sync(self->shout); return count; } int driver_shout_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct driver_shout * self = vio->inst; switch (cmd) { case ROAR_VIO_CTL_NONBLOCK: self->blocking = *(const int*)data; return 0; break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } } #endif //ll roaraudio-1.0beta11/roard/driver_sndio.c0000644000175000017500000001606012264733670016436 0ustar phiphi//driver_sndio.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBSNDIO int driver_sndio_init_vio(struct roar_vio_calls * vio, struct driver_sndio * inst) { if ( vio == NULL ) return -1; memset(vio, 0, sizeof(struct roar_vio_calls)); vio->flags = ROAR_VIO_FLAGS_NONE; vio->refc = 1; vio->close = driver_sndio_close_vio; vio->write = driver_sndio_write; vio->sync = driver_sndio_sync; vio->ctl = driver_sndio_ctl; vio->inst = (void*) inst; return 0; } #define _err() if ( self->shandle != NULL ) sio_close(self->shandle); \ if ( self->mhandle != NULL ) mio_close(self->mhandle); \ if ( self->device != NULL ) roar_mm_free(self->device); \ roar_mm_free(self); \ return -1 int driver_sndio_open(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_sndio * self = NULL; if ( (self = roar_mm_malloc(sizeof(struct driver_sndio))) == NULL ) { ROAR_ERR("driver_sndio_open(*): Can not roar_mm_malloc() instance data: %s", strerror(errno)); return -1; } memset(self, 0, sizeof(struct driver_sndio)); memcpy(&(self->info), info, sizeof(struct roar_audio_info)); self->ssid = -1; if ( sstream == NULL ) { self->stream = NULL; self->dir = ROAR_DIR_OUTPUT; } else { self->stream = sstream; self->dir = ROAR_STREAM(sstream)->dir; switch (self->dir) { case ROAR_DIR_OUTPUT: case ROAR_DIR_MONITOR: self->dir = ROAR_DIR_OUTPUT; break; case ROAR_DIR_MIDI_OUT: info->channels = 16; info->codec = ROAR_CODEC_MIDI; info->bits = 8; break; default: _err(); } } if ( device != NULL ) self->device = roar_mm_strdup(device); if ( driver_sndio_init_vio(inst, self) == -1 ) { ROAR_ERR("driver_sndio_open(*): Can not init vio interface"); _err(); } if ( driver_sndio_open_device(self) == -1 ) { ROAR_ERR("driver_sndio_open(*): Can not open audio device"); _err(); } ROAR_DBG("driver_sndio_open(*): sndio devices opened :)"); return 0; } #undef er int driver_sndio_close_vio (struct roar_vio_calls * vio) { struct driver_sndio * self = vio->inst; if ( self->shandle != NULL ) sio_close(self->shandle); if ( self->mhandle != NULL ) mio_close(self->mhandle); if ( self->device != NULL ) roar_mm_free(self->device); roar_mm_free(self); return 0; } int driver_sndio_open_device (struct driver_sndio * self) { ROAR_DBG("driver_sndio_open_device(*) = ?"); switch (self->dir) { case ROAR_DIR_OUTPUT: if ( (self->shandle = sio_open(self->device, SIO_PLAY, 0)) == NULL ) { ROAR_ERR("driver_sndio_open_device(*): Can not open sndio audio device"); return -1; } self->need_config = 1; break; case ROAR_DIR_MIDI_OUT: if ( (self->mhandle = mio_open(self->device, MIO_OUT, 0)) == NULL ) { ROAR_ERR("driver_sndio_open_device(*): Can not open sndio MIDI device"); return -1; } break; default: return -1; } ROAR_DBG("driver_sndio_open_device(*) = ?"); return 0; } int driver_sndio_config_device(struct driver_sndio * self) { struct sio_par par; sio_initpar(&par); par.bits = self->info.bits; par.rate = self->info.rate; par.pchan = self->info.channels; switch (self->info.codec) { case ROAR_CODEC_PCM_S_LE: par.le = 1; par.sig = 1; break; case ROAR_CODEC_PCM_S_BE: par.le = 0; par.sig = 1; break; case ROAR_CODEC_PCM_U_LE: par.le = 1; par.sig = 0; break; case ROAR_CODEC_PCM_U_BE: par.le = 0; par.sig = 0; break; default: return -1; break; } if ( sio_setpar(self->shandle, &par) == 0 ) { ROAR_ERR("driver_sndio_config_device(*): Can not set stream parameters"); return -1; } if ( sio_start(self->shandle) == 0 ) { ROAR_ERR("driver_sndio_config_device(*): Can not start stream"); return -1; } self->need_config = 0; return 0; } int driver_sndio_reopen_device(struct driver_sndio * self) { return -1; } ssize_t driver_sndio_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_sndio * self = vio->inst; ROAR_DBG("driver_sndio_write(*) = ?"); if ( self->need_config ) { if ( driver_sndio_config_device(vio->inst) == -1 ) { return -1; } } ROAR_DBG("driver_sndio_write(*) = ?"); switch (self->dir) { case ROAR_DIR_OUTPUT: return sio_write(self->shandle, buf, count); break; case ROAR_DIR_MIDI_OUT: return mio_write(self->mhandle, buf, count); break; } ROAR_WARN("driver_sndio_write(*): Driver changed direction to something not supported, this should not happen"); return -1; } int driver_sndio_sync (struct roar_vio_calls * vio) { return -1; } #define data(x) x: if ( data == NULL ) return -1; #define no_data(x) x: if ( data != NULL ) return -1; int driver_sndio_ctl (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { struct driver_sndio * self = vio->inst; unsigned d; switch (cmd) { case data(ROAR_VIO_CTL_SET_SSTREAMID) self->ssid = *(int *)data; break; case data(ROAR_VIO_CTL_SET_SSTREAM) // FIXME: we should do some better error handling here: if ( ROAR_STREAM(data)->dir != self->dir ) return -1; self->stream = data; break; case data(ROAR_VIO_CTL_GET_AUINFO) memcpy(data, &(self->info), sizeof(struct roar_audio_info)); break; case data(ROAR_VIO_CTL_SET_AUINFO) memcpy(&(self->info), data, sizeof(struct roar_audio_info)); return driver_sndio_reopen_device(self); break; case ROAR_VIO_CTL_SET_VOLUME: switch (self->info.channels) { case 1: d = ROAR_MIXER(data)->mixer[0] * SIO_MAXVOL / ROAR_MIXER(data)->scale; break; case 2: if ( ROAR_MIXER(data)->mixer[0] != ROAR_MIXER(data)->mixer[1] ) return -1; d = ROAR_MIXER(data)->mixer[0] * SIO_MAXVOL / ROAR_MIXER(data)->scale; break; default: return -1; } return sio_setvol(self->shandle, d) == 0 ? -1 : 0; break; case ROAR_VIO_CTL_NONBLOCK: if ( *(int*)data == ROAR_SOCKET_BLOCK ) return 0; roar_err_set(ROAR_ERROR_NOTSUP); return -1; break; default: return -1; break; } return 0; } #endif //ll roaraudio-1.0beta11/roard/driver_sysclock.c0000644000175000017500000000567212264733671017164 0ustar phiphi//driver_sysclock.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_DRIVER_SYSCLOCK int driver_sysclock_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_sysclock * self = roar_mm_malloc(sizeof(struct driver_sysclock)); if ( self == NULL ) return -1; if ( device != NULL ) { return -1; } memset(self, 0, sizeof(struct driver_sysclock)); memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = self; inst->close = driver_sysclock_close; inst->write = driver_sysclock_write; inst->ctl = driver_dummy_ctl; self->bps = roar_info2bitspersec(info)/8; if (!self->bps) { roar_mm_free(self); return -1; } switch (info->codec) { case ROAR_CODEC_PCM_S_LE: case ROAR_CODEC_PCM_S_BE: case ROAR_CODEC_PCM_S_PDP: case ROAR_CODEC_PCM_U_LE: case ROAR_CODEC_PCM_U_BE: case ROAR_CODEC_PCM_U_PDP: case ROAR_CODEC_ALAW: case ROAR_CODEC_MULAW: break; default: roar_mm_free(self); return -1; break; } gettimeofday(&(self->lasttime), NULL); self->last_wanted = 0; return 0; } int driver_sysclock_close (struct roar_vio_calls * vio) { struct driver_sysclock * self = vio->inst; if ( self == NULL ) return -1; roar_mm_free(self); return 0; } ssize_t driver_sysclock_write (struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_sysclock * self = vio->inst; struct timeval now; long long diff = (1000000LL * count / (long long)self->bps); long long ago; gettimeofday(&now, NULL); ago = now.tv_usec - self->lasttime.tv_usec; ago += 1000000*(now.tv_sec - self->lasttime.tv_sec); ago -= self->last_wanted; memcpy(&(self->lasttime), &now, sizeof(now)); ROAR_DBG("driver_sysclock_write(*): count=%u, bps=%u, diff=%llu, ago=%llu", count, self->bps, diff, ago); diff -= ago; self->last_wanted = diff; ROAR_DBG("driver_sysclock_write(*): diff=%lli", diff); if ( diff > 0 ) roar_usleep(diff); return count; } #endif //ll roaraudio-1.0beta11/roard/driver_wmm.c0000644000175000017500000002127612264733671016130 0ustar phiphi//driver_wmm.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_HAVE_LIBWINMM static int _alloc_wave_headers(struct driver_wmm * self) { int bytesPerBlock = self->wavefmt.nBlockAlign * self->splPerBlock; /* int bytes = internal->blocks * (sizeof(WAVEHDR) + bytesPerBlock); */ int bytes = self->blocks * (sizeof(*self->wh) + bytesPerBlock); int res; MMRESULT mmres; self->bigbuffer = roar_mm_malloc(bytes); if (self->bigbuffer != NULL) { int i; BYTE * b; memset(self->bigbuffer,0,bytes); self->wh = self->bigbuffer; self->spl = (LPBYTE) (self->wh+self->blocks); for (i=0, b=self->spl; iblocks; ++i, b+=bytesPerBlock) { self->wh[i].data = b; self->wh[i].wh.lpData = self->wh[i].data; self->wh[i].length = bytesPerBlock; self->wh[i].wh.dwBufferLength = self->wh[i].length; self->wh[i].wh.dwUser = (DWORD_PTR)self; mmres = waveOutPrepareHeader(self->hwo, &self->wh[i].wh,sizeof(WAVEHDR)); if (MMSYSERR_NOERROR != mmres) { break; } } if (iblocks) { while (--i >= 0) { waveOutUnprepareHeader(self->hwo, &self->wh[i].wh,sizeof(WAVEHDR)); } roar_mm_free(self->bigbuffer); self->wh = 0; self->spl = 0; self->bigbuffer = 0; } else { /* all ok ! */ } } res = (self->bigbuffer != NULL); return res; } static int _get_free_block(struct driver_wmm * self); static int _wait_wave_headers(struct driver_wmm * self, int wait_all) { int res = 1; while (self->sent_blocks > 0) { int n; _get_free_block(self); n = self->sent_blocks; if (n > 0) { unsigned int ms = (self->msPerBlock>>1)+1; if (wait_all) ms *= n; Sleep(ms); } } res &= !self->sent_blocks; return res; } static int _get_free_block(struct driver_wmm * self) { const int idx = self->widx; int ridx = self->ridx; while (self->wh[ridx].sent && !!(self->wh[ridx].wh.dwFlags & WHDR_DONE)) { /* block successfully sent to hardware, release it */ /*debug("_ao_get_free_block: release block %d\n",ridx);*/ self->wh[ridx].sent = 0; self->wh[ridx].wh.dwFlags &= ~WHDR_DONE; --self->full_blocks; if (self->full_blocks<0) { self->full_blocks = 0; } --self->sent_blocks; if (self->sent_blocks<0) { self->sent_blocks = 0; } if (++ridx >= self->blocks) ridx = 0; } self->ridx = ridx; return self->wh[idx].sent ? -1 : idx; } static int _free_wave_headers(struct driver_wmm * self) { MMRESULT mmres; int res = 1; if (self->wh) { int i; /* Reset so we dont need to wait ... Just a satefy net * since _ao_wait_wave_headers() has been called once before. */ mmres = waveOutReset(self->hwo); /* Wait again to be sure reseted waveheaders has been released. */ _wait_wave_headers(self, 0); for (i=self->blocks; --i>=0; ) { mmres = waveOutUnprepareHeader(self->hwo, &self->wh[i].wh,sizeof(WAVEHDR)); res &= mmres == MMSYSERR_NOERROR; } self->wh = 0; self->spl = 0; } return res; } /* Send a block to audio hardware */ static int _send_block(struct driver_wmm * self, const int idx) { MMRESULT mmres; /* Satanity checks */ if (self->wh[idx].sent) { return 0; } if (!!(self->wh[idx].wh.dwFlags & WHDR_DONE)) { return 0; } /* count <= 0, just pretend it's been sent */ if (self->wh[idx].count <= 0) { self->wh[idx].sent = 2; /* set with 2 so we can track these special cases */ self->wh[idx].wh.dwFlags |= WHDR_DONE; ++self->sent_blocks; return 1; } self->wh[idx].wh.dwBufferLength = self->wh[idx].count; self->wh[idx].count = 0; mmres = waveOutWrite(self->hwo, &self->wh[idx].wh, sizeof(WAVEHDR)); self->wh[idx].sent = (mmres == MMSYSERR_NOERROR); /*&& !(internal->wh[idx].wh.dwFlags & WHDR_DONE);*/ self->sent_blocks += self->wh[idx].sent; return mmres == MMSYSERR_NOERROR; } int driver_wmm_open_vio(struct roar_vio_calls * inst, char * device, struct roar_audio_info * info, int fh, struct roar_stream_server * sstream) { struct driver_wmm * self; MMRESULT mmres; if ( (self = roar_mm_malloc(sizeof(struct driver_wmm))) == NULL ) return -1; memset(self, 0, sizeof(struct driver_wmm)); // VIO Setup: memset(inst, 0, sizeof(struct roar_vio_calls)); inst->flags = ROAR_VIO_FLAGS_NONE; inst->refc = 1; inst->inst = self; inst->close = driver_wmm_close_vio; inst->write = driver_wmm_write; inst->ctl = driver_dummy_ctl; info->codec = ROAR_CODEC_PCM_S_LE; self->wavefmt.wFormatTag = WAVE_FORMAT_PCM; self->wavefmt.nChannels = info->channels; self->wavefmt.wBitsPerSample = info->bits; self->wavefmt.nSamplesPerSec = info->rate; self->wavefmt.nBlockAlign = (self->wavefmt.wBitsPerSample>>3)*self->wavefmt.nChannels; self->wavefmt.nAvgBytesPerSec = self->wavefmt.nSamplesPerSec*self->wavefmt.nBlockAlign; self->wavefmt.cbSize = 0; /* $$$ later this should be optionnal parms */ self->id = WAVE_MAPPER; self->blocks = 64; self->splPerBlock = 512; self->msPerBlock = (self->splPerBlock * 1000 + info->rate - 1) / info->rate; mmres = waveOutOpen(&(self->hwo), self->id, &(self->wavefmt), (DWORD_PTR)0/* waveOutProc */, (DWORD_PTR)self, CALLBACK_NULL/* |WAVE_FORMAT_DIRECT */|WAVE_ALLOWSYNC); if ( mmres != MMSYSERR_NOERROR ) { driver_wmm_close_vio(inst); return -1; } // FIXME: do error checking waveOutGetID(self->hwo, &(self->id)); _alloc_wave_headers(self); self->opened = 1; ROAR_DBG("driver_wmm_open_vio(*) = 0"); return 0; } int driver_wmm_close_vio(struct roar_vio_calls * vio) { struct driver_wmm * self; if ( vio == NULL ) return -1; if ( (self = vio->inst) == NULL ) return -1; if ( self->opened ) { _wait_wave_headers(self, 1); _free_wave_headers(self); waveOutClose(self->hwo); } roar_mm_free(self); ROAR_DBG("driver_wmm_close_vio(*) = 0"); return 0; } ssize_t driver_wmm_write(struct roar_vio_calls * vio, void *buf, size_t count) { struct driver_wmm * self; ssize_t ret_ok = count; int ret = 1; ROAR_DBG("driver_wmm_write(vio=%p, buf=%p, count=%lu) = ?", vio, buf, (unsigned long)count); if ( vio == NULL ) return -1; if ( (self = vio->inst) == NULL ) return -1; if ( ! self->opened ) return -1; while(ret && count > 0) { int n; const int idx = _get_free_block(self); if (idx == -1) { /* debug("sleep %dms, rem %d bytes\n",internal->msPerBlock,num_bytes); */ Sleep(self->msPerBlock); continue; } /* Get free bytes in the block */ n = self->wh[idx].wh.dwBufferLength - self->wh[idx].count; /* debug("free in block %d : %d/%d\n", */ /* idx,n,internal->wh[idx].dwBufferLength); */ /* Get amount to copy */ if (n > (int)count) { n = count; } /* debug("copy = %d\n",n); */ /* Do copy */ CopyMemory((char*)self->wh[idx].wh.lpData + self->wh[idx].count, buf, n); /* Updates pointers and counters */ buf += n; count -= n; /* debug("rem = %d\n",num_bytes); */ self->wh[idx].count += n; /* Is this block full ? */ if (self->wh[idx].count == self->wh[idx].wh.dwBufferLength) { ++self->full_blocks; /* debug("blocks %d full, total:%d\n",internal->widx,internal->full_blocks); */ if (++self->widx == self->blocks) { self->widx = 0; } ret = _send_block(self, idx); } } ROAR_DBG("driver_wmm_write(vio=%p, buf=%p, count=%lu): ret=%i", vio, buf, (unsigned long)count, ret); /* debug("ao_wmm_play => %d rem => [%s]\n",num_bytes,ret?"success":"error"); */ return ret > -1 ? ret_ok : -1; } #endif //ll roaraudio-1.0beta11/roard/empty.c0000644000175000017500000000166212264733671015110 0ustar phiphi//*.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2013-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" //ll roaraudio-1.0beta11/roard/emul_rsound.c0000644000175000017500000001721212264733672016305 0ustar phiphi//emul_rsound.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND static int emul_rsound_lastcon = -1; int emul_rsound_new_client (int client, int data); int emul_rsound_on_connect (int fh, struct roard_listen * lsock) { int oldfh = emul_rsound_lastcon; int client; union { int32_t i[4]; char c[16]; } buf; (void)lsock; // TODO: add error handling roar_socket_nonblock(fh, ROAR_SOCKET_NONBLOCK); if ( emul_rsound_lastcon == -1 ) { emul_rsound_lastcon = fh; return -2; } else { emul_rsound_lastcon = -1; client = clients_new(); if ( client == -1 ) return -1; if ( clients_set_fh(client, fh) == -1 ) { ROAR_ERR("net_get_new_client(void): Can not set client's fh"); clients_delete(client); close(oldfh); close(fh); ROAR_DBG("net_get_new_client(void) = -1"); return -1; } if ( emul_rsound_new_client(client, oldfh) == -1 ) { clients_delete(client); return -1; } // LATENCY: // we currently don't know what we need to set here. buf.i[0] = ROAR_HOST2NET32(0); // block size used by roard. buf.i[1] = ROAR_HOST2NET32(ROAR_OUTPUT_BUFFER_SAMPLES * roar_info2framesize(g_sa) / 8); // Magic zeros to enable protocol handling. // (RSD_CONN_PROTO) buf.i[2] = ROAR_HOST2NET32(0); buf.i[3] = ROAR_HOST2NET32(0); if ( ROAR_NETWORK_WRITE(oldfh, buf.c, sizeof(buf.c)) != sizeof(buf.c) ) { clients_delete(client); return -1; } return client; } return -1; } int emul_rsound_new_client (int client, int data) { struct roar_stream_server * ss; struct roar_stream * s; struct roar_client * c; int stream; if ( clients_get(client, &c) == -1 ) { return -1; } if ((stream = streams_new()) == -1 ) { clients_delete(client); return -1; } if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); clients_delete(client); return -1; } s = ROAR_STREAM(ss); if ( client_stream_add(client, stream) == -1 ) { streams_delete(stream); clients_delete(client); return -1; } memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); ss->codec_orgi = s->info.codec = ROAR_CODEC_RIFF_WAVE; if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) { clients_delete(client); return -1; } /* if ( client_stream_exec(client, stream) == -1 ) { clients_delete(client); return -1; } */ if ( client_stream_set_fh(client, stream, data) == -1 ) { streams_delete(stream); clients_delete(client); return -1; } return 0; } int emul_rsound_vrecv_msg(struct emul_rsound_msg * msg, struct roar_vio_calls * vio) { struct roar_vio_select select; struct roar_vio_selecttv tv = { .sec = 0, .nsec = 0 }; ssize_t ret; int num; if ( msg == NULL || vio == NULL ) return -1; ROAR_VIO_SELECT_SETVIO(&select, vio, ROAR_VIO_SELECT_READ); if ( roar_vio_select(&select, 1, &tv, NULL) == -1 ) return -1; if ( !(select.eventsa & ROAR_VIO_SELECT_READ) ) { errno = EAGAIN; return -1; } ret = roar_vio_read(vio, msg->header, EMUL_RSOUND_MSG_HEADER_LEN); if ( ret != EMUL_RSOUND_MSG_HEADER_LEN ) return -1; msg->header[ret] = 0; if ( msg->header[0] != 'R' || msg->header[1] != 'S' || msg->header[2] != 'D' ) return -1; if ( sscanf(&(msg->header[3]), "%5d", &num) != 1 ) return -1; if ( num > EMUL_RSOUND_MSG_DATA_LEN ) return -1; msg->datalen = num; ret = roar_vio_read(vio, msg->data, num); if ( ret != (ssize_t)num ) return -1; msg->data[num] = 0; msg->datasp = msg->data; msg->dataslen = msg->datalen; for (num = 0; msg->data[num] == ' '; num++) { msg->datasp++; msg->dataslen--; } return 0; } int emul_rsound_vsend_msg(struct emul_rsound_msg * msg, struct roar_vio_calls * vio) { struct roar_vio_select select; struct roar_vio_selecttv tv = { .sec = 0, .nsec = 0 }; ssize_t ret; if ( msg == NULL || vio == NULL ) return -1; ROAR_VIO_SELECT_SETVIO(&select, vio, ROAR_VIO_SELECT_WRITE); if ( roar_vio_select(&select, 1, &tv, NULL) == -1 ) return -1; if ( !(select.eventsa & ROAR_VIO_SELECT_WRITE) ) { errno = EAGAIN; return -1; } snprintf(msg->header, EMUL_RSOUND_MSG_HEADER_LEN+1, "RSD%5d", (int)msg->datalen); ret = roar_vio_write(vio, msg->header, EMUL_RSOUND_MSG_HEADER_LEN); if ( ret != EMUL_RSOUND_MSG_HEADER_LEN ) return -1; ret = roar_vio_write(vio, msg->data, msg->datalen); if ( ret != (ssize_t)msg->datalen ) return -1; return 0; } int emul_rsound_check_client(int client, struct roar_vio_calls * vio) { struct roar_vio_calls rvio; struct emul_rsound_msg msg; struct roar_client * c; struct roar_stream_server * ss; int streamid; int i; ssize_t ptr; size_t max_len; if ( vio == NULL ) { vio = &rvio; roar_vio_open_fh_socket(vio, clients_get_fh(client)); } // we get called in a loop, in case this fails no problem, just // return -1, caller will delete us in case of real error. if ( emul_rsound_vrecv_msg(&msg, vio) == -1 ) return -1; if ( !strncmp(msg.datasp, "INFO", 4) ) { if ( clients_get(client, &c) == -1 ) return clients_delete(client); streamid = -1; for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) if ( c->streams[i] > streamid ) streamid = c->streams[i]; if ( streamid == -1 ) return clients_delete(client); if ( streams_get(streamid, &ss) == -1 ) return clients_delete(client); ptr = roar_info2samplesize(&(ROAR_STREAM(ss)->info)); if ( ptr == -1 ) return clients_delete(client); ptr *= ROAR_STREAM(ss)->pos; ptr /= 8; // bits -> bytes i = snprintf(msg.data+msg.datalen, EMUL_RSOUND_MSG_DATA_LEN - msg.datalen, " %" LIBROAR__ll "d", (LIBROAR__longlong int)ptr); msg.datalen += i; return emul_rsound_vsend_msg(&msg, vio); } else if ( !strncmp(msg.datasp, "NULL", 4) ) { // NULL is simular to NOOP } else if ( !strncmp(msg.datasp, "STOP", 4) ) { // This is quit. return clients_delete(client); } else if ( !strncmp(msg.datasp, "IDENTITY ", 9) ) { if ( msg.dataslen < (8+1+1) ) return clients_delete(client); msg.datasp += 9; msg.dataslen -= 9; if ( clients_get(client, &c) == -1 ) return clients_delete(client); max_len = msg.dataslen < (ROAR_BUFFER_NAME-1) ? msg.dataslen : (ROAR_BUFFER_NAME-1); strncpy(c->name, msg.datasp, max_len); c->name[max_len] = 0; } else if ( !strncmp(msg.datasp, "CLOSECTL", 9) ) { if ( clients_get(client, &c) == -1 ) return clients_delete(client); strncpy(msg.data, " CLOSECTL OK", EMUL_RSOUND_MSG_DATA_LEN); msg.datalen = 12; //strlen(" CLOSECTL OK"); if ( emul_rsound_vsend_msg(&msg, vio) == -1 ) return clients_delete(client); streamid = c->streams[0]; if ( client_stream_exec(client, streamid) == -1 ) return clients_delete(client); return 0; } else { // Unknown command, kill the client. return clients_delete(client); } return 0; } #endif //ll roaraudio-1.0beta11/roard/emul_simple.c0000644000175000017500000000356712264733672016274 0ustar phiphi//emul_simple.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE int emul_simple_on_connect (int client, struct roard_listen * lsock) { struct roar_stream_server * ss; struct roar_stream * s; struct roar_client * c; int stream; if ( clients_get(client, &c) == -1 ) { return -1; } if ((stream = streams_new()) == -1 ) { clients_delete(client); return -1; } if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); clients_delete(client); return -1; } s = ROAR_STREAM(ss); if ( client_stream_add(client, stream) == -1 ) { streams_delete(stream); clients_delete(client); return -1; } memcpy(&(s->info), &(lsock->inst.stpl.info), sizeof(struct roar_audio_info)); ss->codec_orgi = s->info.codec; if ( streams_set_dir(stream, lsock->inst.stpl.dir, 1) == -1 ) { clients_delete(client); return -1; } if ( client_stream_exec(client, stream) == -1 ) { clients_delete(client); return -1; } return 0; } #endif //ll roaraudio-1.0beta11/roard/hwmixer.c0000644000175000017500000002040212264733672015427 0ustar phiphi//hwmixer.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_MIXER #define FLAG_NONE 0x0000 #define FLAG_FHSEC 0x0001 struct hwmixer { const char * name; const char * desc; const char * devs; int flags; int (*open)(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen); int (*close)(struct hwmixer_stream * stream); int (*set_vol)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings); int (*get_vol)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings); }; static int __true (void) { return 0; } struct hwmixer g_hwmixers[] = { #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) {"oss", "OSS Mixer", "/dev/mixer*", FLAG_FHSEC, hwmixer_oss_open, hwmixer_oss_close, hwmixer_oss_set_vol, hwmixer_oss_get_vol}, #endif {"dstr", "Write to DSTR", "/some/file", FLAG_FHSEC, hwmixer_dstr_open, hwmixer_dstr_close, hwmixer_dstr_set_vol, NULL}, {"null", "Null Mixer", NULL, FLAG_NONE, (int (*)(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen))__true, (int (*)(struct hwmixer_stream * stream))__true, (int (*)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings))__true, (int (*)(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings))__true}, {NULL, NULL, NULL, FLAG_NONE, NULL, NULL, NULL, NULL} }; void print_hwmixerlist (void) { struct hwmixer * mixer; int i; printf(" Source Flag Subsys - Description (devices)\n"); printf("------------------------------------------------------\n"); for (i = 0; (mixer = &(g_hwmixers[i]))->name != NULL; i++) { printf(" %-9s %c Mixer - %s (devices: %s)\n", mixer->name, mixer->flags & FLAG_FHSEC ? 's' : ' ', mixer->desc, mixer->devs == NULL ? "(none)" : mixer->devs ); } } void hwmixer_setup_info(struct hwmixer_stream * mstream) { struct roar_stream_server * ss; streams_get(mstream->stream, &ss); memset(&(ROAR_STREAM(ss)->info), 0, sizeof(ROAR_STREAM(ss)->info)); streams_set_dir(mstream->stream, ROAR_DIR_MIXING, 1); streams_set_flag(mstream->stream, ROAR_FLAG_HWMIXER); } int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) { struct roar_stream_server * ss; struct roar_keyval * subnamekv = NULL; struct hwmixer * mixer = NULL; struct hwmixer_stream * stream; ssize_t subnamekvlen = 0; int i; int ret; for (i = 0; g_hwmixers[i].name != NULL; i++) { if ( !strcmp(g_hwmixers[i].name, drv) ) { mixer = &(g_hwmixers[i]); break; } } if ( mixer == NULL ) { ROAR_WARN("hwmixer_open(basestream=%i, drv='%s', dev='%s', fh=%i, basename='%s', subnames='%s'): Driver not found.", basestream, drv, dev, fh, basename, subnames); return -1; } if ( mixer->open == NULL ) { return -1; } if ( fh != -1 && !(mixer->flags & FLAG_FHSEC) ) { return -1; } stream = roar_mm_malloc(sizeof(struct hwmixer_stream)); if ( stream == NULL ) return -1; memset(stream, 0, sizeof(struct hwmixer_stream)); stream->hwmixer = mixer; stream->basestream = basestream; stream->stream = basestream; stream->baseud = NULL; stream->ud = NULL; if ( basename == NULL ) { streams_set_name(basestream, "Hardware Mixer"); } else { streams_set_name(basestream, basename); } hwmixer_setup_info(stream); if ( subnames != NULL ) { subnamekvlen = roar_keyval_split(&subnamekv, subnames, ",;", NULL, 1); } ret = mixer->open(stream, drv, dev, fh, basename, subnamekv, subnamekvlen); if ( subnamekv != NULL ) roar_mm_free(subnamekv); if ( ret == -1 ) { roar_mm_free(stream); return -1; } streams_set_mixerstream(basestream, stream); // try to get in sync with HW mixer. // if possible read hw mixer state. // if not possible write to force a sync value. if ( streams_get(basestream, &ss) == 0 ) { if ( mixer->get_vol != NULL ) { hwmixer_get_volume(basestream, ss, stream, &(ss->mixer)); } else { hwmixer_set_volume(basestream, ss, stream, &(ss->mixer)); } } return 0; } int hwmixer_close(int stream) { struct hwmixer_stream * mstream = streams_get_mixerstream(stream); if ( mstream == NULL ) return 0; if ( mstream->hwmixer->close != NULL ) mstream->hwmixer->close(mstream); roar_mm_free(mstream); return 0; } int hwmixer_set_volume(int id, struct roar_stream_server * ss, struct hwmixer_stream * mstream, struct roar_mixer_settings * settings) { if ( mstream->hwmixer->set_vol != NULL ) return mstream->hwmixer->set_vol(mstream, ROAR_STREAM(ss)->info.channels, HWMIXER_MODE_SET, settings); return 0; } int hwmixer_get_volume(int id, struct roar_stream_server * ss, struct hwmixer_stream * mstream, struct roar_mixer_settings * settings) { if ( mstream->hwmixer->get_vol != NULL ) return mstream->hwmixer->get_vol(mstream, ROAR_STREAM(ss)->info.channels, HWMIXER_MODE_ASK, settings); return 0; } struct hwmixer_stream * hwmixer_substream_new(struct hwmixer_stream * parent) { struct roar_stream_server * ss; struct hwmixer_stream * stream; int id; ROAR_DBG("hwmixer_substream_new(parent=%p) = ?", parent); if ( parent == NULL ) return NULL; ROAR_DBG("hwmixer_substream_new(parent=%p) = ?", parent); stream = roar_mm_malloc(sizeof(struct hwmixer_stream)); if ( stream == NULL ) return NULL; ROAR_DBG("hwmixer_substream_new(parent=%p) = ?", parent); if ( (id = streams_new_virtual(parent->basestream, &ss)) == -1 ) { roar_mm_free(stream); return NULL; } memset(stream, 0, sizeof(struct hwmixer_stream)); stream->hwmixer = parent->hwmixer; stream->basestream = parent->basestream; stream->stream = id; stream->baseud = parent->baseud; stream->ud = NULL; hwmixer_setup_info(stream); streams_set_mixerstream(id, stream); ROAR_DBG("hwmixer_substream_new(parent=%p) = %p", parent, stream); return stream; } int hwmixer_add (char * drv, char * dev, char * opts, int prim, int count) { char * basename = NULL; char * subnames = NULL; char * k, * v; int basestream = streams_new(); int ret; int error = 0; char * strtok_store; //int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) { if ( basestream == -1 ) return -1; client_stream_add(g_self_client, basestream); if ( opts == NULL ) { k = NULL; } else { k = roar_mm_strtok_r(opts, ",", &strtok_store); } while (k != NULL) { // ROAR_WARN("add_output(*): opts: %s", k); if ( (v = strstr(k, "=")) != NULL ) { *v++ = 0; } if ( strcmp(k, "primary") == 0 ) { prim = 1; } else if ( strcmp(k, "name") == 0 ) { basename = v; } else if ( strcmp(k, "subs") == 0 ) { subnames = v; } else if ( strcmp(k, "autoconf") == 0 ) { streams_set_flag(basestream, ROAR_FLAG_AUTOCONF); } else if ( strcmp(k, "passmixer") == 0 ) { streams_set_flag(basestream, ROAR_FLAG_PASSMIXER); } else { ROAR_ERR("add_hwmixer(*): unknown option '%s'", k); error++; } if ( error ) { streams_delete(basestream); if ( prim ) alive = 0; return -1; } k = roar_mm_strtok_r(NULL, ",", &strtok_store); } if ( prim ) { streams_mark_primary(basestream); } ret = hwmixer_open(basestream, drv, dev, -1, basename, subnames); if ( ret == -1 ) { streams_delete(basestream); } return ret == -1 ? -1 : 0; } #endif //ll roaraudio-1.0beta11/roard/hwmixer_dstr.c0000644000175000017500000000725312264733672016474 0ustar phiphi//hwmixer_dstr.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_MIXER /* * This driver ignores errors on seeks: * The writes ensure that if the seek back to begin of file * does not work the records keep seperate and parsable. * So it basically enters some kind of streaming mode. */ //#define TEST_HWMIXER_SUBSTREAMS int hwmixer_dstr_open(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen) { struct roar_vio_calls * vio = roar_mm_malloc(sizeof(struct roar_vio_calls)); struct roar_vio_defaults def; struct roar_stream_server * ss; if ( vio == NULL ) return -1; if ( fh == -1 ) { if ( dev == NULL ) { roar_mm_free(vio); return -1; } if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY|O_CREAT|O_TRUNC, 0644) == -1 ) { roar_mm_free(vio); return -1; } if ( roar_vio_open_dstr(vio, dev, &def, 1) == -1 ) { roar_mm_free(vio); return -1; } } else { if ( roar_vio_open_fh(vio, fh) == -1 ) { roar_mm_free(vio); return -1; } } stream->baseud = vio; roar_vio_printf(vio, "No data yet.\n"); _LIBROAR_IGNORE_RET(roar_vio_lseek(vio, 0, SEEK_SET)); roar_vio_sync(vio); if (streams_get(stream->basestream, &ss) != -1) { ROAR_STREAM(ss)->info.channels = 2; } else { ROAR_WARN("hwmixer_dstr_open(*): can not get object for basestream %i", stream->basestream); } #ifdef TEST_HWMIXER_SUBSTREAMS stream = hwmixer_substream_new(stream); if ( stream == NULL ) { ROAR_WARN("hwmixer_dstr_open(*): can not create substream"); } else { if (streams_get(stream->stream, &ss) != -1) { ROAR_STREAM(ss)->info.channels = 2; } else { ROAR_WARN("hwmixer_dstr_open(*): can not get object for stream %i", stream->stream); } } #endif return 0; } int hwmixer_dstr_close(struct hwmixer_stream * stream) { // are we a substream? if yes we do not clean up anything. // streams_delete() will do all our work. if ( stream->stream != stream->basestream ) return 0; roar_vio_close(stream->baseud); roar_mm_free(stream->baseud); return 0; } int hwmixer_dstr_set_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings) { struct roar_vio_calls * vio = stream->baseud; int i; roar_vio_printf(vio, "[Stream %2i of basestream %2i]\n", stream->stream, stream->basestream); roar_vio_printf(vio, "Channels: %2i\n", channels); roar_vio_printf(vio, "Mode: %1i\n", mode); roar_vio_printf(vio, "Scale: %5i\n", (int)settings->scale); roar_vio_printf(vio, "RPG: %5i/%5i\n", (int)settings->rpg_mul, (int)settings->rpg_div); for (i = 0; i < channels; i++) { roar_vio_printf(vio, "Channel[%2i]: %5i\n", i, (int)settings->mixer[i]); } _LIBROAR_IGNORE_RET(roar_vio_lseek(vio, 0, SEEK_SET)); roar_vio_sync(vio); return 0; } #endif //ll roaraudio-1.0beta11/roard/hwmixer_oss.c0000644000175000017500000002367112264733672016326 0ustar phiphi//hwmixer_oss.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_MIXER #if defined(ROAR_HAVE_OSS_BSD) || defined(ROAR_HAVE_OSS) #define OSS_VOLUME_SCALE 100 struct subdev { int bit; int channels; long long int cmd_read, cmd_write; }; static struct subdev_map { const char * name; struct subdev subdev; } g_subdevs[] = { {"Volume", {.bit = SOUND_MASK_VOLUME, .cmd_read = SOUND_MIXER_READ_VOLUME, .cmd_write = SOUND_MIXER_WRITE_VOLUME }}, {"Bass", {.bit = SOUND_MASK_BASS, .cmd_read = SOUND_MIXER_READ_BASS, .cmd_write = SOUND_MIXER_WRITE_BASS }}, {"Treble", {.bit = SOUND_MASK_TREBLE, .cmd_read = SOUND_MIXER_READ_TREBLE, .cmd_write = SOUND_MIXER_WRITE_TREBLE }}, {"Synth", {.bit = SOUND_MASK_SYNTH, .cmd_read = SOUND_MIXER_READ_SYNTH, .cmd_write = SOUND_MIXER_WRITE_SYNTH }}, {"PCM", {.bit = SOUND_MASK_PCM, .cmd_read = SOUND_MIXER_READ_PCM, .cmd_write = SOUND_MIXER_WRITE_PCM }}, {"Speaker", {.bit = SOUND_MASK_SPEAKER, .cmd_read = SOUND_MIXER_READ_SPEAKER, .cmd_write = SOUND_MIXER_WRITE_SPEAKER }}, {"Line", {.bit = SOUND_MASK_LINE, .cmd_read = SOUND_MIXER_READ_LINE, .cmd_write = SOUND_MIXER_WRITE_LINE }}, {"Mic", {.bit = SOUND_MASK_MIC, .cmd_read = SOUND_MIXER_READ_MIC, .cmd_write = SOUND_MIXER_WRITE_MIC }}, {"CD", {.bit = SOUND_MASK_CD, .cmd_read = SOUND_MIXER_READ_CD, .cmd_write = SOUND_MIXER_WRITE_CD }}, {"Imix", {.bit = SOUND_MASK_IMIX, .cmd_read = SOUND_MIXER_READ_IMIX, .cmd_write = SOUND_MIXER_WRITE_IMIX }}, {"AltPCM", {.bit = SOUND_MASK_ALTPCM, .cmd_read = SOUND_MIXER_READ_ALTPCM, .cmd_write = SOUND_MIXER_WRITE_ALTPCM }}, {"Reclev", {.bit = SOUND_MASK_RECLEV, .cmd_read = SOUND_MIXER_READ_RECLEV, .cmd_write = SOUND_MIXER_WRITE_RECLEV }}, {"IGain", {.bit = SOUND_MASK_IGAIN, .cmd_read = SOUND_MIXER_READ_IGAIN, .cmd_write = SOUND_MIXER_WRITE_IGAIN }}, {"OGain", {.bit = SOUND_MASK_OGAIN, .cmd_read = SOUND_MIXER_READ_OGAIN, .cmd_write = SOUND_MIXER_WRITE_OGAIN }}, {"Line1", {.bit = SOUND_MASK_LINE1, .cmd_read = SOUND_MIXER_READ_LINE1, .cmd_write = SOUND_MIXER_WRITE_LINE1 }}, {"Line2", {.bit = SOUND_MASK_LINE2, .cmd_read = SOUND_MIXER_READ_LINE2, .cmd_write = SOUND_MIXER_WRITE_LINE2 }}, {"Line3", {.bit = SOUND_MASK_LINE3, .cmd_read = SOUND_MIXER_READ_LINE3, .cmd_write = SOUND_MIXER_WRITE_LINE3 }}, /* {"Digital1", {.bit = SOUND_MASK_DIGITAL1, .cmd_read = SOUND_MIXER_READ_DIGITAL1, .cmd_write = SOUND_MIXER_WRITE_DIGITAL1}}, {"Digital2", {.bit = SOUND_MASK_DIGITAL2, .cmd_read = SOUND_MIXER_READ_DIGITAL2, .cmd_write = SOUND_MIXER_WRITE_DIGITAL2}}, {"Digital3", {.bit = SOUND_MASK_DIGITAL3, .cmd_read = SOUND_MIXER_READ_DIGITAL3, .cmd_write = SOUND_MIXER_WRITE_DIGITAL3}}, {"PhoneIn", {.bit = SOUND_MASK_PHONEIN, .cmd_read = SOUND_MIXER_READ_PHONEIN, .cmd_write = SOUND_MIXER_WRITE_PHONEIN }}, {"PhoneOut", {.bit = SOUND_MASK_PHONEOUT, .cmd_read = SOUND_MIXER_READ_PHONEOUT, .cmd_write = SOUND_MIXER_WRITE_PHONEOUT}}, {"Radio", {.bit = SOUND_MASK_RADIO, .cmd_read = SOUND_MIXER_READ_RADIO, .cmd_write = SOUND_MIXER_WRITE_RADIO }}, {"Video", {.bit = SOUND_MASK_VIDEO, .cmd_read = SOUND_MIXER_READ_VIDEO, .cmd_write = SOUND_MIXER_WRITE_VIDEO }}, {"Monitor", {.bit = SOUND_MASK_MONITOR, .cmd_read = SOUND_MIXER_READ_MONITOR, .cmd_write = SOUND_MIXER_WRITE_MONITOR }}, */ // Alias with better name: {"Master", {.bit = SOUND_MASK_VOLUME, .cmd_read = SOUND_MIXER_READ_VOLUME, .cmd_write = SOUND_MIXER_WRITE_VOLUME }}, {"PCM2", {.bit = SOUND_MASK_ALTPCM, .cmd_read = SOUND_MIXER_READ_ALTPCM, .cmd_write = SOUND_MIXER_WRITE_ALTPCM }}, {NULL} }; static int hwmixer_oss_open_stream(struct hwmixer_stream * stream, int devmask, int sdevmask, char * basename, struct roar_keyval * subname) { struct subdev * subdev; struct subdev * source_subdev = NULL; struct roar_stream_server * ss; const char * reqname = subname->value; int i; char name[80]; for (i = 0; g_subdevs[i].name != NULL; i++) { if ( !strcasecmp(subname->key, g_subdevs[i].name) ) { source_subdev = &(g_subdevs[i].subdev); if ( reqname == NULL ) reqname = g_subdevs[i].name; break; } } if ( source_subdev == NULL ) return -1; if ( !(devmask & source_subdev->bit) ) return -1; subdev = roar_mm_malloc(sizeof(struct subdev)); if ( subdev == NULL ) return -1; memcpy(subdev, source_subdev, sizeof(struct subdev)); subdev->channels = sdevmask & subdev->bit ? 2 : 1; stream->ud = subdev; if ( basename == NULL ) { streams_set_name(stream->stream, (char*)reqname); } else { snprintf(name, sizeof(name)-1, "%s/%s", basename, reqname); name[sizeof(name)-1] = 0; streams_set_name(stream->stream, name); } if (streams_get(stream->stream, &ss) != -1) { ROAR_STREAM(ss)->info.channels = subdev->channels; } else { ROAR_WARN("hwmixer_dstr_open(*): can not get object for stream %i", stream->stream); } return 0; } int hwmixer_oss_open(struct hwmixer_stream * stream, char * drv, char * dev, int fh, char * basename, struct roar_keyval * subnames, size_t subnamelen) { struct roar_vio_calls * vio = roar_mm_malloc(sizeof(struct roar_vio_calls)); struct roar_vio_defaults def; struct roar_vio_sysio_ioctl ctl; struct roar_keyval kv; struct hwmixer_stream * cstream; int devmask, sdevmask; mixer_info info; size_t i; if ( vio == NULL ) { return -1; } if ( fh == -1 ) { #ifdef ROAR_DEFAULT_OSS_MIX_DEV if ( dev == NULL ) { dev = ROAR_DEFAULT_OSS_MIX_DEV; } #endif if ( dev == NULL ) { roar_mm_free(vio); return -1; } if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_FILE, O_RDWR, 0644) == -1 ) { roar_mm_free(vio); return -1; } if ( roar_vio_open_dstr(vio, dev, &def, 1) == -1 ) { roar_mm_free(vio); return -1; } } else { if ( roar_vio_open_fh(vio, fh) == -1 ) { roar_mm_free(vio); return -1; } } stream->baseud = vio; ctl.cmd = SOUND_MIXER_READ_DEVMASK; ctl.argp = &devmask; if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) { roar_vio_close(vio); roar_mm_free(vio); return -1; } ctl.cmd = SOUND_MIXER_READ_STEREODEVS; ctl.argp = &sdevmask; if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) { sdevmask = 0; } if ( basename == NULL ) { ctl.cmd = SOUND_MIXER_INFO; ctl.argp = &info; if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == 0 ) { basename = info.name; } } if ( subnamelen == 0 ) { kv.key = "Master"; kv.value = NULL; if ( hwmixer_oss_open_stream(stream, devmask, sdevmask, basename, &kv) == -1 ) { roar_vio_close(vio); roar_mm_free(vio); return -1; } } else { if ( hwmixer_oss_open_stream(stream, devmask, sdevmask, basename, subnames) == -1 ) { roar_vio_close(vio); roar_mm_free(vio); return -1; } for (i = 1; i < subnamelen; i++) { cstream = hwmixer_substream_new(stream); if ( hwmixer_oss_open_stream(cstream, devmask, sdevmask, basename, &(subnames[i])) == -1 ) { roar_vio_close(vio); roar_mm_free(vio); return -1; } } } #ifdef TEST_HWMIXER_SUBSTREAMS stream = hwmixer_substream_new(stream); if ( stream == NULL ) { ROAR_WARN("hwmixer_dstr_open(*): can not create substream"); } else { if (streams_get(stream->stream, &ss) != -1) { ROAR_STREAM(ss)->info.channels = 2; } else { ROAR_WARN("hwmixer_dstr_open(*): can not get object for stream %i", stream->stream); } } #endif return 0; } int hwmixer_oss_close(struct hwmixer_stream * stream) { // are we a substream? if yes we do not clean up anything. // streams_delete() will do all our work. roar_mm_free(stream->ud); if ( stream->stream != stream->basestream ) return 0; roar_vio_close(stream->baseud); roar_mm_free(stream->baseud); return 0; } int hwmixer_oss_set_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings) { struct roar_vio_calls * vio = stream->baseud; struct roar_vio_sysio_ioctl ctl; struct subdev * subdev = stream->ud; int i; int l, r; if ( channels == 0 ) return 0; if ( channels == 1 ) { l = r = settings->mixer[0]; } else { l = settings->mixer[0]; r = settings->mixer[1]; } if ( subdev->channels == 1 ) { l = r = (l + r) / 2; } l = (l * OSS_VOLUME_SCALE) / settings->scale; r = (r * OSS_VOLUME_SCALE) / settings->scale; i = (l & 0xFF) | ((r & 0xFF) << 8); ctl.cmd = subdev->cmd_write; ctl.argp = &i; return roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl); } int hwmixer_oss_get_vol(struct hwmixer_stream * stream, int channels, int mode, struct roar_mixer_settings * settings) { struct roar_vio_calls * vio = stream->baseud; struct roar_vio_sysio_ioctl ctl; struct subdev * subdev = stream->ud; int i; int l, r; ctl.cmd = subdev->cmd_read; ctl.argp = &i; if ( roar_vio_ctl(vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl) == -1 ) return -1; l = i & 0xFF; r = (i >> 8) & 0xFF; if ( subdev->channels == 1 ) r = l; settings->scale = OSS_VOLUME_SCALE; if ( channels == 1 ) { settings->mixer[0] = (l + r) / 2; } else if ( channels == 2 ) { settings->mixer[0] = l; settings->mixer[1] = r; } else { return -1; } return 0; } #endif #endif //ll roaraudio-1.0beta11/roard/lib.c0000644000175000017500000000530212264733673014515 0ustar phiphi//lib.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" int lib_run_bg(const char * cmd, const int infh, const int outfh, const int errfh, int * closefh, const size_t lenclose) { #ifdef ROAR_HAVE_FORK pid_t child; int fh[3] = {-1, -1, -1}; size_t i; ROAR_WARN("lib_run_bg(cmd='%s', ...): This function should never be called. Contact devels.", cmd); child = roar_fork(NULL); if ( child == -1 ) { ROAR_ERR("lib_run_bg(*): Can not fork: %s", strerror(errno)); return -1; } if ( child ) { // we are the parent! return child; } // we are the child. // first stop the watchdog. roar_watchdog_stop(); // then we need to close a lot of open files! // before we do this we need to keep backups of our handles: fh[0] = dup(infh); fh[1] = dup(outfh); fh[2] = dup(errfh); // TODO: test for errors here. #ifdef ROAR_SUPPORT_LISTEN for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) if ( g_listen[i].used ) roar_vio_close(&(g_listen[i].sock)); // listen socket. #endif // this breaks the new driver interface // clients_free(); // delete all clients!, this allso delets all streams #ifndef ROAR_WITHOUT_DCOMP_MIDI midi_free(); // close midi devices #endif // close fh's we got ask to close: #ifdef ROAR_HAVE_IO_POSIX for (i = 0; i < lenclose; i++) close(closefh[i]); #else if ( lenclose ) { ROAR_WARN("lib_run_bg(*): lenclose > 0 and no way known to close fds"); } #endif // next we need to remap our stdio: // stdio: fh 0..2 for (i = 0; i < 3; i++) { #ifdef ROAR_HAVE_IO_POSIX close(i); #endif dup2(fh[i], i); // todo test if this is ok. close(fh[i]); } // OK, now we should have set up all our fh properbly, exec our command: execl("/bin/sh", "sh", "-c", cmd, (char*)NULL); // still alive? BAD! ROAR_ERR("lib_run_bg(*): We are still alive! BAD!"); ROAR_U_EXIT(3); return -1; #else return -1; #endif } //ll roaraudio-1.0beta11/roard/light.c0000644000175000017500000001552512264733673015066 0ustar phiphi//light.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_LIGHT // declared 'extern' struct light_state g_light_state; struct light_mixer g_light_mixer; // // static inline void __set_channel(size_t index, uint8_t val) { g_light_state.changes[index] |= g_light_state.state[index] ^ val; g_light_state.state[index] = val; } int light_init (uint32_t channels) { struct roar_stream_server * ss; int i; g_light_state.channels = 0; if ( channels == 0 || channels > ((uint32_t)512UL*(uint32_t)512UL) ) /* unrealstic values */ return -1; if ( (g_light_state.state = roar_mm_malloc(channels)) == NULL ) { return -1; } if ( (g_light_state.changes = roar_mm_malloc(channels)) == NULL ) { roar_mm_free(g_light_state.state); return -1; } g_light_state.channels = channels; if ( (g_light_mixer.stream = add_mixer(ROAR_SUBSYS_LIGHT, _MIXER_NAME("Light Control"), &ss)) == -1 ) { roar_mm_free(g_light_state.state); return -1; } ROAR_STREAM(ss)->info.codec = ROAR_CODEC_DMX512; ROAR_STREAM(ss)->info.bits = ROAR_LIGHT_BITS; ROAR_STREAM(ss)->info.rate = ROAR_OUTPUT_CFREQ; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL ) { if ( streams_get_subsys(i) == ROAR_SUBSYS_LIGHT ) { streams_set_mixer_stream(i, g_light_mixer.stream); } } } return light_reset(); } int light_free (void) { if ( g_light_state.state != NULL ) { roar_mm_free(g_light_state.state); } if ( g_light_state.changes != NULL ) { roar_mm_free(g_light_state.changes); } g_light_state.channels = 0; return 0; } int light_reset (void) { if ( g_light_state.channels == 0 ) return 0; if ( g_light_state.state == NULL ) return -1; if ( g_light_state.changes == NULL ) return -1; memset(g_light_state.state, 0, g_light_state.channels); memset(g_light_state.changes, 0, g_light_state.channels); memset(g_light_state.events, 0, sizeof(g_light_state.events)); g_light_state.eventsqueuelen = 0; return 0; } int light_reinit(void) { if ( g_light_state.changes == NULL ) return -1; memset(g_light_state.changes, 0, g_light_state.channels); memset(g_light_state.events, 0, sizeof(g_light_state.events)); g_light_state.eventsqueuelen = 0; return 0; } int light_update(void) { return 0; } int light_check_stream (int id) { struct roar_stream * s; struct roar_stream_server * ss; char buf[512]; int i; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("light_check_stream(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); switch (s->info.codec) { case ROAR_CODEC_DMX512: if ( stream_vio_s_read(ss, buf, 512) != 512 ) { streams_delete(id); return -1; } for (i = 0; i < (g_light_state.channels < 512 ? g_light_state.channels : 512); i++) { __set_channel(i, buf[i]); } // memcpy(g_light_state.state, buf, g_light_state.channels < 512 ? g_light_state.channels : 512); s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, 1); return 0; break; case ROAR_CODEC_ROARDMX: ROAR_DBG("light_check_stream(id=%i): Codec: RoarDMX", id); if ( cf_light_roardmx_read(id, ss) == -1 ) { streams_delete(id); // simply drop the client on error. return -1; } break; default: streams_delete(id); return -1; } return 0; } static inline int light_send_stream_dmx512 (int id, struct roar_stream * s, struct roar_stream_server * ss) { size_t chans = g_light_state.channels; uint8_t buf[512]; register uint8_t * bufptr; if ( chans > 512 ) chans = 512; if ( chans == 512 ) { bufptr = g_light_state.state; } else { memset(buf, 0, 512); memcpy(buf, g_light_state.state, chans); bufptr = buf; } if ( stream_vio_s_write(ss, bufptr, 512) != 512 ) { streams_delete(id); return -1; } s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, 1); return 0; } int light_send_stream (int id) { struct roar_stream * s; struct roar_stream_server * ss; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("light_send_stream(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); switch (s->info.codec) { case ROAR_CODEC_DMX512: return light_send_stream_dmx512(id, s, ss); break; case ROAR_CODEC_ROARDMX: return cf_light_roardmx_write(id, ss); break; default: streams_delete(id); return -1; } return 0; } int light_dmxchannel_get(size_t index) { if ( (size_t)g_light_state.channels <= index ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } return (int)(unsigned int)(uint8_t)g_light_state.state[index]; } int light_dmxchannel_set(size_t index, uint8_t val) { if ( (size_t)g_light_state.channels <= index ) { roar_err_set(ROAR_ERROR_NOENT); return -1; } __set_channel(index, val); return 0; } ssize_t light_dmxchannel_num(void) { if ( g_light_state.state == NULL ) { roar_err_set(ROAR_ERROR_BADSTATE); return -1; } return g_light_state.channels; } int light_dmxchannel_swap_universe(uint8_t * universe, size_t len) { uint8_t c; size_t i; if ( g_light_state.state == NULL ) { roar_err_set(ROAR_ERROR_BADSTATE); return -1; } if ( g_light_state.channels != len ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } for (i = 0; i < len; i++) { c = g_light_state.state[i]; __set_channel(i, universe[i]); universe[i] = c; } return 0; } int light_dmxevent_add(const uint8_t * events, size_t len) { size_t i; if ( events == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( len > (sizeof(g_light_state.events) - g_light_state.eventsqueuelen) ) { roar_err_set(ROAR_ERROR_NOSPC); return -1; } for (i = 0; i < len; i++) { g_light_state.events[g_light_state.eventsqueuelen++] = events[i]; roar_notify_core_emit_simple(ROAR_DATA_DMX512_EVENT, -1, g_light_mixer.stream, ROAR_OT_STREAM, events[i], -1, NULL, -1); } return 0; } int light_dmxevent_read(const uint8_t ** events, size_t * len) { if ( events == NULL || len == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } *events = g_light_state.events; *len = g_light_state.eventsqueuelen; return 0; } #endif //ll roaraudio-1.0beta11/roard/loop.c0000644000175000017500000001160312264733673014721 0ustar phiphi//loop.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" int main_loop (struct roar_audio_info * sa, int sysclocksync) { void ** streams_input = NULL; int term = 0; int streams; #ifdef ROAR_HAVE_GETTIMEOFDAY long int loopc = 0; struct timeval try, ans; float freq; #endif #ifdef ROAR_SUPPORT_LISTEN int i; int have_listen; #endif #ifdef MONITOR_LATENCY long int ans_1last = 0, ans_2last = 0, ans_3last = 0; printf("\n\e[s"); fflush(stdout); #endif ROAR_DBG("main_loop(*) = ?"); // alive = 1; g_pos = 0; #ifdef ROAR_HAVE_GETTIMEOFDAY if ( sysclocksync ) { gettimeofday(&try, NULL); } #endif while (alive) { #if defined(MONITOR_LATENCY) && defined(ROAR_HAVE_GETTIMEOFDAY) gettimeofday(&try, NULL); #endif ROAR_DBG("main_loop(*): looping..."); roar_watchdog_trigger(); #ifdef ROAR_SUPPORT_LISTEN have_listen = 0; for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) { if ( g_listen[i].used ) { have_listen = 1; break; } } if ( have_listen ) { ROAR_DBG("main_loop(*): check for new clients..."); net_check_listen(); } #endif ROAR_DBG("main_loop(*): check for new data..."); #ifdef ROAR_SUPPORT_LISTEN if ( clients_check_all() == 0 && g_terminate && !have_listen ) { #else if ( clients_check_all() == 0 && g_terminate ) { #endif term = 1; } #ifndef ROAR_WITHOUT_DCOMP_MIDI ROAR_DBG("main_loop(*): updating midi subsystem..."); midi_update(); #endif if ( waveform_update_inputs() == -1 ) alive = 0; ROAR_DBG("main_loop(*): mixing clients..."); if ( g_standby ) { // while in standby we still neet to get the buffers to free input buffer space. streams = streams_get_mixbuffers(&streams_input, sa, g_pos); } else { if ( ( streams = streams_get_mixbuffers(&streams_input, sa, g_pos)) != -1 ) { roar_mix_pcm(g_output_buffer, sa->bits, streams_input, ROAR_OUTPUT_BUFFER_SAMPLES * sa->channels); } } if ( term && streams < 1 ) alive = 0; if ( waveform_update_mixer() == -1 ) alive = 0; /* // while in standby we still need to write out our buffer to not run in an endless loop without // a break */ if ( plugins_update() == -1 ) alive = 0; ROAR_DBG("main_loop(*): sending output data..."); #ifdef ROAR_HAVE_USLEEP if ( g_standby || (streams < 1 && g_autostandby) ) { roar_usleep(((uint_least32_t)1000000 * ROAR_OUTPUT_BUFFER_SAMPLES) / sa->rate); ROAR_DBG("usleep(%u) = ?\n", (1000000 * ROAR_OUTPUT_BUFFER_SAMPLES) / sa->rate); } else { #endif clients_send_filter(sa); // streams_send_filter_all(); // this currently results in deadlocks. clients_send_mon(sa); #ifdef ROAR_HAVE_USLEEP } #endif #ifndef ROAR_WITHOUT_DCOMP_MIDI midi_reinit(); #endif #ifndef ROAR_WITHOUT_DCOMP_SSYNTH ssynth_update(); #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT light_reinit(); #endif // output_buffer_reinit(); g_pos = ROAR_MATH_OVERFLOW_ADD(g_pos, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels); ROAR_DBG("main_loop(*): current pos: %u", g_pos); #if defined(MONITOR_LATENCY) && defined(ROAR_HAVE_GETTIMEOFDAY) gettimeofday(&ans, NULL); while (ans.tv_sec > try.tv_sec) { ans.tv_sec--; ans.tv_usec += 1000000; } ans.tv_usec -= try.tv_usec; if ( loopc % 128 ) { printf("\e[ucurrent latency: %.3fms average: %.3fms ", ans.tv_usec / (double)1000, (ans.tv_usec+ans_3last+ans_2last+ans_1last)/ (double)4000); fflush(stdout); } ans_3last = ans_2last; ans_2last = ans_1last; ans_1last = ans.tv_usec; #endif #ifdef ROAR_HAVE_GETTIMEOFDAY if ( sysclocksync && !(loopc % sysclocksync) ) { gettimeofday(&ans, NULL); while (ans.tv_sec > try.tv_sec) { ans.tv_sec--; ans.tv_usec += 1000000; } ans.tv_usec -= try.tv_usec; freq = (sysclocksync * ROAR_OUTPUT_BUFFER_SAMPLES) / (ans.tv_usec / 1e6); printf("SYNC: f_conf=%iHz, f_real=%.2fHz diff=%+.3f%%\n", sa->rate, freq, 100*(freq/sa->rate - 1)); // memcpy(&try, &ans, sizeof(try)); gettimeofday(&try, NULL); } if ( sysclocksync ) loopc++; #endif } return -1; } //ll roaraudio-1.0beta11/roard/memlock.c0000644000175000017500000001136612264733673015405 0ustar phiphi//memlock.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #define MAX_SEGMENTS 16 struct memlock { int level; void * addr; size_t len; }; static struct memlock memlock_table[MAX_SEGMENTS]; static volatile int memlock_table_inited = 0; static void memlock_table_init (void) { if ( memlock_table_inited ) return; memset(memlock_table, 0, sizeof(memlock_table)); memlock_table_inited = 1; memlock_register(MEMLOCK_MEDIUM, memlock_table, sizeof(memlock_table)); memlock_register(MEMLOCK_MEDIUM, g_clients, sizeof(g_clients)); memlock_register(MEMLOCK_MEDIUM, g_streams, sizeof(g_streams)); memlock_register(MEMLOCK_HIGH, g_listen, sizeof(g_listen)); memlock_register(MEMLOCK_HIGH, &g_counters, sizeof(g_counters)); } int memlock_register(int level, void * addr, size_t len) { int i; if ( !memlock_table_inited ) memlock_table_init(); for (i = 0; i < MAX_SEGMENTS; i++) { if ( memlock_table[i].addr == NULL ) { memlock_table[i].level = level; memlock_table[i].addr = addr; memlock_table[i].len = len; return 0; } } return -1; } static inline int memlock_lock(struct memlock * seg) { return roar_mm_mlock(seg->addr, seg->len); } static inline int memlock_unlock(struct memlock * seg) { return roar_mm_munlock(seg->addr, seg->len); } int memlock_str2level(const char * str) { if ( str == NULL ) return -1; if ( !strcasecmp(str, "none") ) { return MEMLOCK_NONE; } else if ( !strcasecmp(str, "low") ) { return MEMLOCK_LOW; } else if ( !strcasecmp(str, "medium") ) { return MEMLOCK_MEDIUM; } else if ( !strcasecmp(str, "high") ) { return MEMLOCK_HIGH; } else if ( !strcasecmp(str, "nearlyall") ) { return MEMLOCK_NEARLYALL; } else if ( !strcasecmp(str, "nearlyallsys") ) { return MEMLOCK_NEARLYALLSYS; } else if ( !strcasecmp(str, "allcur") ) { return MEMLOCK_ALLCUR; } else if ( !strcasecmp(str, "all") ) { return MEMLOCK_ALL; } else if ( !strcasecmp(str, "default") ) { return MEMLOCK_DEFAULT; } else { return -1; } } int memlock_set_level(int level) { static int old_level = MEMLOCK_NONE; int i; int ret = 0; ROAR_DBG("memlock_set_level(level=%i) = ?", level); ROAR_DBG("memlock_set_level(level=%i): ask for locking level change: %i->%i", level, old_level, level); if ( !memlock_table_inited ) memlock_table_init(); if ( level == old_level ) { ROAR_DBG("memlock_set_level(level=%i) = 0 // old and new level are the same, nothing to do", level); return 0; } // TODO: fix those #ifdefs and replace them with more general tests if ( level == MEMLOCK_ALL ) { #ifdef ROAR_HAVE_MLOCKALL // if we do not have ROAR_HAVE_MLOCKALL we do not have MCL_* flags. // we just try to lock all known segments as fallback. old_level = MEMLOCK_ALL; return roar_mm_mlockall(MCL_CURRENT|MCL_FUTURE); #endif } else if ( level == MEMLOCK_ALLCUR ) { #ifdef ROAR_HAVE_MLOCKALL old_level = MEMLOCK_ALLCUR; return roar_mm_mlockall(MCL_CURRENT); #endif } else if ( old_level == MEMLOCK_ALL || old_level == MEMLOCK_ALLCUR ) { #ifdef ROAR_HAVE_MUNLOCKALL ret = roar_mm_munlockall(); // after roar_mm_munlockall() we need to re-lock all segemnts of target locking level. i = old_level; old_level = MEMLOCK_NONE; return memlock_set_level(i); #endif } for (i = 0; i < MAX_SEGMENTS; i++) { if ( memlock_table[i].addr != NULL ) { ROAR_DBG("memlock_set_level(level=%i): found registerd segment %i at %p with %llu Byte length", level, i, memlock_table[i].addr, (unsigned long long int)memlock_table[i].len); if ( level > old_level ) { if ( memlock_table[i].level > old_level && memlock_table[i].level <= level ) if ( memlock_lock(&(memlock_table[i])) == -1 ) ret = -1; } else { if ( memlock_table[i].level <= old_level && memlock_table[i].level > level ) if ( memlock_unlock(&(memlock_table[i])) == -1 ) ret = -1; } } } old_level = level; ROAR_DBG("memlock_set_level(level=%i) = %i", level, ret); return ret; } //ll roaraudio-1.0beta11/roard/meta.c0000644000175000017500000001434412264733674014704 0ustar phiphi//meta.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_SUPPORT_META int stream_meta_set (int id, int type, const char * name, const char * val) { int i; struct roar_stream_server * s = g_streams[id]; roar_notify_core_emit_simple(ROAR_OE_STREAM_META_UPDATE, -1, id, ROAR_OT_STREAM, ROAR_META_MODE_SET, -1, NULL, 0); if ( s == NULL ) return -1; for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) if ( s->meta[i].type == type ) { s->meta[i].type = ROAR_META_TYPE_NONE; if ( s->meta[i].value != NULL ) roar_mm_free(s->meta[i].value); s->meta[i].value = NULL; } return stream_meta_add(id, type, name, val); } int stream_meta_add (int id, int type, const char * name, const char * val) { int i; char * c; struct roar_stream_server * s = g_streams[id]; roar_notify_core_emit_simple(ROAR_OE_STREAM_META_UPDATE, -1, id, ROAR_OT_STREAM, ROAR_META_MODE_ADD, -1, NULL, 0); if ( s == NULL ) return -1; for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) { if ( s->meta[i].type == ROAR_META_TYPE_NONE ) { s->meta[i].type = type; if ( name == NULL ) { s->meta[i].key[0] = 0; } else { strncpy(s->meta[i].key, name, ROAR_META_MAX_NAMELEN); } if ( (c = strdup(val)) == NULL ) { s->meta[i].type = ROAR_META_TYPE_NONE; s->meta[i].key[0] = 0; return -1; } s->meta[i].value = c; ROAR_DBG("stream_meta_add(id=%i, type=%i, name='%s', val='%s') = 0", id, type, name, val); return 0; } } return -1; } int stream_meta_get (int id, int type, const char * name, char * val, size_t len) { size_t i; size_t vallen; struct roar_stream_server * s = g_streams[id]; if ( s == NULL ) return -1; for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) { if ( s->meta[i].type == type ) { if ( name != NULL ) if ( strncmp(s->meta[i].key, name, ROAR_META_MAX_NAMELEN) != 0 ) continue; if ( s->meta[i].value == NULL ) return -1; if ( (vallen = strlen(s->meta[i].value)) > (len - 1) ) { ROAR_DBG("stream_meta_get(*): val too small: need %i have %i", vallen, len); return -1; } strncpy(val, s->meta[i].value, vallen); val[vallen] = 0; return 0; } } return -1; } int stream_meta_list (int id, int * types, size_t len) { int i, j; int have = 0; int found; struct roar_stream_server * s = g_streams[id]; if ( s == NULL ) return -1; if ( len < ROAR_META_MAX_PER_STREAM ) // TODO: find a way we do not need this return -1; types[0] = -1; for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) { found = 0; for (j = 0; j < have; j++) if ( types[j] == s->meta[i].type ) { found = 1; break; } if ( !found ) types[have++] = s->meta[i].type; } return have; } int stream_meta_clear (int id) { int i; struct roar_stream_server * s = NULL; if ( id < 0 || id > ROAR_STREAMS_MAX ) { ROAR_ERR("stream_meta_clear(id=%i): Can not clear meta data on stream: invalid stream ID", id); return -1; } roar_notify_core_emit_simple(ROAR_OE_STREAM_META_UPDATE, -1, id, ROAR_OT_STREAM, ROAR_META_MODE_CLEAR, -1, NULL, 0); s = g_streams[id]; if ( s == NULL ) return -1; for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) { s->meta[i].type = ROAR_META_TYPE_NONE; if ( s->meta[i].value ) roar_mm_free(s->meta[i].value); s->meta[i].value = NULL; s->meta[i].key[0] = 0; } return 0; } int stream_meta_finalize(int id) { register int dir; register int co, ci, i; struct roar_stream_server * s; roar_notify_core_emit_simple(ROAR_OE_STREAM_META_UPDATE, -1, id, ROAR_OT_STREAM, ROAR_META_MODE_FINALIZE, -1, NULL, 0); if ( streams_get_flag(id, ROAR_FLAG_META) != 1 ) // ignore non meta streams return 0; dir = ROAR_STREAM(g_streams[id])->dir; if ( dir != ROAR_DIR_PLAY && dir != ROAR_DIR_META && // ignore on non input streams dir != ROAR_DIR_FILTER && dir != ROAR_DIR_BIDIR && dir != ROAR_DIR_RECPLAY ) return 0; ROAR_DBG("stream_meta_finalize(id=%i) = ?", id); for (co = 0; co < ROAR_STREAMS_MAX; co++) { if ( g_streams[co] == NULL ) continue; dir = ROAR_STREAM(g_streams[co])->dir; if ( dir != ROAR_DIR_MONITOR && dir != ROAR_DIR_FILTER && dir != ROAR_DIR_META && dir != ROAR_DIR_BIDIR && dir != ROAR_DIR_OUTPUT ) continue; if ( streams_get_flag(co, ROAR_FLAG_META) != 1 ) continue; ROAR_DBG("stream_meta_finalize(id=%i): found output stream: id=%i", id, co); stream_meta_clear(co); for (ci = 0; ci < ROAR_STREAMS_MAX; ci++) { if ( g_streams[ci] == NULL ) continue; dir = ROAR_STREAM(g_streams[ci])->dir; if ( dir != ROAR_DIR_PLAY && dir != ROAR_DIR_META && dir != ROAR_DIR_FILTER && dir != ROAR_DIR_BIDIR ) continue; if ( streams_get_flag(ci, ROAR_FLAG_META) != 1 ) continue; ROAR_DBG("stream_meta_finalize(id=%i): found input stream: id=%i", id, ci); // ok, next we copy the date of ci to co: s = g_streams[ci]; for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) { if ( s->meta[i].type == ROAR_META_TYPE_NONE ) continue; ROAR_DBG("stream_meta_finalize(id=%i): found meta data, copy: %i->%i", id, ci, co); stream_meta_add(co, s->meta[i].type, s->meta[i].key, s->meta[i].value); // ignore errors } } // ask the codec filter to update meta data: ROAR_DBG("stream_meta_finalize(id=%i): Asking stream %i to update meta data", id, co); streams_ctl(co, ROAR_CODECFILTER_CTL_META_UPDATE, NULL); // ignore errors... } return 0; } #endif //ll roaraudio-1.0beta11/roard/midi.c0000644000175000017500000005670612264733674014710 0ustar phiphi//midi.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_MIDI // declared 'extern' struct midi_config midi_config; struct midi_state_mess g_midi_mess; #ifndef ROAR_WITHOUT_DCOMP_CB struct midi_state_cb g_midi_cb; #endif struct midi_clock g_midi_clock; struct midi_mixer g_midi_mixer; // // #if defined(ROAR_HAVE_IO_POSIX) && !defined(ROAR_TARGET_WIN32) #define _HAVE_CONSOLE #endif int midi_init_config(void) { midi_config.init = 1; midi_config.inited = 0; #ifndef ROAR_WITHOUT_DCOMP_CB midi_config.init_cb = 0; midi_config.console_dev = NULL; #endif return 0; } int midi_init (void) { struct roar_stream_server * ss; char cmap[16]; int i; midi_config.inited = 0; if ( midi_config.init ) { #ifndef ROAR_WITHOUT_DCOMP_CB if ( midi_config.init_cb ) { if ( midi_cb_init() == -1 ) { ROAR_WARN("Can not initialize MIDI subsystem component CB"); } } else { g_midi_cb.console = -1; } #endif if ( midi_clock_init() == -1 ) { ROAR_WARN("Can not initialize MIDI subsystem component clock"); } } g_midi_mess.buf = NULL; if ( (g_midi_mixer.stream = add_mixer(ROAR_SUBSYS_MIDI, _MIXER_NAME("MIDI"), &ss)) == -1 ) { ROAR_WARN("Can not create MIDI mixer"); } roardsp_chanlist_init(cmap, 16, ROARDSP_CHANLIST_MAP_MIDI); streams_set_map(g_midi_mixer.stream, cmap, 16); ss->state = ROAR_STREAMSTATE_OLD; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL ) { if ( streams_get_subsys(i) == ROAR_SUBSYS_MIDI ) { streams_set_mixer_stream(i, g_midi_mixer.stream); } } } midi_config.inited |= MIDI_INITED_MAIN; return 0; } int midi_free (void) { if ( midi_reinit() == -1 ) return -1; #ifndef ROAR_WITHOUT_DCOMP_CB if ( midi_cb_free() == -1 ) return -1; #endif return 0; } int midi_update(void) { if ( g_midi_clock.stream != -1 ) midi_check_bridge(g_midi_clock.stream); #ifndef ROAR_WITHOUT_DCOMP_SSYNTH midi_conv_mes2ssynth(); #endif #ifndef ROAR_WITHOUT_DCOMP_CB return midi_cb_update(); #else return 0; #endif } int midi_reinit(void) { if ( g_midi_mess.buf != NULL ) roar_buffer_free(g_midi_mess.buf); g_midi_mess.buf = NULL; return 0; } // STREAMS: int midi_check_stream (int id) { struct roar_stream * s; struct roar_stream_server * ss; struct roar_buffer * b; void * buf; ssize_t len; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("midi_check_stream(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); if ( s->dir == ROAR_DIR_BRIDGE ) return midi_check_bridge(id); switch (s->info.codec) { case ROAR_CODEC_MIDI: break; default: streams_delete(id); return -1; } if ( roar_buffer_new_data(&b, MIDI_READ_SIZE, &buf) == -1 ) { ROAR_ERR("midi_check_stream(id=%i): Can not alloc buffer space!", id); ROAR_DBG("midi_check_stream(id=%i) = -1", id); return -1; } if ( (len = stream_vio_s_read(ss, buf, MIDI_READ_SIZE)) < 1 ) { streams_delete(id); roar_buffer_free(b); return -1; } if ( roar_buffer_set_len(b, len) == -1 ) { ROAR_WARN("midi_check_stream(id=%i): Can not set buffer size. BAD.", id); roar_buffer_free(b); streams_delete(id); return -1; } if ( stream_add_buffer(id, &b) == -1 ) { roar_buffer_free(b); streams_delete(id); return -1; } switch (s->info.codec) { case ROAR_CODEC_MIDI: return midi_conv_midi2mes(id); break; default: streams_delete(id); return -1; } ROAR_DBG("midi_check_stream(id=%i) = 0", id); return 0; } int midi_send_stream (int id) { struct roar_stream * s; struct roar_stream_server * ss; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("midi_send_stream(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); switch (s->info.codec) { case ROAR_CODEC_MIDI: return midi_conv_mes2midi(id); break; default: streams_delete(id); return -1; } return 0; } #if 1 static int _cache_to_mes(struct midi_message * mes, unsigned char * data, size_t len, int id, struct roar_stream_server * ss) { unsigned char type = *data; ROAR_DBG("_cache_to_mes(*): type=0x%.2X", (unsigned int)type); if (type == MIDI_TYPE_CLOCK_TICK || type == MIDI_TYPE_CLOCK_START || type == MIDI_TYPE_CLOCK_STOP ) { if ( len != 1 ) return -1; mes->type = type; if ( type == MIDI_TYPE_CLOCK_TICK ) { // TODO: ROAR_STREAM(ss)->pos = ROAR_MATH_OVERFLOW_ADD(ROAR_STREAM(ss)->pos, 1); } } else { mes->type = type & 0xF0; mes->channel = type & 0x0F; switch (mes->type) { case MIDI_TYPE_NOTE_ON: case MIDI_TYPE_NOTE_OFF: if ( len != 3 ) return -1; roar_midi_note_from_midiid(&(mes->d.note), data[1]); // if velocity is zero we have a NOTE OFF event if ( data[2] == 0 ) mes->type = MIDI_TYPE_NOTE_OFF; case MIDI_TYPE_PA: case MIDI_TYPE_CONTROLER: mes->kk = data[1]; mes->vv = data[2]; break; case MIDI_TYPE_PROGRAM: case MIDI_TYPE_MA: if ( len != 2 ) return -1; mes->vv = data[1]; break; case MIDI_TYPE_PB: case MIDI_TYPE_SYSEX: ROAR_WARN("_cache_to_mes(id=%i): Message of Type 0x%.2X (PB or SysEx) not yet supported", id, (unsigned int)type); return -1; break; } } switch (mes->type) { case MIDI_TYPE_CONTROLER: switch (mes->kk) { case MIDI_CCE_MAIN_VOL: if ( (516U * (unsigned int)mes->vv) > 65100 ) { // max volume ss->mixer.mixer[mes->channel] = 65535; } else { ss->mixer.mixer[mes->channel] = 516 * mes->vv; } break; } break; } ROAR_DBG("_cache_to_mes(*) = 0"); return 0; } int midi_conv_midi2mes (int id) { struct roar_stream * s; struct roar_stream_server * ss; size_t have; void * bufdata; unsigned char * data; unsigned char cache[3]; size_t cachepos = 0; int sync = 1; struct roar_buffer * buf = NULL; struct midi_message * mes = NULL; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("midi_conv_midi2mes(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); while (ss->buffer != NULL) { if ( roar_buffer_get_len(ss->buffer, &have) == -1 ) return -1; if ( roar_buffer_get_data(ss->buffer, &bufdata) == -1 ) return -1; data = bufdata; while (have) { if ( !sync ) { if ( *data & 0x80 ) { cachepos = 0; sync = 1; } else { data++; have--; continue; } } if ( (*data & 0x80) && cachepos != 0 ) { // submit cache. if ( midi_new_bufmes(&buf, &mes) == -1 ) { // this is bad. // TODO: handle better. return -1; } if ( _cache_to_mes(mes, cache, cachepos, id, ss) == -1 ) { ROAR_WARN("midi_conv_midi2mes(id=%i): Message can not be parsed.", id); roar_buffer_free(buf); } else { midi_add_buf(id, &buf); // FIXME: don't we need error handling here? } cachepos = 0; } else if ( cachepos == sizeof(cache) ) { // lost sync. sync = 0; continue; } ROAR_DBG("midi_conv_midi2mes(id=%i): cache[%u] = 0x%.2X", id, (unsigned int)cachepos, (unsigned int)*data); cache[cachepos++] = *data; data++; have--; } if ( roar_buffer_next(&(ss->buffer)) == -1 ) { ROAR_WARN("midi_conv_midi2mes(id=%i): Can not move to next buffer segment. BAD.", id); break; } } if ( cachepos ) { if ( midi_new_bufmes(&buf, &mes) == -1 ) { // this is bad. // TODO: handle better. return -1; } if ( _cache_to_mes(mes, cache, cachepos, id, ss) == -1 ) { roar_buffer_free(buf); } else { midi_add_buf(id, &buf); // FIXME: don't we need error handling here? cachepos = 0; } } if ( cachepos ) { if ( roar_buffer_new_data(&buf, cachepos, &bufdata) == -1 ) return -1; memcpy(bufdata, cache, cachepos); ss->buffer = buf; } return 0; } #else int midi_conv_midi2mes (int id) { void * bufdata; unsigned char * data; struct roar_stream * s; struct roar_stream_server * ss; struct roar_buffer * buf = NULL; struct midi_message * mes = NULL; size_t need = 0, have = 0, last_have = 0, old_have = 0; int alive = 1; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("midi_conv_midi2mes(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); while (ss->buffer != NULL && alive) { ROAR_DBG("midi_conv_midi2mes(id=%i): ss->buffer=%p, alive=%i", id, ss->buffer, alive); if ( roar_buffer_get_data(ss->buffer, &bufdata) == -1 ) { alive = 0; continue; } data = bufdata; if ( roar_buffer_get_len(ss->buffer, &have) == -1 ) { alive = 0; continue; } old_have = have; while (have && alive) { ROAR_DBG("midi_conv_midi2mes(id=%i): have=%llu, alive=%i", id, (long long unsigned int)have, alive); if ( *data & 0x80 ) { if ( buf != NULL ) { midi_add_buf(id, buf); buf = NULL; } last_have = have; need = 0; if ( midi_new_bufmes(&buf, &mes) == -1 ) { alive = 0; continue; } if (*data == MIDI_TYPE_CLOCK_TICK || *data == MIDI_TYPE_CLOCK_START || *data == MIDI_TYPE_CLOCK_STOP ) { mes->type = *data; if ( *data == MIDI_TYPE_CLOCK_TICK ) { s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, 1); } } else { mes->type = *data & 0xF0; mes->channel = *data & 0x0F; switch (*data & 0xF0) { case MIDI_TYPE_NOTE_ON: case MIDI_TYPE_NOTE_OFF: need = 2; break; case MIDI_TYPE_PA: need = 2; break; case MIDI_TYPE_CONTROLER: need = 2; break; case MIDI_TYPE_PROGRAM: need = 1; break; case MIDI_TYPE_MA: need = 1; break; case MIDI_TYPE_PB: case MIDI_TYPE_SYSEX: need = 1; break; } } } else { if ( mes == NULL ) { ROAR_WARN("midi_conv_midi2mes(id=%i): Lost sync.", id); data++; have--; continue; } switch (mes->type) { case MIDI_TYPE_NOTE_ON: case MIDI_TYPE_NOTE_OFF: if ( need == 2 ) { roar_midi_note_from_midiid(&(mes->d.note), *data); // if velocity is zero we have a NOTE OFF event if ( data[1] == 0 ) mes->type = MIDI_TYPE_NOTE_OFF; } case MIDI_TYPE_PA: case MIDI_TYPE_CONTROLER: if ( need == 2 ) { mes->kk = *data; } else { mes->vv = *data; } break; case MIDI_TYPE_PROGRAM: case MIDI_TYPE_MA: mes->vv = *data; break; case MIDI_TYPE_PB: case MIDI_TYPE_SYSEX: ROAR_WARN("midi_conv_midi2mes(id=%i): Message of Type 0x%.2X (PB or SysEx) not yet supported", id, mes->type); break; } if ( need ) need--; if ( !need ) { switch (mes->type) { case MIDI_TYPE_CONTROLER: switch (mes->kk) { case MIDI_CCE_MAIN_VOL: if ( 516 * mes->vv > 65100 ) { // max volume ss->mixer.mixer[mes->channel] = 65535; } else { ss->mixer.mixer[mes->channel] = 516 * mes->vv; } break; } break; } } } data++; have--; } if ( need ) { ROAR_DBG("midi_conv_midi2mes(id=%i) = ?", id); if ( roar_buffer_set_offset(ss->buffer, old_have - last_have) == -1 ) { ROAR_ERR("midi_conv_midi2mes(*): FIXME: BUG!!! Need to restore buffer here with corrected length"); } } else if ( !have ) { roar_buffer_next(&(ss->buffer)); } if ( need && buf != NULL ) { roar_buffer_free(buf); buf = NULL; } else if ( buf != NULL ) { midi_add_buf(id, buf); buf = NULL; } } return 0; } #endif #define _nb len++; *(d++) int midi_conv_mes2midi (int id) { struct roar_stream * s; struct roar_stream_server * ss; struct roar_buffer * buf = g_midi_mess.buf; struct midi_message * mes = NULL; void * bufdata; unsigned char data[3]; unsigned char * d; int len; int send_clock; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("midi_conv_mes2midi(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); send_clock = streams_get_flag(id, ROAR_FLAG_SYNC); if ( roar_buffer_ref(buf) == -1 ) return -1; roar_buffer_foreach(buf) { if ( roar_buffer_get_data(buf, &bufdata) == -1 ) { return -1; } mes = bufdata; if (mes->type == MIDI_TYPE_CLOCK_TICK || mes->type == MIDI_TYPE_CLOCK_START || mes->type == MIDI_TYPE_CLOCK_STOP ) { if ( send_clock ) { if ( stream_vio_s_write(ss, &(mes->type), 1) != 1 ) { streams_delete(id); return -1; } } if ( mes->type == MIDI_TYPE_CLOCK_TICK ) { s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, 1); } } else { len = 0; d = data; _nb = (mes->type & 0xF0) | (mes->channel & 0x0F); switch (mes->type) { case MIDI_TYPE_CONTROLER: switch (mes->kk) { case MIDI_CCE_MAIN_VOL: if ( 516U * (unsigned int)mes->vv > 65100 ) { // max volume ss->mixer.mixer[mes->channel] = 65535; } else { ss->mixer.mixer[mes->channel] = 516 * mes->vv; } break; } case MIDI_TYPE_NOTE_ON: case MIDI_TYPE_NOTE_OFF: case MIDI_TYPE_PA: _nb = mes->kk; _nb = mes->vv; break; case MIDI_TYPE_PROGRAM: case MIDI_TYPE_MA: _nb = mes->vv; break; case MIDI_TYPE_PB: case MIDI_TYPE_SYSEX: break; } if ( stream_vio_s_write(ss, data, len) != len ) { streams_delete(id); return -1; } } } return 0; } #undef _nb #ifndef ROAR_WITHOUT_DCOMP_SSYNTH int midi_conv_mes2ssynth(void) { struct roar_buffer * buf = g_midi_mess.buf; struct midi_message * mes = NULL; void * bufdata; if ( roar_buffer_ref(g_midi_mess.buf) == -1 ) return -1; roar_buffer_foreach(buf) { if ( roar_buffer_get_data(buf, &bufdata) == -1 ) { return -1; } mes = bufdata; if ( ssynth_eval_message(mes) == -1 ) return -1; } return 0; } #endif int midi_new_bufmes (struct roar_buffer ** buf, struct midi_message ** mes) { if ( buf == NULL || mes == NULL ) return -1; *buf = (void*)(*mes = NULL); if ( roar_buffer_new_data(buf, sizeof(struct midi_message), (void**)mes) == -1 ) { *buf = (void*)(*mes = NULL); return -1; } memset((void*)*mes, 0, sizeof(struct midi_message)); (*mes)->type = MIDI_TYPE_NONE; return 0; } int midi_add_buf (int id, struct roar_buffer ** buf) { #ifdef DEBUG struct midi_message * mes; void * bufdata; #endif if ( id == -1 || buf == NULL || *buf == NULL ) return -1; #ifdef DEBUG if ( roar_buffer_get_data(*buf, &bufdata) == -1 ) return -1; mes = bufdata; ROAR_DBG("midi_add_buf(id=%i, buf=%p) = ?", id, buf); ROAR_DBG("midi_add_buf(*): MIDI Message of Type 0x%.2X", mes->type); ROAR_DBG("midi_add_buf(*): Channel: %i", mes->channel); ROAR_DBG("midi_add_buf(*): flags=0x%.2X", mes->flags); ROAR_DBG("midi_add_buf(*): kk=0x%.2X, vv=0x%.2X", mes->kk, mes->vv); #endif if ( g_midi_mess.buf == NULL ) { g_midi_mess.buf = *buf; } else { if ( roar_buffer_moveinto(g_midi_mess.buf, buf) == -1 ) { ROAR_DBG("midi_add_buf(*) = -1"); return -1; } } ROAR_DBG("midi_add_buf(*) = 0"); return 0; } // bridges: int midi_check_bridge (int id) { ROAR_DBG("midi_check_bridge(id=%i) = ?", id); if ( id == g_midi_clock.stream ) { midi_clock_tick(); return 0; } return -1; } // clock: int midi_clock_init (void) { struct roar_stream * s; struct roar_stream_server * ss; if ( (g_midi_clock.stream = streams_new()) == -1 ) { ROAR_WARN("Error while initializing MIDI subsystem component clock"); return -1; } client_stream_add(g_self_client, g_midi_clock.stream); midi_vio_set_dummy(g_midi_clock.stream); streams_get(g_midi_clock.stream, &ss); s = ROAR_STREAM(ss); memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); s->pos_rel_id = g_midi_clock.stream; s->info.codec = ROAR_CODEC_MIDI; ss->codec_orgi = ROAR_CODEC_MIDI; s->info.channels = 1; // we have only one channel, ticking on channel 0 s->info.rate = ROAR_MIDI_TICKS_PER_BEAT; // one beat per sec s->info.bits = ROAR_MIDI_BITS; if ( streams_set_dir(g_midi_clock.stream, ROAR_DIR_BRIDGE, 1) == -1 ) { ROAR_WARN("Error while initializing MIDI subsystem component clock"); return -1; } streams_set_name(g_midi_clock.stream, "MIDI Clock"); streams_set_flag(g_midi_clock.stream, ROAR_FLAG_PRIMARY); streams_set_flag(g_midi_clock.stream, ROAR_FLAG_SYNC); midi_clock_set_bph(3600); // one beat per sec ss->state = ROAR_STREAMSTATE_NEW; midi_config.inited |= MIDI_INITED_CLOCK; return 0; } int midi_clock_set_bph (uint_least32_t bph) { uint_least32_t sph = g_sa->rate/2 * 75 * g_sa->channels; // samples per houre g_midi_clock.bph = bph; g_midi_clock.spt = sph/bph; g_midi_clock.nt = ROAR_MATH_OVERFLOW_ADD(g_pos, g_midi_clock.spt); return 0; } int midi_clock_tick (void) { struct roar_buffer * buf; struct midi_message * mes; struct roar_stream_server * ss; #ifdef DEBUG unsigned int diff; #endif if ( streams_get(g_midi_clock.stream, &ss) == -1 ) { ROAR_ERR("midi_clock_tick(void): Something very BAD happend: can not get stream object of my own stream!"); g_midi_clock.stream = -1; ROAR_WARN("midi_clock_tick(void): Disabled MIDI Clock"); return -1; } // the strange expr at the end is to avoid warp around bugs. while ( g_pos >= g_midi_clock.nt && !(g_pos > (uint32_t)4294900000LU && g_midi_clock.nt < (uint32_t)1000LU) ) { #ifdef DEBUG diff = g_pos - g_midi_clock.nt; ROAR_DBG("midi_clock_tick(void): g_pos is %u samples (%5.2f%%) after of nt.", diff, (float)diff/g_midi_clock.spt); #endif g_midi_clock.nt = ROAR_MATH_OVERFLOW_ADD(g_midi_clock.nt, g_midi_clock.spt); if ( streams_get_flag(g_midi_clock.stream, ROAR_FLAG_SYNC) ) { ROAR_DBG("midi_clock_tick(void): TICK! (nt=%lu)", (unsigned long int)g_midi_clock.nt); if ( midi_new_bufmes(&buf, &mes) == -1 ) { ROAR_ERR("midi_clock_tick(void): Can not create Clock-Tick-Message"); } mes->type = MIDI_TYPE_CLOCK_TICK; if ( midi_add_buf(g_midi_clock.stream, &buf) == -1 ) { ROAR_ERR("midi_clock_tick(void): Can not add Clock-Tick-Message"); roar_buffer_free(buf); return -1; } ROAR_STREAM(ss)->pos = ROAR_MATH_OVERFLOW_ADD(ROAR_STREAM(ss)->pos, 1); ss->state = ROAR_STREAMSTATE_OLD; } else { ROAR_DBG("midi_clock_tick(void): silent tick. (nt=%lu)", (unsigned long int)g_midi_clock.nt); } } return 0; } // CB: #ifndef ROAR_WITHOUT_DCOMP_CB int midi_cb_init (void) { #ifdef _HAVE_CONSOLE struct roar_stream * s; struct roar_stream_server * ss; int i; char * files[] = { "/NX", "/dev/roarconsole", "/dev/console", #ifdef __linux__ "/dev/tty0", "/dev/vc/0", #endif NULL }; g_midi_cb.console = -1; g_midi_cb.stream = -1; g_midi_cb.stoptime = 0; g_midi_cb.playing = 0; if ( midi_config.console_dev != NULL ) { files[0] = midi_config.console_dev; } for (i = 0; files[i] != NULL; i++) { if ( (g_midi_cb.console = open(files[i], O_WRONLY|O_NOCTTY, 0)) != -1 ) break; } if ( g_midi_cb.console == -1 ) return -1; if ( (g_midi_cb.stream = streams_new()) == -1 ) { ROAR_WARN("Error while initializing MIDI subsystem component CB"); midi_cb_free(); return -1; } client_stream_add(g_self_client, g_midi_clock.stream); midi_vio_set_dummy(g_midi_cb.stream); streams_get(g_midi_cb.stream, &ss); s = ROAR_STREAM(ss); memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); s->pos_rel_id = -1; s->info.codec = 0; ss->codec_orgi = 0; s->info.channels = 1; s->info.rate = 1193180; s->info.bits = 8; if ( streams_set_dir(g_midi_cb.stream, ROAR_DIR_BRIDGE, 1) == -1 ) { ROAR_WARN("Error while initializing MIDI subsystem component CB"); midi_cb_free(); return -1; } streams_set_name(g_midi_cb.stream, "Console speaker bridge"); streams_set_flag(g_midi_cb.stream, ROAR_FLAG_OUTPUT); streams_set_flag(g_midi_cb.stream, ROAR_FLAG_PRIMARY); streams_set_flag(g_midi_cb.stream, ROAR_FLAG_HWMIXER); streams_set_flag(g_midi_cb.stream, ROAR_FLAG_MUTE); midi_config.inited |= MIDI_INITED_CB; return 0; #else g_midi_cb.console = -1; g_midi_cb.stream = -1; return -1; #endif } int midi_cb_free (void) { #ifdef _HAVE_CONSOLE midi_cb_stop(); if ( g_midi_cb.stream != -1 ) streams_delete(g_midi_cb.stream); if ( g_midi_cb.console != -1 ) close(g_midi_cb.console); return 0; #else return -1; #endif } int midi_cb_play(float t, float freq, int override) { float samples_per_sec /* S/s */ = g_sa->rate * g_sa->channels; /* #define MIDI_CB_NOOVERRIDE 0 #define MIDI_CB_OVERRIDE 1 */ if ( g_midi_cb.playing && override != MIDI_CB_OVERRIDE ) return -1; g_midi_cb.stoptime = ROAR_MATH_OVERFLOW_ADD(g_pos, samples_per_sec*t); midi_cb_start(freq); return 0; } int midi_cb_update (void) { if ( !streams_get_flag(g_midi_cb.stream, ROAR_FLAG_MUTE) ) { if ( midi_cb_readbuf() == -1 ) return -1; } else if ( g_midi_cb.playing ) { midi_cb_stop(); } if ( !g_midi_cb.playing ) return 0; /* if ( g_midi_cb.stoptime <= g_pos ) midi_cb_stop(); */ ROAR_DBG("midi_cb_update(void) = ?"); return 0; } int midi_cb_start(float freq) { // On linux this uses ioctl KIOCSOUND #ifdef __linux__ if ( g_midi_cb.console == -1 ) return -1; if ( ioctl(g_midi_cb.console, KIOCSOUND, freq == 0 ? 0 : (int)(1193180.0/freq)) == -1 ) return -1; g_midi_cb.playing = 1; return 0; #else return -1; #endif } int midi_cb_stop (void) { #ifdef __linux__ int ret; ret = midi_cb_start(0); g_midi_cb.playing = 0; return ret; #else return -1; #endif } int midi_cb_readbuf(void) { struct roar_buffer * buf = g_midi_mess.buf; struct midi_message * mes = NULL; void * bufdata; ROAR_DBG("midi_cb_readbuf(void) = ?"); roar_buffer_foreach(buf) { ROAR_DBG("midi_cb_readbuf(void): buf=%p", buf); if ( roar_buffer_get_data(buf, &bufdata) == -1 ) { return -1; } mes = bufdata; switch (mes->type) { case MIDI_TYPE_NOTE_ON: midi_cb_start(mes->d.note.freq); break; case MIDI_TYPE_NOTE_OFF: midi_cb_stop(); break; case MIDI_TYPE_CONTROLER: if ( mes->kk == MIDI_CCE_ALL_NOTE_OFF ) /* all note off */ midi_cb_stop(); break; } } return 0; } #endif // VIO: static int midi_vio_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { if ( cmd == ROAR_VIO_CTL_NONBLOCK ) return 0; return -1; } static int midi_vio_ok(struct roar_vio_calls * vio, ...) { return 0; } int midi_vio_set_dummy(int stream) { struct roar_stream_server * ss; if ( streams_get(stream, &ss) == -1 ) return -1; ss->vio.read = NULL; ss->vio.write = NULL; ss->vio.lseek = NULL; ss->vio.sync = (int (*)(struct roar_vio_calls * vio))midi_vio_ok; ss->vio.ctl = midi_vio_ctl; ss->vio.close = (int (*)(struct roar_vio_calls * vio))midi_vio_ok; return 0; } #endif //ll roaraudio-1.0beta11/roard/mixer.c0000644000175000017500000000407712264733675015105 0ustar phiphi//mixer.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" int need_vol_change (int channels, struct roar_mixer_settings * set) { int i; if ( set == NULL || channels < 1 || channels > ROAR_MAX_CHANNELS ) return -1; if ( set->rpg_mul != set->rpg_div ) return 1; for (i = 0; i < channels; i++) if ( set->mixer[i] != set->scale ) return 1; return 0; } #define _err() streams_delete(stream); return -1 int add_mixer (int subsys, char * name, struct roar_stream_server ** ss_ptr) { struct roar_stream_server * ss; int stream; if ( (stream = streams_new()) == -1 ) return -1; if ( streams_get(stream, &ss) == -1 ) { _err(); } if ( streams_set_name(stream, name) == -1 ) { _err(); } if ( client_stream_add(g_self_client, stream) == -1 ) { _err(); } if ( streams_set_dir(stream, ROAR_DIR_MIXING, 1) == -1 ) { _err(); } // the mixers are the most sync thing we have... if ( streams_set_rawflag(stream, ROAR_FLAG_SYNC) == -1 ) { _err(); } if ( streams_set_flag(stream, ROAR_FLAG_IMMUTABLE) == -1 ) { _err(); } switch (subsys) { case ROAR_SUBSYS_WAVEFORM: ss->delay = _MEGA/ROAR_OUTPUT_CFREQ; break; } if ( ss_ptr != NULL ) *ss_ptr = ss; return stream; } //ll roaraudio-1.0beta11/roard/network.c0000644000175000017500000000515612264733675015451 0ustar phiphi//network.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifdef ROAR_SUPPORT_LISTEN #ifdef ROAR_BROKEN_PEERCRED #undef SO_PEERCRED #endif #ifdef ROAR_HAVE_SELECT #define _CAN_OPERATE #endif int net_check_listen (void) { struct roar_vio_selecttv rtv; struct roar_vio_select sv[ROAR_MAX_LISTEN_SOCKETS]; size_t num = 0; ssize_t ret; size_t i; for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) { if ( g_listen[i].used ) { ROAR_VIO_SELECT_SETVIO(&(sv[num]), &(g_listen[i].sock), ROAR_VIO_SELECT_READ); sv[num].ud.si = i; num++; } } if ( num == 0 ) return 0; rtv.sec = 0; rtv.nsec = 1000; if ( (ret = roar_vio_select(sv, num, &rtv, NULL)) > 0 ) { for (i = 0; i < num; i++) { if ( sv[i].eventsa & ROAR_VIO_SELECT_READ ) { if ( net_get_new_client(&(g_listen[sv[i].ud.si])) == -1 ) return -1; } } } return ret; } int net_get_new_client (struct roard_listen * lsock) { int fh; int socket; struct roar_vio_calls vio; struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); if ( roar_vio_ctl(&(lsock->sock), ROAR_VIO_CTL_GET_FH, &socket) == -1 ) { // next is needed for winsock: if ( roar_vio_ctl(&(lsock->sock), ROAR_VIO_CTL_GET_SELECT_FH, &socket) == -1 ) { ROAR_DBG("net_get_new_client(void) = -1 // can not find any acceptable socket to accept() on"); return -1; } } fh = accept(socket, (struct sockaddr*)&addr, &addrlen); ROAR_DBG("net_get_new_client(void): fh = %i", fh); if ( fh == -1 ) return -1; if ( clients_new_from_fh2(fh, lsock->proto, ROAR_BYTEORDER_NETWORK, 1, lsock, (struct sockaddr*)&addr, addrlen) == -1 ) { if ( roar_vio_open_fh_socket(&vio, fh) == -1 ) { close(fh); return -1; } roar_vio_close(&vio); return -1; } return 0; } #endif //ll roaraudio-1.0beta11/roard/output.c0000644000175000017500000003433612264733675015322 0ustar phiphi//output.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" // stuff we defined 'extern' void * g_output_buffer = NULL; void * g_input_buffer = NULL; size_t g_output_buffer_len = 0; // // int output_buffer_init (struct roar_audio_info * info) { size_t size; void * buf; size = ROAR_OUTPUT_CALC_OUTBUFSIZE(info); ROAR_DBG("output_buffer_init(*): output buffer size is %i", size); if ( (buf = roar_mm_malloc(size)) == NULL ) return -1; g_output_buffer = buf; g_output_buffer_len = size; if ( (buf = roar_mm_malloc(size)) == NULL ) { g_output_buffer = NULL; g_output_buffer_len = 0; roar_mm_free(g_output_buffer); return -1; } g_input_buffer = buf; ROAR_DBG("output_buffer_init(*): output buffer is at %p", buf); memlock_register(MEMLOCK_LOW, g_output_buffer, size); memlock_register(MEMLOCK_LOW, g_input_buffer, size); output_buffer_reinit(); return 0; } int output_buffer_reinit (void) { if ( g_output_buffer != NULL ) memset(g_output_buffer, 0, g_output_buffer_len); return 0; } int output_buffer_free (void) { ROAR_DBG("output_buffer_init(*): freeing output buffer at %p", g_output_buffer); if ( g_output_buffer != NULL ) roar_mm_free(g_output_buffer); if ( g_input_buffer != NULL ) roar_mm_free(g_input_buffer); g_output_buffer = NULL; g_input_buffer = NULL; g_output_buffer_len = 0; return 0; } #ifdef ROAR_DRIVER_DEFAULT int output_add_default (char * drv, char * dev, char * opts, int prim, int count) { return output_add(drv, dev, opts, prim, count); } #else int output_add_default (char * drv, char * dev, char * opts, int prim, int count) { char * drvs[] = { // operating system depended things: #ifdef __OpenBSD__ /* OpenBSD use sndio natively, this check is discusses with upstream (See ML archive August 2010) */ "sndio", #endif #ifdef ROAR_TARGET_WIN32 /* on Win32 we use WMM API. We may also test for ROAR_HAVE_LIBWINMM. I'm not sure what is better. * both, WMM and UNIX like stuff is supported in cygwin. */ "wmm", #endif // native and pseudo-native interfaces: "oss", "alsa", "sndio", "wmm", // sound libs: "ao", "portaudio", // other sound systems: "esd", "rsound", "artsc", "pulsesimple", "roar", // libroareio's drivers: "cdriver", // specal buildins: "sysclock", "null", // terminator: NULL }; int i; int ret; int _alive; char * _opts; if ( drv != NULL ) return output_add(drv, dev, opts, prim, count); if ( dev != NULL ) { ROAR_WARN("add_default_output(drv=(none), dev='%s', opts='%s', prim=%i, count=%i): It's not recommended to use device name without driver name.", dev, opts, prim, count); } for (i = 0; drvs[i] != NULL; i++) { ROAR_INFO("add_default_output(*): trying driver %s", ROAR_DBG_INFO_INFO, drvs[i]); _alive = alive; // save global alive setting if ( opts == NULL ) { _opts = NULL; } else { _opts = roar_mm_strdup(opts); } ret = output_add(drvs[i], dev, _opts, prim, count); if ( _opts != NULL ) roar_mm_free(_opts); if ( ret != -1 ) return ret; alive = _alive; // restore global alive setting ROAR_INFO("add_default_output(*): Driver %s faild to load", ROAR_DBG_INFO_VERBOSE, drvs[i]); } return -1; } #endif #define _CKPARAM(n) if ( n (v == NULL) ) { \ ROAR_WARN("add_output(drv='%s', dev='%s', opts=..., prim=%i, count=%i): " \ "Parameter '%s' expects %s parameter.", \ drv, dev, prim, count, k, (n 1) ? "a" : "no"); \ error++; \ } else int output_add (char * drv, char * dev, char * opts, int prim, int count) { int stream; int default_flags = 0; struct roar_stream * s; struct roar_stream_server * ss; char * k, * v; #ifdef ROAR_DRIVER_CODEC char * to_free = NULL; #endif int sync = 0, f_mmap = 0; int32_t blocks = -1, blocksize = -1; int dir = ROAR_DIR_OUTPUT; int error = 0; // DMX: int32_t channel = -1; int32_t universe = -1; uint16_t tu16; float q = -32e6; char * strtok_store; ROAR_INFO("add_output(drv='%s', dev='%s', opts='%s', prim=%i, count=%i): trying to add output driver", ROAR_DBG_INFO_INFO, drv, dev, opts, prim, count); if ( drv == NULL && count == 0 ) { #ifdef ROAR_DRIVER_DEFAULT drv = ROAR_DRIVER_DEFAULT; prim = 1; sync = 1; #ifdef ROAR_DRIVER_CODEC if ( opts == NULL ) { opts = to_free = roar_mm_strdup("codec=" ROAR_DRIVER_CODEC); } #endif #else ROAR_ERR("add_output(*): Can not find default driver"); return -1; #endif } if ( opts == NULL && count == 0 ) { ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); default_flags = ROAR_FLAG_AUTOCONF|ROAR_FLAG_RECSOURCE; sync = 1; prim = 1; // if ( prim == 0 ) prim = 1; -> prim allways = 1 } ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); if ( (stream = streams_new()) == -1 ) { ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts); if ( prim ) alive = 0; return -1; } ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); streams_get(stream, &ss); s = ROAR_STREAM(ss); ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); memset(&(s->info), 0xFF, sizeof(struct roar_audio_info)); // set everything to -1 s->pos_rel_id = -1; // s->info.codec = codec; // seting default flags: streams_set_flag(stream, default_flags); ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); if ( opts == NULL ) { k = NULL; } else { k = roar_mm_strtok_r(opts, ",", &strtok_store); } ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s'): initial k='%s'(%p)", drv, dev, opts, k, k); while (k != NULL) { // ROAR_WARN("add_output(*): opts: %s", k); if ( (v = strstr(k, "=")) != NULL ) { *v++ = 0; } ROAR_DBG("add_output(*): opts: k='%s', v='%s'", k, v); if ( strcmp(k, "rate") == 0 ) { _CKPARAM() s->info.rate = atoi(v); } else if ( strcmp(k, "channels") == 0 ) { _CKPARAM() s->info.channels = atoi(v); } else if ( strcmp(k, "bits") == 0 ) { _CKPARAM() s->info.bits = atoi(v); } else if ( strcmp(k, "codec") == 0 ) { _CKPARAM() if ( (s->info.codec = roar_str2codec(v)) == -1 ) { ROAR_ERR("add_output(*): unknown codec '%s'", v); error++; } } else if ( strcmp(k, "q") == 0 ) { _CKPARAM() q = atof(v); } else if ( strcmp(k, "blocks") == 0 ) { _CKPARAM() blocks = atoi(v); } else if ( strcmp(k, "blocksize") == 0 ) { _CKPARAM() blocksize = atoi(v); } else if ( strcmp(k, "mmap") == 0 ) { _CKPARAM(!) f_mmap = 1; } else if ( strcmp(k, "subsystem") == 0 ) { _CKPARAM() { if ( !strcasecmp(v, "wave") || !strcasecmp(v, "waveform") ) { dir = ROAR_DIR_OUTPUT; #ifndef ROAR_WITHOUT_DCOMP_MIDI } else if ( !strcasecmp(v, "midi") ) { dir = ROAR_DIR_MIDI_OUT; #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT } else if ( !strcasecmp(v, "light") ) { dir = ROAR_DIR_LIGHT_OUT; #endif #ifndef ROAR_WITHOUT_DCOMP_RAW } else if ( !strcasecmp(v, "raw") ) { dir = ROAR_DIR_RAW_OUT; #endif } else if ( !strcasecmp(v, "complex") ) { dir = ROAR_DIR_COMPLEX_OUT; } else { ROAR_ERR("add_output(*): unknown/unsupported subsystem '%s'", k); error++; } } // DMX: } else if ( strcmp(k, "channel") == 0 ) { _CKPARAM() { channel = atoi(v); if ( channel < 0 || channel > 65535 ) { ROAR_ERR("add_output(*): Invalide channel (not within 0..65535): %i", channel); channel = -1; error++; } } } else if ( strcmp(k, "universe") == 0 ) { _CKPARAM() { universe = atoi(v); if ( universe < 0 || universe > 255 ) { ROAR_ERR("add_output(*): Invalide universe (not within 0..255): %i", universe); universe = -1; error++; } } } else if ( strcmp(k, "name") == 0 ) { _CKPARAM() { if ( streams_set_name(stream, v) == -1 ) { ROAR_ERR("add_output(*): Can not set Stream name"); error++; } } } else if ( strcmp(k, "meta") == 0 ) { _CKPARAM(!) streams_set_flag(stream, ROAR_FLAG_META); } else if ( strcmp(k, "sync") == 0 ) { _CKPARAM(!) sync = 1; } else if ( strcmp(k, "primary") == 0 ) { _CKPARAM(!) prim = 1; } else if ( strcmp(k, "cleanmeta") == 0 ) { _CKPARAM(!) streams_set_flag(stream, ROAR_FLAG_CLEANMETA); } else if ( strcmp(k, "autoconf") == 0 ) { _CKPARAM(!) streams_set_flag(stream, ROAR_FLAG_AUTOCONF); } else if ( strcmp(k, "recsource") == 0 ) { _CKPARAM(!) streams_set_flag(stream, ROAR_FLAG_RECSOURCE); } else if ( strcmp(k, "passmixer") == 0 ) { _CKPARAM(!) streams_set_flag(stream, ROAR_FLAG_PASSMIXER); } else if ( strcmp(k, "recsource") == 0 ) { _CKPARAM(!) streams_set_flag(stream, ROAR_FLAG_RECSOURCE); } else { ROAR_ERR("add_output(*): unknown option '%s'", k); error++; } if ( error ) { streams_delete(stream); if ( prim ) alive = 0; #ifdef ROAR_DRIVER_CODEC if ( to_free != NULL ) roar_mm_free(to_free); #endif return -1; } k = roar_mm_strtok_r(NULL, ",", &strtok_store); } ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); // set audio info... switch (dir) { case ROAR_DIR_LIGHT_OUT: switch (s->info.codec) { case ROAR_CODEC_DMX512: case -1: if ( s->info.rate == -1 ) s->info.rate = ROAR_OUTPUT_CFREQ; s->info.channels = 0; s->info.bits = 8; s->info.codec = ROAR_CODEC_DMX512; // in case codec == -1 break; } break; case ROAR_DIR_MIDI_OUT: switch (s->info.codec) { case ROAR_CODEC_MIDI: case -1: if ( s->info.rate == -1 ) s->info.rate = ROAR_MIDI_TICKS_PER_BEAT; s->info.channels = ROAR_MIDI_CHANNELS_DEFAULT; s->info.bits = ROAR_MIDI_BITS; s->info.codec = ROAR_CODEC_MIDI; // in case codec == -1 break; } break; case ROAR_DIR_RAW_OUT: if ( s->info.rate == -1 ) s->info.rate = 0; if ( s->info.bits == -1 ) s->info.bits = 0; if ( s->info.channels == -1 ) s->info.channels = 0; if ( s->info.codec == -1 ) s->info.codec = 0; break; } if ( s->info.rate == -1 ) s->info.rate = g_sa->rate; if ( s->info.bits == -1 ) s->info.bits = g_sa->bits; if ( s->info.channels == -1 ) s->info.channels = g_sa->channels; if ( s->info.codec == -1 ) s->info.codec = g_sa->codec; ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec); if ( streams_set_dir(stream, dir, 1) == -1 ) { streams_delete(stream); return -1; } #ifdef ROAR_DRIVER_CODEC if ( to_free != NULL ) roar_mm_free(to_free); #endif if ( s->info.codec == ROAR_CODEC_ALAW || s->info.codec == ROAR_CODEC_MULAW ) s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter ROAR_STREAM_SERVER(s)->codec_orgi = s->info.codec; if ( driver_openvio(&(ss->vio), &(ss->driver_id), drv, dev, &(s->info), -1, ss) == -1 ) { ss->driver_id = -1; // don't close a driver not opened... memset(&(ss->vio), 0, sizeof(struct roar_vio_calls)); streams_delete(stream); if ( prim ) alive = 0; ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not open output driver.", drv, dev, opts); ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts); return -1; } _LIBROAR_IGNORE_RET(roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream)); // ignore errors here _LIBROAR_IGNORE_RET(roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM, s)); // ignore errors here if ( blocks != -1 ) { if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks) == -1 ) { ROAR_WARN("add_output(drv='%s', dev='%s', opts='%s'): can not set number of blocks.", drv, dev, opts); } } if ( blocksize != -1 ) { if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize) == -1 ) { ROAR_WARN("add_output(drv='%s', dev='%s', opts='%s'): can not set blocksize.", drv, dev, opts); } } // TODO: we shoudld *really* check for errors here... if ( channel != -1 ) { tu16 = channel; if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16) == -1 ) { streams_delete(stream); if ( prim ) alive = 0; ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not set DMX channel number.", drv, dev, opts); ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts); return -1; } } if ( universe != -1 ) { tu16 = universe; if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16) == -1 ) { streams_delete(stream); if ( prim ) alive = 0; ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not set DMX universe.", drv, dev, opts); ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts); return -1; } } ROAR_DBG("add_output(*): ss->driver_id=%i", ss->driver_id); streams_set_fh(stream, -1); // update some internal structures if ( q > -1e6 ) { ROAR_DBG("add_output(*): setting q=%f", q); streams_ctl(stream, ROAR_CODECFILTER_CTL_SET_Q|ROAR_STREAM_CTL_TYPE_FLOAT, &q); } client_stream_add(g_self_client, stream); if ( prim ) { streams_mark_primary(stream); s->pos_rel_id = stream; } if ( sync ) { streams_set_flag(stream, ROAR_FLAG_SYNC); } else { streams_reset_flag(stream, ROAR_FLAG_SYNC); } if ( f_mmap ) streams_set_flag(stream, ROAR_FLAG_MMAP); ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec); return 0; } //ll roaraudio-1.0beta11/roard/plugins.c0000644000175000017500000001737612264733675015450 0ustar phiphi//plugins.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #define MAX_PLUGINS 8 static struct _roard_plugin { struct roar_dl_lhandle * lhandle; } g_plugins[MAX_PLUGINS]; static struct _roard_plugin * _pp = NULL; static int _plugins_inited = 0; static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle); static const struct roar_dl_fnreg _plugin_callbacks = { .fn = -1, .subtype = -1, .version = -1, .callback = plugin_callback, .userdata = NULL }; static struct _roard_plugin * _find_free(void) { int i; ROAR_DBG("_find_free(void) = ?"); for (i = 0; i < MAX_PLUGINS; i++) { if ( g_plugins[i].lhandle == NULL ) { memset(&(g_plugins[i]), 0, sizeof(struct _roard_plugin)); ROAR_DBG("_find_free(void) = %p // i=%i", &(g_plugins[i]), i); return &(g_plugins[i]); } } ROAR_DBG("_find_free(void) = NULL"); return NULL; } int plugins_preinit (void) { ROAR_DBG("plugins_preinit(void) = ?"); memset(g_plugins, 0, sizeof(g_plugins)); #ifdef DEBUG print_pluginlist(FORMAT_NATIVE); #endif ROAR_DBG("plugins_preinit(void) = 0"); return 0; } static inline void plugins_delete(struct _roard_plugin * plugin) { ROAR_DBG("plugins_delete(plugin=%p) = ?", plugin); roar_dl_appsched_trigger(plugin->lhandle, ROAR_DL_APPSCHED_FREE); roar_dl_close(plugin->lhandle); memset(plugin, 0, sizeof(struct _roard_plugin)); plugin->lhandle = NULL; } static int plugins_init_one(struct _roard_plugin * plugin) { if ( plugin == NULL ) return -1; ROAR_DBG("plugins_init_one(plugin=%p) = ?", plugin); _pp = plugin; if ( roar_dl_ra_init(plugin->lhandle, NULL, NULL) == -1 ) { ROAR_WARN("plugins_init(void): Can not RA init lib at %p: %s", plugin->lhandle, roar_error2str(roar_error)); plugins_delete(plugin); return -1; } roar_dl_appsched_trigger(plugin->lhandle, ROAR_DL_APPSCHED_INIT); _pp = NULL; return 0; } int plugins_init (void) { size_t i; ROAR_DBG("plugins_init(void) = ?"); #ifdef DEBUG print_pluginlist(FORMAT_NATIVE); #endif if ( _plugins_inited ) { ROAR_DBG("plugins_init(void) = -1 // error=BUSY"); roar_err_set(ROAR_ERROR_BUSY); return -1; } ROAR_DL_RFNREG(ROAR_DL_HANDLE_APPLICATION, _plugin_callbacks); for (i = 0; i < MAX_PLUGINS; i++) { if ( g_plugins[i].lhandle != NULL ) { plugins_init_one(&(g_plugins[i])); } } _plugins_inited = 1; #ifdef DEBUG print_pluginlist(FORMAT_NATIVE); #endif ROAR_DBG("plugins_init(void) = 0"); return 0; } int plugins_free (void) { int i; ROAR_DBG("plugins_free(void) = ?"); for (i = 0; i < MAX_PLUGINS; i++) { if ( g_plugins[i].lhandle != NULL ) { plugins_delete(&(g_plugins[i])); } } return plugins_preinit(); } int plugins_update (void) { int ret = 0; int i; for (i = 0; i < MAX_PLUGINS; i++) { if ( g_plugins[i].lhandle != NULL ) { if ( roar_dl_appsched_trigger(g_plugins[i].lhandle, ROAR_DL_APPSCHED_UPDATE) == -1 ) if ( roar_error != ROAR_ERROR_NOENT ) ret = -1; } } return ret; } int plugins_load (const char * filename, const char * args) { struct _roard_plugin * next = _find_free(); struct roar_dl_librarypara * para; ROAR_DBG("plugins_load(filename=\"%s\", args=\"%s\") = ?", filename, args); if ( next == NULL ) return -1; if ( (para = roar_dl_para_new(args, NULL, ROARD_DL_APPNAME, ROARD_DL_ABIVERSION)) == NULL ) { ROAR_WARN("Can not load plugin (allocate para set): %s: %s", filename, roar_error2str(roar_error)); return -1; } next->lhandle = roar_dl_open(filename, ROAR_DL_FLAG_PLUGIN, 0 /* we delay this until plugins_init() */, para); roar_dl_para_unref(para); if ( next->lhandle == NULL ) { ROAR_ERR("plugins_load(filename='%s'): can not load plugin: %s", filename, roar_dl_errstr(NULL)); return -1; } if ( _plugins_inited ) return plugins_init_one(next); return 0; } void print_pluginlist(enum output_format format) { const struct roar_dl_libraryname * libname; struct _roard_plugin * p; size_t i; switch (format) { case FORMAT_NATIVE: printf(" Name\n"); printf(" Attributes\n"); printf("-----------------------------------------------------\n"); break; case FORMAT_WIKI: case FORMAT_CSV: default: roar_err_set(ROAR_ERROR_NOTSUP); return; } for (i = 0; i < MAX_PLUGINS; i++) { p = &(g_plugins[i]); if ( p->lhandle == NULL ) continue; libname = roar_dl_getlibname(p->lhandle); if ( libname == NULL ) { } else { printf(" %s\n", libname->libname); printf(" Flags: %s\n", ""); if ( libname->description != NULL ) printf(" Description: %s\n", libname->description); if ( libname->contact != NULL ) printf(" Contact: %s\n", libname->contact); } } } static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle) { (void)options, (void)userdata; ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = ?", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); switch (fn) { case ROAR_DL_FN_PROTO: if ( subtype != ROAR_DL_PROTO_SUBTYPE ) { ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=TYPEMM", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); roar_err_set(ROAR_ERROR_TYPEMM); return -1; } if ( objectlen != ROAR_DL_PROTO_SIZE ) { ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADLIB", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); roar_err_set(ROAR_ERROR_BADLIB); return -1; } if ( version != ROAR_DL_PROTO_VERSION ) { ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADVERSION", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); roar_err_set(ROAR_ERROR_BADVERSION); return -1; } switch (action) { case ROAR_DL_FNREG: return clients_register_proto_common(object, lhandle); break; case ROAR_DL_FNUNREG: return clients_unregister_proto(((const struct roard_proto *)object)->proto); break; } break; } ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=NOTSUP", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); roar_err_set(ROAR_ERROR_NOTSUP); return -1; } //ll roaraudio-1.0beta11/roard/raw.c0000644000175000017500000000355312264733676014551 0ustar phiphi//raw.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_RAW int raw_check_stream (int id) { struct roar_stream * s; struct roar_stream_server * ss; struct roar_buffer * buf; void * data; ssize_t len; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("raw_check_stream(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); if ( s->pos_rel_id == -1 ) return -1; // TODO: do we really need a buffer object here? wouldn't space on stack be ok? if ( roar_buffer_new_data(&buf, RAW_READ_LEN, &data) == -1 ) return -1; if ( (len = stream_vio_s_read(ss, data, RAW_READ_LEN)) < 1 ) { // this is len=0 -> eof OR len=-1 -> error streams_delete(id); roar_buffer_free(buf); return -1; } if ( stream_vio_write(s->pos_rel_id, data, len) != len ) { // we are hard here as this is needed to ensure data integrety streams_delete(s->pos_rel_id); } roar_buffer_free(buf); return 0; } #endif //ll roaraudio-1.0beta11/roard/rdtcs.c0000644000175000017500000000700112264733676015067 0ustar phiphi//rdtcs.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_RDTCS // declared 'extern' struct rdtcs_state g_rdtcs; int rdtcs_init (void) { return 0; } int rdtcs_free (void) { return 0; } int rdtcs_init_config (void) { memset(&g_rdtcs, 0, sizeof(g_rdtcs)); strncpy(g_rdtcs.rds.ps, RDTCS_RDS_PS_DEFAULT, RDTCS_RDS_PS_LEN); g_rdtcs.rds.ps[RDTCS_RDS_PS_LEN] = 0; g_rdtcs.rds.pty = RDTCS_RDS_PTY_DEFAULT; g_rdtcs.rds.pi = RDTCS_RDS_PI_DEFAULT; g_rdtcs.rds.flags = RDTCS_RDS_FLAG_NONE; return 0; } int rdtcs_rds_set_ps (char * ps) { int i; if ( ps == NULL ) return -1; if ( strlen(ps) > 8 ) return -1; // coppy string converting to upper case: for (i = 0; ps[i]; i++) { g_rdtcs.rds.ps[i] = toupper(ps[i]); } g_rdtcs.rds.ps[i] = 0; // terminating \0 return 0; } int rdtcs_rds_set_pty (char * pty) { if ( pty == NULL ) return -1; return -1; } int rdtcs_rds_set_flag (unsigned int flag, int reset) { g_rdtcs.rds.flags |= flag; if ( reset ) g_rdtcs.rds.flags -= flag; return 0; } int rdtcs_check_stream (int id) { return -1; } int rdtcs_send_stream (int id) { struct roar_stream * s; struct roar_stream_server * ss; if ( g_streams[id] == NULL ) return -1; ROAR_DBG("rdtcs_send_stream(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); switch (s->info.codec) { case ROAR_CODEC_RDS: return rdtcs_send_stream_rds(id, ss); break; default: streams_delete(id); return -1; } return 0; } int rdtcs_send_stream_rds (int id, struct roar_stream_server * ss) { struct roar_stream * s; s = ROAR_STREAM(ss); return rdtcs_send_stream_rds_group(id, ss); } int rdtcs_send_stream_rds_group (int id, struct roar_stream_server * ss) { char out[RDTCS_RDS_GROUP_LEN]; char * c; int block[4] = {RDTCS_RDS_BLOCK_A, RDTCS_RDS_BLOCK_B, RDTCS_RDS_BLOCK_C0, RDTCS_RDS_BLOCK_D}; uint16_t data[4]; uint16_t crc; register uint32_t s; int i, fill; // TODO: think about byte order! for (i = 0; i < 4; i++) data[i] = 0; data[0] = g_rdtcs.rds.pi; memset(out, 0, sizeof(out)); c = out; s = 0; fill = 0; for (i = 0; i < 4; i++) { // data is 16 bit long s |= data[i] << (fill & 0xFFFF); fill += 16; crc = rdtcs_rds_crc_calc(data[i], block[i]); // CRC is 10 bit long s |= crc << (fill & 0x03FF); fill += 10; // shift all complet bytes we allready have out while (fill >= 8) { *c = s & 0xFF; c++; s >>= 8; fill -= 8; } } return stream_vio_s_write(ss, out, RDTCS_RDS_GROUP_LEN) == RDTCS_RDS_GROUP_LEN ? 0 : -1; } uint16_t rdtcs_rds_crc_calc (uint16_t data, int block) { return 0xAAAA; } #endif //ll roaraudio-1.0beta11/roard/req.c0000644000175000017500000013535712264733676014557 0ustar phiphi//req.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * massage <-> object converters: * ckport: ignore-symbol: roar_stream_s2m of target libroar0 * ckport: ignore-symbol: roar_stream_m2s of target libroar0 * ckport: ignore-symbol: roar_ctl_c2m of target libroar0 * ckport: ignore-symbol: roar_ctl_ia2m of target libroar0 * ckport: ignore-symbol: roar_ctl_m2f of target libroar0 * Caps support: * ckport: ignore-symbol: roar_caps_from_msg of target libroar0 * ckport: ignore-symbol: roar_caps_to_msg of target libroar0 * Server info: * ckport: ignore-symbol: roar_server_info_to_mes of target libroar0 * PASSFH: * ckport: ignore-symbol: roar_socket_recv_fh of target libroar0 * AUTH: * ckport: ignore-symbol: roar_auth_from_mes of target libroar0 * ckport: ignore-symbol: roar_auth_to_mes of target libroar0 * Events: * ckport: ignore-symbol: roar_event_from_blob of target libroar0 * Filter: * ckport: ignore-symbol: roar_filter_match of target libroar0 */ #include "roard.h" // include for uname() used by req_on_server_info() #ifdef ROAR_HAVE_UNAME #include #endif static void * _dataspace(struct roar_message * mes, char ** data, uint32_t flags[2], size_t len) { if ( len <= LIBROAR_BUFFER_MSGDATA ) return mes->data; if ( *data != NULL ) roar_mm_free(*data); *data = roar_mm_malloc(len); ROAR_DBG("_dataspace(mes=%p, data=%p, flags=%p, len=%llu): *data=%p", mes, data, flags, (long long unsigned int)len, *data); if ( *data == NULL ) return NULL; flags[1] |= COMMAND_FLAG_OUT_LONGDATA; return *data; } int req_on_noop (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { (void)client, (void)data, (void)flags; mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 0; return 0; } int req_on_quit (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { (void)client, (void)data; mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 0; flags[1] |= COMMAND_FLAG_OUT_DELETE; return 0; } int req_on_identify (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_client_server * cs; struct roar_client * c; int max_len; (void)data, (void)flags; if ( mes->datalen < 1 ) return -1; clients_get_server(client, &cs); c = ROAR_CLIENT(cs); if ( mes->data[0] == 1 ) { if ( c->pid == -1 ) { c->pid = ROAR_NET2HOST32(*(uint32_t*)((mes->data)+1)); ROAR_DBG("req_on_identify(): new PID: c->pid = %i", c->pid); } ROAR_DBG("req_on_identify(): final PID: c->pid = %i", c->pid); max_len = (mes->datalen - 5) < (ROAR_BUFFER_NAME-1) ? (mes->datalen - 5) : (ROAR_BUFFER_NAME-1); strncpy(c->name, mes->data + 5, max_len); c->name[max_len] = 0; // we set the acclevel to IDENTED here. // if it is alreay > IDENTED we reset it anyway // as potential auth relevent data changed. cs->acclev = ACCLEV_IDENTED; mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 0; ROAR_DBG("req_on_identify(*): client=%i, pid=%i", client, c->pid); ROAR_DBG("req_on_identify(*) = 0"); return 0; } return -1; } int req_on_auth (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_error_frame error_frame; void * error_data; struct roar_message error_mes; struct roar_client_server * cs; struct roar_auth_message authmes; int next = -1; int ret; (void)flags; clients_get_server(client, &cs); // TODO: add code to support some auth. if ( roar_auth_from_mes(&authmes, mes, *data) == -1 ) return -1; ROAR_INFO("req_on_auth(client=%i,...): authtype=%s(%i), len=%llu bytes", ROAR_DBG_INFO_VERBOSE, client, roar_autht2str(authmes.type), authmes.type, (long long unsigned int)authmes.len); ROAR_DBG("req_on_auth(client=%i,...): CALL auth_client_ckeck(cs=%p, &authmes=%p, &next=%p)", client, cs, &authmes, &next); ret = auth_client_ckeck(cs, &authmes, &next); ROAR_DBG("req_on_auth(client=%i,...): RET %i // next=%s(%i)", client, ret, roar_autht2str(next), next); if ( ret != 1 ) { ROAR_DBG("req_on_auth(client=%i,...) = ?", client); if ( next != -1 ) { ROAR_DBG("req_on_auth(client=%i,...) = ?", client); memset(&authmes, 0, sizeof(authmes)); authmes.type = next; if ( roar_auth_to_mes(&error_mes, NULL, &authmes) == -1 ) return -1; ROAR_DBG("req_on_auth(client=%i,...) = ?", client); if ( roar_err_init(&error_frame) == -1 ) return -1; ROAR_DBG("req_on_auth(client=%i,...) = ?", client); error_frame.ra_errno = ROAR_ERROR_PERM; error_frame.datalen = error_mes.datalen; error_data = roar_err_buildmsg(mes, NULL, &error_frame); ROAR_DBG("req_on_auth(client=%i,...): error_data=%p", client, error_data); memcpy(error_data, error_mes.data, error_mes.datalen); mes->cmd = ROAR_CMD_ERROR; mes->pos = g_pos; ROAR_DBG("req_on_auth(client=%i,...): mes=%p{.datalen=%i}", client, mes, (int)mes->datalen); ROAR_DBG("req_on_auth(client=%i,...) = 0 // cmd=ERROR", client); return 0; } ROAR_DBG("req_on_auth(client=%i,...) = 0", client); return -1; } mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 0; ROAR_DBG("req_on_auth(client=%i,...) = 0", client); return 0; } int req_on_whoami (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { (void)data, (void)flags; mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 1; mes->data[0] = client; return 0; } int req_on_new_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { int stream; struct roar_stream_server * ss; struct roar_stream * s; struct roar_stream * source_stream; struct roar_audio_info * info; struct roar_audio_info * source_info; ROAR_DBG("req_on_new_stream(client=%i, ...): creating stream...", client); if ((stream = streams_new()) == -1 ) return -1; ROAR_DBG("req_on_new_stream(client=%i, ...): stream=%i", client, stream); ROAR_DBG("req_on_new_stream(client=%i, ...): getting stream...", client); if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); return -1; } s = ROAR_STREAM(ss); ROAR_DBG("req_on_new_stream(client=%i, ...): set client of stream...", client); if ( client_stream_add(client, stream) == -1 ) { streams_delete(stream); return -1; } ROAR_DBG("req_on_new_stream(client=%i, ...): loading stream from message...", client); if ( roar_stream_m2s(s, mes) == -1 ) { streams_delete(stream); return -1; } ROAR_DBG("req_on_new_stream(client=%i, ...): setting id and codec of stream...", client); ROAR_STREAM(s)->id = stream; // roar_stream_m2s() resets this ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM(s)->info.codec; ROAR_DBG("req_on_new_stream(client=%i, ...): setting direction stream...", client); // int streams_set_dir (int id, int dir, int defaults) if ( streams_set_dir(stream, ROAR_STREAM(s)->dir, 1) == -1 ) { streams_delete(stream); return -1; } ROAR_DBG("req_on_new_stream(client=%i, ...): checking mixer settings...", client); if ( mes->stream != -1 && mes->stream != ss->mixer_stream ) { streams_delete(stream); return -1; } ROAR_DBG("req_on_new_stream(client=%i, ...): setting up direction specific stream settings...", client); switch (ROAR_STREAM(s)->dir) { case ROAR_DIR_LIGHT_IN: case ROAR_DIR_LIGHT_OUT: #ifndef ROAR_WITHOUT_DCOMP_LIGHT info = &(ROAR_STREAM(s)->info); info->channels = 0; info->bits = 0; info->rate = 0; #else streams_delete(stream); return -1; #endif break; case ROAR_DIR_MIDI_IN: case ROAR_DIR_MIDI_OUT: #ifndef ROAR_WITHOUT_DCOMP_MIDI info = &(ROAR_STREAM(s)->info); info->channels = ROAR_MIDI_CHANNELS_DEFAULT; info->bits = ROAR_MIDI_BITS; info->rate = 0; #else streams_delete(stream); return -1; #endif break; case ROAR_DIR_RAW_IN: #ifndef ROAR_WITHOUT_DCOMP_RAW if ( ROAR_STREAM(s)->pos_rel_id == -1 || ROAR_STREAM(s)->pos_rel_id == stream || streams_get_dir(ROAR_STREAM(s)->pos_rel_id) != ROAR_DIR_RAW_OUT ) { ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting // in case rel_id == stream streams_delete(stream); return -1; } #else case ROAR_DIR_RAW_OUT: streams_delete(stream); return -1; #endif break; case ROAR_DIR_THRU: if ( ROAR_STREAM(s)->pos_rel_id == -1 || ROAR_STREAM(s)->pos_rel_id == stream ) { ROAR_STREAM(s)->pos_rel_id = -1; // force this here as it will try to delete itself while deleting // in case rel_id == stream streams_delete(stream); return -1; } if ( streams_get_clientobj(ROAR_STREAM(s)->pos_rel_id, &source_stream) == -1 ) { streams_delete(stream); return -1; } info = &(ROAR_STREAM(s)->info); source_info = &(ROAR_STREAM(source_stream)->info); info->channels = source_info->channels; info->bits = source_info->bits; info->rate = source_info->rate; info->codec = source_info->codec; ROAR_STREAM_SERVER(s)->codec_orgi = ROAR_STREAM_SERVER(source_stream)->codec_orgi; break; case ROAR_DIR_FILTER: info = &(ROAR_STREAM(s)->info); if ( ROAR_STREAM(s)->pos_rel_id == -1 ) { source_info = g_sa; } else { if ( streams_get_clientobj(ROAR_STREAM(s)->pos_rel_id, &source_stream) == -1 ) { streams_delete(stream); return -1; } source_info = &(ROAR_STREAM(source_stream)->info); } if ( info->channels != source_info->channels || info->bits != source_info->bits || info->codec != source_info->codec || info->rate != source_info->rate ) { // the stream parameters don't match the one of the stream being filtered. // -> delete and reject the stream. streams_delete(stream); return -1; } break; } ROAR_DBG("req_on_new_stream(client=%i, ...): returning (OK, stream=%i)...", client, stream); mes->cmd = ROAR_CMD_OK; mes->stream = stream; mes->datalen = 0; return 0; } int req_on_exec_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_message m; struct roar_client * c; struct roar_connection con; int16_t * d = (int16_t*)mes->data; int sock; int i; int r; ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): execing stream", client, mes->stream); if ( mes->stream != -1 ) { if ( streams_is_ready(mes->stream) ) { flags[1] |= COMMAND_FLAG_OUT_CLOSECON; } else { if ( (r = client_stream_exec(client, mes->stream)) == -1 ) return -1; } ROAR_DBG("req_on_exec_stream(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream); mes->cmd = ROAR_CMD_OK; mes->datalen = 0; return 0; } ROAR_DBG("req_on_exec_stream(client=%i,...): non stream exec", client); if ( mes->datalen < 4*2 ) return -1; ROAR_DBG("req_on_exec_stream(client=%i,...) = ?", client); for (i = 0; i < 4; i++) { d[i] = ROAR_NET2HOST16(d[i]); } if ( d[0] != 0 ) // version return -1; if ( d[1] != 0 ) // flags return -1; if ( clients_get_protohandle(d[2]) == NULL ) return -1; ROAR_DBG("req_on_exec_stream(client=%i,...) = ?", client); memset(&m, 0, sizeof(m)); m.cmd = ROAR_CMD_OK; flags[1] |= COMMAND_FLAG_OUT_NOSEND; c = ROAR_CLIENT(g_clients[client]); sock = c->fh; if ( sock == -1 ) return -1; ROAR_DBG("req_on_exec_stream(client=%i,...) = ?", client); roar_connect_fh(&con, sock); roar_send_message(&con, &m, NULL); clients_set_fh(client, -1); clients_delete(client); ROAR_DBG("req_on_exec_stream(client=%i,...): calling clients_new_from_fh(): sock=%i, d={?, ?, %i, %i}", client, sock, (int)d[2], (int)d[3]); if ( clients_new_from_fh(sock, d[2], d[3], 1) == -1 ) { close(sock); } ROAR_DBG("req_on_exec_stream(client=%i,...) = 0", client); return 0; } int req_on_con_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { char host[80] = {0}; int port = 0; int type; int fh; int len; if ( mes->datalen < 4 ) return -1; if ( *(mes->data) != 0 ) return -1; if ( mes->datalen > 80 ) // we do not support long messages here return -1; type = (unsigned)mes->data[1]; port = ROAR_NET2HOST16(((uint16_t*)mes->data)[1]); len = mes->datalen - 4; strncpy(host, &(mes->data[4]), len); host[len] = 0; if ( type > ROAR_SOCKET_TYPE_MAX ) return -1; if ( type == ROAR_SOCKET_TYPE_FILE ) // disabled because of security resons return -1; if ( type == ROAR_SOCKET_TYPE_FORK ) // why should we connect to ourself? return -1; ROAR_DBG("req_on_con_stream(*): CONNECT(type=%i, host='%s', port=%i)", type, host, port); roar_libroar_nowarn(); fh = roar_socket_open(ROAR_SOCKET_MODE_CONNECT, type, host, port); roar_libroar_warn(); if ( fh == -1 ) return -1; if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) { close(fh); return 1; } mes->datalen = 0; mes->cmd = ROAR_CMD_OK; return 0; } int req_on_passfh (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { int sock = clients_get_fh(client); int16_t * d = (int16_t*)mes->data; struct roard_listen * lsock; int listening; int fh; int i; ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...) = ?", client, mes->stream); if ( (fh = roar_socket_recv_fh(sock, NULL, NULL)) == -1 ) { ROAR_WARN("req_on_passfh(client=%i, mes={stream=%i,...},...): was unabled to get filehandle from remote end. bad.", client, mes->stream); ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (ERROR)...", client, mes->stream); return -1; } ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): fh=%i", client, mes->stream, fh); if ( mes->stream != -1 ) { // stream pass: ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): This is a stream passfh", client, mes->stream); if ( client_stream_set_fh(client, mes->stream, fh) == -1 ) { close(fh); ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (ERROR)...", client, mes->stream); return -1; } ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream); mes->datalen = 0; mes->cmd = ROAR_CMD_OK; return 0; } // non-stream pass: ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): This is a client passfh", client, mes->stream); /* 0: Version, 16 1: Flags, 16 2: Protocol, 16 3: Byteorder, 16 Options... */ if ( mes->datalen < 4*2 ) return -1; for (i = 0; i < 4; i++) { d[i] = ROAR_NET2HOST16(d[i]); } if ( d[0] != 0 ) // version return -1; listening = d[1] & ROAR_CLIENTPASS_FLAG_LISTEN; if ( listening ) d[1] -= ROAR_CLIENTPASS_FLAG_LISTEN; if ( d[1] != 0 ) // flags return -1; if ( listening ) { if ( get_listen(&lsock, NULL) == -1 ) { close(fh); return -1; } roar_vio_open_fh_socket(&(lsock->sock), fh); lsock->used = 1; lsock->proto = d[2]; } else { if ( clients_new_from_fh(fh, d[2], d[3], 1) == -1 ) return -1; } ROAR_DBG("req_on_passfh(client=%i, mes={stream=%i,...},...): returning (OK)...", client, mes->stream); mes->datalen = 0; mes->cmd = ROAR_CMD_OK; return 0; } #ifdef ROAR_SUPPORT_META int req_on_set_meta (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { int type; int mode; int namelen, vallen; char val[255+1]; char name[ROAR_META_MAX_NAMELEN+1]; if ( mes->datalen < 3 ) return -1; if ( mes->data[0] != 0 ) // version return -1; mode = (unsigned) mes->data[1]; type = (unsigned) mes->data[2]; ROAR_DBG("req_on_set_meta(*): mode=%i, type=%i", mode, type); if ( mode == ROAR_META_MODE_CLEAR ) { stream_meta_clear(mes->stream); mes->datalen = 0; mes->cmd = ROAR_CMD_OK; return 0; } else if ( mode == ROAR_META_MODE_DELETE ) { // unsuppoerted at the moment return -1; } else if ( mode == ROAR_META_MODE_FINALIZE ) { stream_meta_finalize(mes->stream); mes->datalen = 0; mes->cmd = ROAR_CMD_OK; return 0; } else if ( mode == ROAR_META_MODE_SET || mode == ROAR_META_MODE_ADD ) { if ( mes->datalen < 5 ) return -1; namelen = (unsigned) mes->data[3]; vallen = (unsigned) mes->data[4]; ROAR_DBG("req_on_set_meta(*): namelen=%i, vallen=%i", namelen, vallen); if ( mes->datalen < (5 + namelen + vallen) ) return -1; if ( namelen > ROAR_META_MAX_NAMELEN ) return -1; strncpy(name, &(mes->data[5]), namelen); name[namelen] = 0; if ( vallen > 255 ) return -1; strncpy(val, &(mes->data[5+namelen]), vallen); val[vallen] = 0; if ( mode == ROAR_META_MODE_SET ) { if ( stream_meta_set(mes->stream, type, name, val) == -1 ) return -1; } else { if ( stream_meta_add(mes->stream, type, name, val) == -1 ) return -1; } mes->datalen = 0; mes->cmd = ROAR_CMD_OK; return 0; } else { // unknown mode! return -1; } return -1; } int req_on_get_meta (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { int vallen; int type; char val[LIBROAR_BUFFER_MSGDATA-1]; if ( mes->datalen != 2 ) return -1; if ( mes->data[0] != 0 ) // version return -1; type = (unsigned) mes->data[1]; if ( stream_meta_get(mes->stream, type, NULL, val, LIBROAR_BUFFER_MSGDATA-2) == -1 ) return -1; vallen = strlen(val); mes->cmd = ROAR_CMD_OK; mes->datalen = 2 + vallen; mes->data[0] = 0; mes->data[1] = (unsigned char) vallen; val[vallen] = 0; strncpy(&(mes->data[2]), val, vallen+1); return 0; } int req_on_list_meta (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { int i; int len = 0; int types[ROAR_META_MAX_PER_STREAM]; if ( mes->datalen != 1 ) return -1; if ( mes->data[0] != 0 ) // version return -1; if ( (len = stream_meta_list(mes->stream, types, ROAR_META_MAX_PER_STREAM)) == -1 ) return -1; mes->cmd = ROAR_CMD_OK; mes->datalen = 1 + len; mes->data[0] = 0; for (i = 0; i < len; i++) mes->data[i+1] = types[i]; return 0; } #endif int req_on_gettimeofday (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_time curtime; ROAR_DBG("req_on_gettimeofday(client=%i, mes=%p, data=%p, flags=%p) = ?", client, mes, data, flags); if ( *data != NULL ) { return -1; } ROAR_DBG("req_on_gettimeofday(client=%i, mes=%p, data=%p, flags=%p) = ?", client, mes, data, flags); if ( mes->datalen && mes->datalen < 8 ) { return -1; } ROAR_DBG("req_on_gettimeofday(client=%i, mes=%p, data=%p, flags=%p) = ?", client, mes, data, flags); if ( mes->datalen >= 8 ) { if ( *(uint64_t *)mes->data != 0 ) { return -1; } } ROAR_DBG("req_on_gettimeofday(client=%i, mes=%p, data=%p, flags=%p) = ?", client, mes, data, flags); if ( roar_clock_gettime(&curtime, ROAR_CLOCK_REALTIME) == -1 ) return -1; if ( roar_time_to_msg(mes, &curtime) == -1 ) return -1; mes->cmd = ROAR_CMD_OK; ROAR_DBG("req_on_gettimeofday(client=%i, mes=%p, data=%p, flags=%p) = ?", client, mes, data, flags); return 0; } int req_on_server_info (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { #ifdef ROAR_HAVE_UNAME struct utsname utsname; #endif #ifdef ROAR_HAVE_GETVERSIONEX OSVERSIONINFO osinfo; char buf_release[80]; #endif struct roar_server_info info; uint16_t * d16; #ifdef ROAR_HAVE_GETHOSTID long hostid; char hostidbuf[64]; #endif if ( mes->datalen != 4 ) return -1; d16 = (uint16_t*)mes->data; // check version. if ( ROAR_NET2HOST16(d16[0]) != 0 ) return -1; switch (ROAR_NET2HOST16(d16[1])) { case ROAR_IT_SERVER: memset(&info, 0, sizeof(info)); // the following if is optimized out by compiler. if ( ROAR_VERSION_DISTRIBUTION_STRING[0] == 0 ) { info.version = "roard/" ROAR_VERSION_STRING " <" ROAR_DEV_VENDOR_STRING ">"; } else { info.version = "roard/" ROAR_VERSION_STRING " <" ROAR_DEV_VENDOR_STRING "> (" ROAR_VERSION_DISTRIBUTION_STRING ")"; } info.build = ROAR_BUILD_STAMP; info.license = ROAR_LICENSE_GPLv3_0; #ifdef ROAR_HAVE_GETHOSTID hostid = gethostid(); snprintf(hostidbuf, sizeof(hostidbuf), sizeof(long) == 8 ? "0x%.16lx" : "0x%.8lx", hostid); info.hostid = hostidbuf; #endif if ( !!strcmp(g_config->location, CONF_DEF_STRING) ) info.location = g_config->location; if ( !!strcmp(g_config->description, CONF_DEF_STRING) ) info.description = g_config->description; info.contact = g_config->contact; info.serial = g_config->serial; info.uiurl = g_config->uiurl; #ifdef ROAR_HAVE_UNAME if ( uname(&utsname) == 0 ) { roar_random_salt_nonce(&utsname, sizeof(utsname)); info.un.sysname = utsname.sysname; info.un.release = utsname.release; info.un.nodename = utsname.nodename; info.un.machine = utsname.machine; } #endif #ifdef ROAR_HAVE_GETVERSIONEX osinfo.dwOSVersionInfoSize = sizeof(osinfo); if ( GetVersionEx(&osinfo) ) { info.un.sysname = "Windows"; snprintf(buf_release, sizeof(buf_release), "%i.%i.%i", (int)osinfo.dwMajorVersion, (int)osinfo.dwMinorVersion, (int)osinfo.dwBuildNumber); buf_release[sizeof(buf_release)-1] = 0; info.un.release = buf_release; } #endif *data = NULL; if ( roar_server_info_to_mes(mes, &info, (void**)data) == -1 ) return -1; if ( *data != NULL ) flags[1] |= COMMAND_FLAG_OUT_LONGDATA; break; default: /* unknown request */ return -1; break; } mes->cmd = ROAR_CMD_OK; return 0; } int req_on_server_oinfo (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_stream s; int dir = ROAR_DIR_PLAY; int subsys; //ROAR_DIR_OUTPUT if ( mes->datalen != 0 ) { if ( mes->datalen != 2 ) return -1; if ( mes->data[0] != 0 ) return -1; dir = mes->data[1]; } subsys = streams_dir2subsys(dir); memset(&s, 0, sizeof(struct roar_stream)); s.dir = ROAR_DIR_MIXING; s.pos_rel_id = -1; switch (subsys) { case ROAR_SUBSYS_WAVEFORM: s.info.rate = g_sa->rate; s.info.bits = g_sa->bits; s.info.channels = g_sa->channels; s.info.codec = g_sa->codec; s.pos = g_pos; break; #ifndef ROAR_WITHOUT_DCOMP_MIDI case ROAR_SUBSYS_MIDI: break; #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT case ROAR_SUBSYS_LIGHT: s.info.rate = ROAR_OUTPUT_CFREQ; s.info.bits = ROAR_LIGHT_BITS; s.info.channels = g_light_state.channels; break; #endif #ifndef ROAR_WITHOUT_DCOMP_RAW case ROAR_SUBSYS_RAW: // no need to set anything here. break; #endif #ifndef ROAR_WITHOUT_DCOMP_RDTCS case ROAR_SUBSYS_RDTCS: s.info.rate = ROAR_OUTPUT_CFREQ; s.info.bits = ROAR_RDTCS_BITS; s.info.channels = ROAR_RDTCS_CHANNELS; s.info.codec = ROAR_RDTCS_CODEC; break; #endif default: return -1; break; } if ( roar_stream_s2m(&s, mes) == -1 ) return -1; mes->cmd = ROAR_CMD_OK; return 0; } int req_on_caps (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_caps caps; struct roar_stds * stds; size_t i; if ( roar_caps_from_msg(&caps, mes, *data) == -1 ) return -1; // handle the data from the caps command here... if ( !(caps.flags & ROAR_CF_REQUEST) ) { mes->cmd = ROAR_CMD_OK; mes->datalen = 0; return 0; } mes->datalen = 0; switch (caps.type) { case ROAR_CT_STANDARDS: if ( (stds = roar_stds_new(g_caps_stds.stds_len)) == NULL ) return -1; for ( i = 0; i < stds->stds_len; i++) { stds->stds[i] = ROAR_HOST2NET32(g_caps_stds.stds[i]); } caps.data = stds->stds; caps.len = stds->stds_len * 4; // TODO: add support for **data. if ( roar_caps_to_msg(mes, &caps, NULL) == -1 ) { roar_stds_free(stds); return -1; } roar_stds_free(stds); break; default: return -1; break; } mes->cmd = ROAR_CMD_OK; return 0; } int req_on_get_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 2; *((uint16_t*)mes->data) = ROAR_HOST2NET16((unsigned) g_standby); return 0; } int req_on_set_standby (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { if ( mes->datalen != 2 ) return -1; g_standby = ROAR_NET2HOST16(*((uint16_t*)mes->data)); mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 0; return 0; } int req_on_exit (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { int term = 0; if ( mes->datalen == 1 ) term = mes->data[0]; mes->cmd = ROAR_CMD_OK; mes->pos = g_pos; mes->datalen = 0; ROAR_DBG("req_on_exit(*): term=%i", term); if ( term ) { cleanup_listen_socket(1); } else { alive = 0; } return 0; } int req_on_list_clients(int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { unsigned char filter, cmp; uint32_t id; int clients[ROAR_CLIENTS_MAX]; int i, c = 0; if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 ) return -1; // TODO: add code to support filter if ( filter != ROAR_CTL_FILTER_ANY ) return -1; for (i = 0; i < ROAR_CLIENTS_MAX; i++) { if ( g_clients[i] != NULL ) { clients[c++] = i; } } roar_ctl_ia2m(mes, clients, c); mes->cmd = ROAR_CMD_OK; return 0; } int req_on_list_streams(int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { unsigned char filter, cmp; uint32_t id; int streams[ROAR_STREAMS_MAX]; int i, c = 0; int match; if ( roar_ctl_m2f(mes, &filter, &cmp, &id) == -1 ) return -1; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] == NULL ) continue; match = 0; switch (filter) { case ROAR_CTL_FILTER_ANY: match = 1; break; case ROAR_CTL_FILTER_DIR: match = roar_filter_match(cmp, id, ROAR_STREAM(g_streams[i])->dir); break; default: // unsupported filter... return -1; break; } if ( match ) streams[c++] = i; } roar_ctl_ia2m(mes, streams, c); mes->cmd = ROAR_CMD_OK; return 0; } int req_on_get_client (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_client * c; int ret; if ( mes->datalen != 1 ) return -1; if ( *data != NULL ) roar_mm_free(*data); *data = NULL; if ( clients_get(mes->data[0], &c) == -1 ) return -1; mes->cmd = ROAR_CMD_OK; ret = roar_ctl_c2m2(mes, c, (void**)data); if ( *data != NULL ) flags[1] |= COMMAND_FLAG_OUT_LONGDATA; return ret; } int req_on_get_stream (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_stream_server * s; if ( mes->datalen != 1 ) return -1; if ( streams_get(mes->data[0], &s) == -1 ) return -1; mes->cmd = ROAR_CMD_OK; mes->stream = mes->data[0]; return roar_stream_s2m(ROAR_STREAM(s), mes); } int req_on_get_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_stream * s; struct roar_stream_server * ss; struct roar_audio_info * audio_info; struct roar_stream_ltm * ltm; struct roar_stream_rpg rpg; uint16_t * d = (uint16_t *) mes->data; int64_t * d64 = ( int64_t *) mes->data; int64_t * d64ptr; int i, h, k; char * str; size_t needed; int test, bits; ROAR_DBG("req_on_get_stream_para(client=%i, mes=%p{.stream=%i, .datalen=%i,...}, data=%p, flags=%p) = ?", client, mes, (int)mes->stream, (int)mes->datalen, data, flags); if ( mes->datalen < 4 ) return -1; for (i = 0; i < 2; i++) { d[i] = ROAR_NET2HOST16(d[i]); } if ( d[0] != 0 ) { ROAR_WARN("req_on_get_stream_para(*): unsupported command version: %i, %i", (int)d[0], (int)d[1]); return -1; } switch (d[1]) { case ROAR_STREAM_PARA_INFO: if ( streams_get(mes->stream, &ss) == -1 ) { ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream); return -1; } if ( streams_calc_delay(mes->stream) == -1 ) { ROAR_WARN("req_on_get_stream_para(*): can not calc delay for stream %i", mes->stream); } s = ROAR_STREAM(ss); audio_info = &(s->info); mes->datalen = 2*12; d[ 2] = ROAR_OUTPUT_CALC_OUTBUFSIZE(audio_info); d[ 3] = ss->pre_underruns; d[ 4] = ss->post_underruns; d[ 5] = ss->codec_orgi; d[ 6] = (ss->flags & 0xFFFF) | (ss->primary ? ROAR_FLAG_PRIMARY : 0) | (ss->driver_id != -1 ? ROAR_FLAG_OUTPUT : 0); d[ 7] = ss->delay/1000; d[ 8] = ss->state; d[ 9] = (ss->flags & 0xFFFF0000) >> 16; d[10] = ss->mixer_stream; d[11] = ss->role; ROAR_DBG("req_on_get_stream_para(*): ss->driver_id=%i", ss->driver_id); ROAR_DBG("req_on_get_stream_para(*): delay=%i, send delay=%i", ss->delay, d[7]); for (i = 0; i < mes->datalen/2; i++) { d[i] = ROAR_HOST2NET16(d[i]); } mes->pos = s->pos; break; case ROAR_STREAM_PARA_NAME: str = streams_get_name(mes->stream); if ( str == NULL ) return -1; mes->datalen = 4 + strlen(str); if ( mes->datalen > LIBROAR_BUFFER_MSGDATA ) return -1; strncpy(((char*)&(mes->data))+4, str, mes->datalen); d[0] = ROAR_HOST2NET16(d[0]); d[1] = ROAR_HOST2NET16(d[1]); break; case ROAR_STREAM_PARA_CHANMAP: if ( streams_get(mes->stream, &ss) == -1 ) { ROAR_WARN("req_on_get_stream_para(*): request on non existing (or other error?) stream %i", mes->stream); return -1; } s = ROAR_STREAM(ss); memcpy(&(mes->data[4]), ss->chanmap.in, s->info.channels); mes->datalen = 2*2 + s->info.channels; d[0] = ROAR_HOST2NET16(d[0]); d[1] = ROAR_HOST2NET16(d[1]); break; case ROAR_STREAM_PARA_LTM: ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM request...", client); if ( mes->datalen < (6 * 2) ) { ROAR_ERR("req_on_get_stream_para(client=%i, ...): LTM request of client is corruped: message too short", client); return -1; } for (i = 2; i < mes->datalen/2; i++) { d[i] = ROAR_NET2HOST16(d[i]); } if ( d[2] != ROAR_LTM_SST_GET_RAW ) { ROAR_ERR("req_on_get_stream_para(client=%i, ...): LTM request of client is corruped: unknown LTM subtype: %i", client, (int)d[2]); return -1; } ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM request of type GET_RAW", client); test = d[5]; bits = 0; while (test) { if ( test & 0x1 ) bits++; test >>= 1; } needed = 0; if ( mes->stream == -1 ) { ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM multi-stream request...", client); for (i = 6; i < mes->datalen/2; i++) { if ( (ltm = streams_ltm_get(d[i], d[5], d[3])) == NULL ) return -1; needed += ltm->channels; } } else { ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM single-stream request for stream %i...", client, mes->stream); if ( (ltm = streams_ltm_get(mes->stream, d[5], d[3])) == NULL ) return -1; needed = ltm->channels; } needed *= bits; needed += mes->stream == -1 ? (mes->datalen/2) - 6 : 1; ROAR_DBG("req_on_get_stream_para(client=%i, ...): data size for answer is %i 64 bit sub-packets", client, (int)needed); ROAR_DBG("req_on_get_stream_para(client=%i, ...): mes->datalen=%i, data=%p{%p}", client, (int)mes->datalen, data, *data); d64 = _dataspace(mes, data, flags, needed * 8); ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data); if ( (d = roar_mm_malloc(mes->datalen)) == NULL ) return -1; ROAR_DBG("req_on_get_stream_para(client=%i, ...): d=%p, data=%p{%p}", client, d, data, *data); ROAR_DBG("req_on_get_stream_para(client=%i, ...): mes->datalen=%i, data=%p{%p}", client, (int)mes->datalen, data, *data); ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data); memcpy(d, mes->data, mes->datalen); ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data); d64ptr = d64; ROAR_DBG("req_on_get_stream_para(client=%i, ...): mes->datalen=%i, data=%p{%p}", client, (int)mes->datalen, data, *data); ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data); if ( mes->stream == -1 ) { for (i = 6; i < mes->datalen/2; i++) { ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data); if ( (ltm = streams_ltm_get(d[i], d[5], d[3])) == NULL ) return -1; *d64ptr = ltm->channels & 0xFFFF; d64ptr++; for (h = 0; h < ltm->channels; h++) { for (k = 0; k < ROAR_LTM_MTBITS; k++) { if ( d[5] & (1<cur[h].rms; break; default: ROAR_ERR("req_on_get_stream_para(client=%i, ...): client requets unknown MT for LTM: bit %i", client, k); } d64ptr++; } } } } } else { if ( (ltm = streams_ltm_get(mes->stream, d[5], d[3])) == NULL ) return -1; *d64ptr = ltm->channels & 0xFFFF; d64ptr++; for (h = 0; h < ltm->channels; h++) { for (k = 0; k < ROAR_LTM_MTBITS; k++) { if ( d[5] & (1<cur[h].rms; ROAR_DBG("req_on_get_stream_para(client=%i, ...): rms=%lli to %p", client, (long long int)*d64ptr, d64ptr); break; default: ROAR_ERR("req_on_get_stream_para(client=%i, ...): client requets unknown MT for LTM: bit %i", client, k); } d64ptr++; } } } } ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data); roar_mm_free(d); for (i = 0; i < needed; i++) { d64[i] = ROAR_HOST2NET64(d64[i]); } mes->datalen = needed * 8; ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM d64=%p, d64ptr=%p", client, d64, d64ptr); ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM final message has %i byte of data", client, (int)mes->datalen); ROAR_DBG("req_on_get_stream_para(client=%i, ...): d64=%p, data=%p{%p}", client, d64, data, *data); ROAR_DBG("req_on_get_stream_para(client=%i, ...): LTM GET_RAW request: OK. returning...", client); break; case ROAR_STREAM_PARA_RPG: if ( streams_get_rpg(mes->stream, &rpg) == -1 ) { return -1; } mes->datalen = 2*5; d[2] = rpg.mode; d[3] = rpg.mul; d[4] = rpg.div; for (i = 0; i < mes->datalen/2; i++) { d[i] = ROAR_HOST2NET16(d[i]); } break; default: ROAR_WARN("req_on_get_stream_para(*): unsupported command: %i", d[1]); return -1; } ROAR_DBG("req_on_get_stream_para(client=%i, mes=%p{.stream=%i, .datalen=%i,...}, data=%p, flags=%p) = 0 // returning OK", client, mes, (int)mes->stream, (int)mes->datalen, data, flags); mes->cmd = ROAR_CMD_OK; return 0; } int req_on_set_stream_para (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_stream_server * ss; struct roar_stream_rpg rpg; uint16_t * d = (uint16_t *) mes->data; uint32_t tmp, tmp2, flagstore; int protect = 0; int i; if ( mes->datalen < 2*2 ) return -1; for (i = 0; i < 2; i++) { d[i] = ROAR_NET2HOST16(d[i]); } if ( d[0] != 0 ) return -1; switch (d[1]) { case ROAR_STREAM_PARA_FLAGS: if ( mes->datalen != 2*4 && mes->datalen != 2*5 ) return -1; d[2] = ROAR_NET2HOST16(d[2]); d[3] = ROAR_NET2HOST16(d[3]); ROAR_DBG("req_on_set_stream_para(*): request seems to be valid"); tmp = 0; if ( mes->datalen == 2*5 ) { d[4] = ROAR_NET2HOST16(d[4]); tmp = d[4]; tmp <<= 16; } tmp |= d[3]; if ( d[2] & ROAR_PROTECT_FLAG ) { protect = 1; d[2] -= ROAR_PROTECT_FLAG; } switch (d[2]) { case ROAR_SET_FLAG: if ( streams_set_flag(mes->stream, tmp) == -1 ) return -1; break; case ROAR_RESET_FLAG: if ( streams_reset_flag(mes->stream, tmp) == -1 ) return -1; break; case ROAR_NOOP_FLAG: break; case ROAR_TOGGLE_FLAG: if ( streams_get(mes->stream, &ss) == -1 ) return -1; flagstore = ss->flags; tmp2 = flagstore & tmp; // those are the flags we need to reset. ROAR_DBG("req_on_set_stream_para(*): tmp2=0x%.8lx", (long int)tmp2); if ( tmp2 ) if ( streams_reset_flag(mes->stream, tmp2) == -1 ) return -1; tmp2 = (flagstore ^ tmp) & tmp; // those are the flags we need to set. ROAR_DBG("req_on_set_stream_para(*): tmp2=0x%.8lx", (long int)tmp2); if ( tmp2 ) if ( streams_set_flag(mes->stream, tmp2) == -1 ) return -1; break; default: return -1; break; } ROAR_DBG("req_on_set_stream_para(*): protect=%i", protect); if ( protect ) if ( streams_protect_flag(mes->stream, tmp) == -1 ) return -1; break; case ROAR_STREAM_PARA_CHANMAP: if ( streams_set_map(mes->stream, &(mes->data[4]), mes->datalen - 4) == -1 ) return -1; break; case ROAR_STREAM_PARA_ROLE: if ( mes->datalen != 2*3 ) return -1; d[2] = ROAR_NET2HOST16(d[2]); if ( streams_set_role(mes->stream, d[2]) == -1 ) return -1; break; case ROAR_STREAM_PARA_LTM: if ( mes->datalen < (6 * 2) ) return -1; for (i = 2; i < mes->datalen/2; i++) { d[i] = ROAR_NET2HOST16(d[i]); } if ( mes->stream == -1 ) { for (i = 6; i < mes->datalen/2; i++) if ( streams_ltm_ctl(d[i], d[5], d[3], d[2]) == -1 ) return -1; } else { if ( streams_ltm_ctl(mes->stream, d[5], d[3], d[2]) == -1 ) return -1; } break; case ROAR_STREAM_PARA_RPG: if ( mes->datalen != (5 * 2) ) return -1; for (i = 2; i < mes->datalen/2; i++) { d[i] = ROAR_NET2HOST16(d[i]); } rpg.mode = d[2]; rpg.mul = d[3]; rpg.div = d[4]; if ( streams_set_rpg(mes->stream, &rpg) == -1 ) return -1; break; default: ROAR_WARN("req_on_set_stream_para(*): unsupported command version: %i, %i", d[0], d[1]); return -1; break; } mes->cmd = ROAR_CMD_OK; mes->datalen = 0; return 0; } int req_on_kick (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_stream_server * ss; uint16_t * info = (uint16_t *) mes->data; int is_stream = 0; if ( mes->datalen != 4 ) return -1; info[0] = ROAR_NET2HOST16(info[0]); info[1] = ROAR_NET2HOST16(info[1]); switch (info[0]) { case ROAR_OT_CLIENT: clients_delete(info[1]); break; case ROAR_OT_STREAM: is_stream = 1; break; case ROAR_OT_SOURCE: if ( streams_get_flag(info[1], ROAR_FLAG_SOURCE) != 1 ) return -1; is_stream = 1; break; case ROAR_OT_OUTPUT: if ( streams_get(info[1], &ss) == -1 ) return -1; if ( ss->driver_id == -1 ) return -1; is_stream = 1; break; case ROAR_OT_MIXER: if ( streams_get(info[1], &ss) == -1 ) return -1; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_MIXING ) return -1; is_stream = 1; break; case ROAR_OT_BRIDGE: if ( streams_get(info[1], &ss) == -1 ) return -1; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_BRIDGE ) return -1; is_stream = 1; break; default: /* TODO: those types should be handled, too: #define ROAR_OT_SAMPLE 4 #define ROAR_OT_LISTEN 8 #define ROAR_OT_ACTION 9 #define ROAR_OT_MSGQUEUE 10 #define ROAR_OT_MSGBUS 11 */ return -1; break; } if ( is_stream ) { if ( streams_get_flag(info[1], ROAR_FLAG_IMMUTABLE) == 1 ) return -1; streams_delete(info[1]); } mes->cmd = ROAR_CMD_OK; mes->datalen = 0; return 0; } int req_on_attach (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { uint16_t * info = (uint16_t *) mes->data; if ( mes->datalen < 6 ) return -1; info[0] = ROAR_NET2HOST16(info[0]); info[1] = ROAR_NET2HOST16(info[1]); info[2] = ROAR_NET2HOST16(info[2]); if ( info[0] != 0 ) return -1; if ( info[1] == ROAR_ATTACH_SIMPLE ) { if ( client_stream_move(info[2], mes->stream) == -1 ) return -1; } else { return -1; } mes->cmd = ROAR_CMD_OK; mes->datalen = 0; return 0; } int req_on_set_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_mixer_settings tmpmixer; struct roar_stream_server * s; uint16_t * info = (uint16_t *) mes->data; uint16_t version; uint16_t scale = 65535; int stream; int i; int chans; ROAR_DBG("req_on_set_vol(*) = ?"); ROAR_DBG("req_on_set_vol(*): mes->datalen=%i", mes->datalen); if ( mes->datalen < (4*2) ) return -1; version = ROAR_NET2HOST16(info[0]); ROAR_DBG("req_on_set_vol(*): version=%i", (int)version); switch (version) { case 0: stream = ROAR_NET2HOST16(info[1]); break; case 1: stream = mes->stream; scale = ROAR_NET2HOST16(info[1]); break; default: return -1; break; } ROAR_DBG("req_on_set_vol(*): stream=%i", stream); if ( scale == 0 ) return -1; // TODO: change this code. // we should not directly change the stream object but use some stream_*()-func // for that job. if ( stream < 0 || stream >= ROAR_STREAMS_MAX ) return -1; s = g_streams[stream]; if ( s == NULL ) return -1; ROAR_DBG("req_on_set_vol(*): s=%p", s); info[2] = ROAR_NET2HOST16(info[2]); switch (info[2]) { case ROAR_SET_VOL_ALL: chans = (mes->datalen/2) - 3; ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ALL, channes=%i", chans); if ( chans >= ROAR_MAX_CHANNELS ) return -1; ROAR_DBG("req_on_set_vol(*): mixer at %p", s->mixer.mixer); for (i = 0; i < chans; i++) { s->mixer.mixer[i] = ROAR_NET2HOST16(info[i+3]); ROAR_DBG("req_on_set_vol(*): channel %i: %i", i, ROAR_NET2HOST16(info[i+3])); } s->mixer.scale = scale; ROAR_DBG("req_on_set_vol(*): mixer changed!"); break; case ROAR_SET_VOL_ONE: ROAR_DBG("req_on_set_vol(*): mode is ROAR_SET_VOL_ONE"); if ( ROAR_NET2HOST16(info[3]) >= ROAR_MAX_CHANNELS ) return -1; s->mixer.mixer[ROAR_NET2HOST16(info[3])] = ROAR_NET2HOST16(info[4]); s->mixer.scale = scale; break; case ROAR_SET_VOL_UNMAPPED: chans = (mes->datalen/2) - 3; if ( chans >= ROAR_MAX_CHANNELS ) return -1; memcpy(&tmpmixer, &(s->mixer), sizeof(tmpmixer)); for (i = 0; i < chans; i++) { tmpmixer.mixer[i] = ROAR_NET2HOST16(info[i+3]); } tmpmixer.scale = scale; if ( roar_conv_volume(&(s->mixer), &tmpmixer, ROAR_STREAM(s)->info.channels, chans) == -1 ) return -1; break; case ROAR_SET_VOL_MS: default: return -1; } if ( streams_set_mixer(stream) == -1 ) return -1; mes->cmd = ROAR_CMD_OK; mes->datalen = 0; return 0; } int req_on_get_vol (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { uint16_t * info = (uint16_t *) mes->data; uint16_t version = -1; int stream; struct roar_stream_server * s; int i; int chans; ROAR_DBG("req_on_get_vol(*) = ?"); ROAR_DBG("req_on_get_vol(*): mes->datalen=%i", mes->datalen); if ( mes->datalen < 2 ) { return -1; } version = ROAR_NET2HOST16(info[0]); switch (version) { case 0: if ( mes->datalen < (2*2) ) return -1; stream = ROAR_NET2HOST16(info[1]); break; case 1: stream = mes->stream; break; default: return -1; break; } ROAR_DBG("req_on_get_vol(*): stream=%i", stream); // TODO: change this code. // we should not directly change the stream object but use some stream_*()-func // for that job. if ( stream < 0 || stream >= ROAR_STREAMS_MAX ) return -1; s = g_streams[stream]; if ( s == NULL ) return -1; ROAR_DBG("req_on_get_vol(*): s=%p", s); // ok, we have everything info[0] = ROAR_HOST2NET16(version); switch (version) { case 0: info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels); for (i = 0; i < chans; i++) info[2+i] = ROAR_HOST2NET16(s->mixer.mixer[i]); mes->datalen = (2 + chans)*2; break; case 1: info[1] = ROAR_HOST2NET16(chans = ROAR_STREAM(s)->info.channels); info[2] = ROAR_HOST2NET16(s->mixer.scale); info[3] = ROAR_HOST2NET16(s->mixer.rpg_mul); info[4] = ROAR_HOST2NET16(s->mixer.rpg_div); for (i = 0; i < chans; i++) info[5+i] = ROAR_HOST2NET16(s->mixer.mixer[i]); mes->datalen = (5 + chans)*2; break; default: return -1; break; } mes->cmd = ROAR_CMD_OK; return 0; } int req_on_add_data (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_buffer * b; void * buf; if ( roar_buffer_new_data(&b, mes->datalen, &buf) == -1 ) { ROAR_ERR("req_on_add_data(*): Can not alloc buffer space!"); ROAR_DBG("req_on_add_data(*) = -1"); return -1; } if ( data == NULL ) { memcpy(buf, mes->data, mes->datalen); } else { memcpy(buf, *data, mes->datalen); } if ( stream_add_buffer(mes->stream, &b) == -1 ) { roar_buffer_free(b); return -1; } mes->cmd = ROAR_CMD_OK_STOP; mes->datalen = 0; return 0; } int req_on_beep (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { struct roar_beep bs; int16_t * info = (int16_t*)mes->data; int stream; memset(&bs, 0, sizeof(bs)); if ( mes->datalen > 0 ) { if ( mes->datalen < 2 ) return -1; if ( ROAR_NET2HOST16(info[0]) != 0 ) /* version */ return -1; if ( mes->datalen != 8*2 ) return -1; bs.vol = ROAR_NET2HOST16(info[1]); bs.time = ROAR_NET2HOST16(info[2]); bs.freq = ROAR_NET2HOST16(info[3]); bs.type = ROAR_NET2HOST16(info[4]); bs.x = ROAR_NET2HOST16(info[5]); bs.y = ROAR_NET2HOST16(info[6]); bs.z = ROAR_NET2HOST16(info[7]); } if ( (stream = beep_start(client, &bs)) == -1 ) return -1; mes->stream = stream; mes->cmd = ROAR_CMD_OK_STOP; mes->datalen = 0; return 0; } int req_on_wait (int client, struct roar_message * mes, char ** data, uint32_t flags[2]) { uint16_t * u16 = (uint16_t*)mes->data; struct roar_event events[4]; size_t left, tmp; size_t num = 0; void * vp = mes->data; vp += 4; // check for complet header... if ( mes->datalen < 4 ) return -1; u16[0] = ROAR_NET2HOST16(u16[0]); u16[1] = ROAR_NET2HOST16(u16[1]); // do we support version and flags? if ( u16[0] != 0 || u16[1] != 0 ) return -1; memset(events, 0, sizeof(events)); left = mes->datalen - 4; while (left) { tmp = left; if ( roar_event_from_blob(&(events[num]), vp, &tmp) == -1 ) return -1; vp += tmp; left -= tmp; num++; } if ( clients_wait(client, events, num) == -1 ) return -1; flags[1] |= COMMAND_FLAG_OUT_NOSEND; return 0; } //ll roaraudio-1.0beta11/roard/roard.c0000644000175000017500000023027312264733677015071 0ustar phiphi//roard.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* ckport options: * Stuff checked by configure: * ckport: ignore-symbol: getuid of target win32 * ckport: ignore-symbol: setuid of target win32 * ckport: ignore-symbol: getgid of target win32 * ckport: ignore-symbol: setgid of target win32 * ckport: ignore-symbol: setsid of target win32 * ckport: ignore-symbol: kill of target win32 * ckport: ignore-symbol: chroot of target win32 * ckport: ignore-symbol: fork of target win32 * ckport: ignore-symbol: getservbyname of target win32 * ckport: ignore-symbol: nice of target win32 * */ #include "roard.h" enum metaaction { MA_ACTION, MA_LIST_PROTO, MA_LIST_PLUGIN }; enum action { START, STOP, RESTART, RESTART_RETRY, SHUTDOWN }; enum af_mode { AF_MODE_NONE, AF_MODE_LOAD, AF_MODE_GEN }; // some stuff we only define extern globally. int g_verbose = ROAR_DBG_INFO_NONE; int alive; #ifdef ROAR_SUPPORT_LISTEN int g_no_listen; #endif uint32_t g_pos; // current position in output stream int g_standby; int g_autostandby; struct roard_listen g_listen[ROAR_MAX_LISTEN_SOCKETS]; int g_self_client; int g_terminate; struct roar_audio_info * g_sa, * g_max_sa; struct roard_config * g_config; struct counters g_counters; // end of extern block. #ifdef ROAR_SUPPORT_LISTEN static const char * server[ROAR_MAX_LISTEN_SOCKETS]; #endif #if defined(ROAR_HAVE_IO_POSIX) && defined(ROAR_HAVE_FS_POSIX) #define SUPPORT_PIDFILE static char * pidfile = NULL; #endif #if defined(ROAR_HAVE_SETGID) || defined(ROAR_HAVE_SETUID) static int setids = 0; #endif #ifdef ROAR_HAVE_LIBX11 static char * x11display = NULL; #endif #ifdef ROAR_HAVE_MAIN_ARGS void usage (void) { printf("Usage: roard [OPTIONS]...\n\n"); printf("Misc Options:\n\n"); printf( #if defined(ROAR_HAVE_FORK) || defined(ROAR_TARGET_WIN32) " --daemon - Bring the server into background after init\n" #endif " --verbose - Be more verbose, can be used multiple times\n" " --terminate - Terminate after last client quited\n" " --start - No op parameter (starting roard is default operation)\n" " --restart - Trys to stop an old instance and start a new with new settings\n" " --stop - Stops a running roard (provide --pidfile!)\n" " --shutdown - Terminates a running roard (provide --pidfile!)\n" " --realtime - Trys to get realtime priority,\n" " give multible times for being more realtime\n" " --memlock LEVEL - Set default memory locking level to LEVEL\n" " --watchdog - Enable watchdog\n" " --watchdog-time TIME - Set watchdog time to TIME (in ms)\n" #ifdef ROAR_HAVE_CHROOT " --chroot DIR - chroots to the given dir\n" #endif #ifdef ROAR_HAVE_SETGID " --setgid - GroupID to the audio group as specified via -G\n" #endif #ifdef ROAR_HAVE_SETUID " --setuid - UserID to the audio user as specified via -U\n" #endif " --sysclocksync - calculate exact sample rate using the system clock\n" " --location LOC - Set lion readable location of server\n" " --description DESC - Set lion readable description of server\n" " --contact CONTACT - Set contact for this server\n" " --serial SERIAL - Set serial for this device or server\n" " (for embedded devices only)\n" " --uiurl UIURL - Set URL for userinterface of this device or server\n" " (for embedded devices only)\n" #ifdef SUPPORT_PIDFILE " --pidfile PIDFILE - Write a pidfile at PIDFILE\n" #endif #ifdef ROAR_HAVE_SYSLOG " --log-syslog - Log Warnings, Errors, ... to syslog\n" #endif #ifdef ROAR_HAVE_SYSTEM " --script-postdown S - Run command lion S after complet shutdown.\n" #endif ); printf("\nAuth Options:\n\n"); printf( " --guest-acclev ACCLEV - Sets the access level for guest access to ACCLEV,\n" " Use \"none\" to disable guest access.\n" " --trust-acclev ACCLEV - Sets the access level for trust-authed\n" " connections to ACCLEV. Use \"none\" to disable trust auth.\n" " --trust-root - Trust root user\n" " --no-trust-root - Don't trust root user\n" " --authfile-gen FILE - Generate an new authfile\n" " --authfile-load FILE - Load an authfile\n" " --authfile-type TYPE - Type of authfile\n" " --authfile-acclev ACCLEV\n" " - Sets the access level for authfile\n" " --new-authfile - Parameters for new authfile follow\n" ); printf("\nPlugin Options:\n\n"); printf( " --plugin-load FILE - Load plugin FILE\n" " --plugin-args ARGS - Arguments for the plugin\n" " (must be given before the --plugin-load)\n" " --list-plugins - List loaded plugins\n" ); printf("\nAudio Options:\n\n"); printf( " -R --rate RATE - Set server rate\n" " -B --bits BITS - Set server bits\n" " -C --chans CHANNELS - Set server channels\n" " --aiprofile PROFILE - Use the given audio profile\n" ); printf("\nStream Options:\n\n"); printf( " --stream-flags D=F - Set default flags for stream directions\n" " D is the stream direction and F is a comma separated\n" " list of flags in form +flag or -flag to set or unset\n" " a flag as default or remove it from the default\n" ); printf("\nStream Options:\n\n"); printf( " --list-rolestack - Show the current role stack\n" " --rolestack-push R:A - Add a rule for role R with action A on top\n" " of the role stack.\n" ); printf("\nOutput Options:\n\n"); printf(" -o --odriver DRV - Set the driver, use '--list-driver' to get a list\n"); printf(" -O --odevice DEV - Set the device\n"); printf(" -oO OPTS - Set output options\n"); printf(" -oN - Adds another output\n"); printf(" -oP - Mark output as primary\n"); #ifdef ROAR_DRIVER_DEFAULT printf(" --list-driver - List all drivers (default driver: %s)\n", ROAR_DRIVER_DEFAULT); #else printf(" --list-driver - List all drivers (default driver: (autodetect))\n"); #endif #ifndef ROAR_WITHOUT_DCOMP_SOURCES printf("\nSource Options:\n\n"); printf(" -s --source DRV - Use DRV as input driver\n" " -S DEV - Use DEV as input device\n" " -sO OPTS - Use OPTS as input options\n" " -sN - Adds another source\n" " -sP - Make souce as primary\n" ); printf(" --list-sources - List all sources\n"); #endif #ifndef ROAR_WITHOUT_DCOMP_MIXER printf("\nHardware Mixer Options:\n\n"); printf(" -m --mixer DRV - Use DRV as mixer driver\n" " -M DEV - Use DEV as mixer device\n" " -mO OPTS - Use OPTS as mixer options\n" " -mN - Adds another mixer\n" " -mP - Make mixer as primary\n" ); printf(" --list-mixers - List all mixers\n"); #endif printf("\nCodec Filter Options:\n\n"); printf(" --list-cf - List all codec filter\n" ); #ifndef ROAR_WITHOUT_DCOMP_MIDI printf("\nMIDI Options:\n\n"); printf(" --midi-no-console - Disable console based MIDI synth\n" " --midi-console-enable - Enables the console based MIDI synth\n" " --midi-console DEV - Set device for MIDI console\n" #ifndef ROAR_WITHOUT_DCOMP_SSYNTH " --ssynth-enable - Enable simple software synth\n" " --ssynth-disable - Disable simple software synth\n" #endif ); #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT printf("\nLight Control Options:\n\n"); printf(" --light-channels NUM - Sets the number of channels for Light control (default: %i)\n", LIGHT_CHANNELS_DEFAULT ); #endif #ifndef ROAR_WITHOUT_DCOMP_RDTCS printf("\nRadio Data and Transmitter Control System Options:\n\n"); printf(" --rds-pi PI - Sets the RDS Programme Identification (PI)\n" " --rds-ps PS - Sets the RDS Programme Service Name (PS)\n" " --rds-pty PTY - Sets the RDS Programme Type (PTY)\n" " --rds-tp - Sets the RDS Traffic Programme (TP) flag\n" " --rds-ct - Enables sending of RDS Clock Time (CT)\n" ); #endif #ifdef ROAR_HAVE_LIBX11 printf("\nX11 Options:\n\n"); printf( " --x11-display DISPLAY - Set display for X11\n" " --display DISPLAY - Set display for X11\n" ); #endif printf("\nServer Options:\n\n"); printf(" -t --tcp - Use TCP listen socket\n" #ifdef ROAR_HAVE_UNIX " -u --unix - Use UNIX Domain listen socket (default)\n" #endif #ifdef ROAR_HAVE_LIBDNET " -n --decnet - use DECnet listen socket\n" #endif " -4 - Use IPv4 connections (implies -t)\n" #ifdef AF_INET6 " -6 - Use IPv6 connections (implies -t)\n" #endif #ifdef IPV6_ADDRFORM " -64 - Try to downgrade sockets from IPv6 into IPv4,\n" " this is normaly not useful.\n" #endif " -p --port - TCP Port to bind to\n" " -b --bind - IP/Hostname to bind to\n" " --sock - Filename for UNIX Domain Socket\n" " --proto PROTO - Use PROTO as protocol on Socket\n" " --proto-dir DIR - Set direction parameter for protocol\n" " --proto-rate RATE - Set sample rate parameter for protocol\n" " --proto-bits BITS - Set bits per sample parameter for protocol\n" " --proto-codec E - Set codec parameter for protocol\n" " --proto-chans C - Set number of channels parameter for protocol\n" " --proto-aiprofile PROFILE\n" " - Sets the audio profile for socket\n" " --proto-profile P - Set profile for listen socket\n" " --list-proto - List supported protocols\n" " --list-profiles - List supported profiles for --proto-profile\n" " --list-aiprofiles - List supported profiles for --proto-aiprofile\n" " --new-sock - Parameters for new socket follow\n" #ifdef ROAR_HAVE_LIBSLP " --slp - Enable OpenSLP support\n" #endif #ifdef ROAR_HAVE_LIBX11 " --x11 - Enable X11 support\n" #endif " --jumbo-mtu MTU - Sets the MTU for Jumbo Packets\n" " -G GROUP - Sets the group for the UNIX Domain Socket, (default: %s)\n" " You need the permissions to change the GID\n" " -U USER - Sets the user for the UNIX Domain Socket, (default: do not set)\n" " You need the permissions to change the UID (normaly only root has)\n" " --no-listen - Do not listen for new clients\n" " (only useful for relaing, impleys --terminate)\n" " --client-fh - Comunicate with a client over this handle\n" " (only useful for relaing)\n" " --close-fh - Closes the given fh\n" " --standby - Start in standby state\n" " --auto-standby - Automatical goes into standby if there are no streams\n", #ifdef ROAR_DEFAULT_SOCKGRP ROAR_DEFAULT_SOCKGRP #else "(none)" #endif ); // printf("\n Options:\n\n"); printf("\n"); } #endif struct counters * counters_getptr(void) { return &g_counters; } #define _pmsg(format, args...) roar_debug_msg(type, __LINE__, __FILE__, ROAR_DBG_PREFIX, format, ## args) #define _pmsgc(group, counter, name) _pmsg(" Counter %-10s: %" LIBROAR__ll "u", (name), (LIBROAR__longlong unsigned int)(counters->group.counter)) void counters_print(int type, int force) { struct counters * counters = counters_getptr(); if ( type != ROAR_DEBUG_TYPE_INFO || force || (ROAR_DBG_INFOVAR) >= ROAR_DBG_INFO_INFO ) { _pmsg("--- Counter Listing ---"); _pmsg(" Current:"); _pmsgc(cur, clients, "Clients"); _pmsgc(cur, streams, "Streams"); _pmsg(" Total:"); _pmsgc(sum, clients, "Clients"); _pmsgc(sum, streams, "Streams"); _pmsg("--- End of Counter Listing ---"); } } #undef _pmsgc #undef _pmsg int restart_server (const char * server, int terminate) { struct roar_connection con; #ifdef ROAR_HAVE_KILL char buf[80]; ssize_t l; struct roar_vio_calls fh; pid_t pid; int ok; ROAR_INFO("restart_server(server='%s', terminate=%i): trying to restart server", ROAR_DBG_INFO_INFO, server, terminate); if ( pidfile != NULL ) { if ( roar_vio_open_dstr_simple(&fh, pidfile, O_RDONLY) ) { ROAR_WARN("restart_server(*): Can not read pidfile: %s", pidfile); } else { l = roar_vio_read(&fh, buf, 80); roar_vio_close(&fh); if ( l > 0 ) { buf[l-1] = 0; buf[79] = 0; pid = atoi(buf); if ( terminate ) { ok = kill(pid, SIGUSR1); } else { ok = kill(pid, SIGINT); } if ( ok == 0 ) { return 0; } else { ROAR_WARN("restart_server(*): Can not kill roard by pidfile"); } } else { ROAR_WARN("restart_server(*): Can not find a PID in the pidfile"); } } } #endif if ( roar_simple_connect(&con, server, "roard") == -1 ) { return -1; } if ( roar_terminate(&con, terminate) == -1 ) { return -1; } return roar_disconnect(&con); } #define R_SETUID 1 #define R_SETGID 2 int init_config (void) { int i; memset(g_config, 0, sizeof(struct roard_config)); for (i = 0; i < ROAR_DIR_DIRIDS; i++) { g_config->streams[i].mixer_channels = 1; g_config->streams[i].mixer.rpg_mul = 1; g_config->streams[i].mixer.rpg_div = 1; g_config->streams[i].mixer.scale = 65535; g_config->streams[i].mixer.mixer[0] = g_config->streams[i].mixer.scale; g_config->streams[i].rpgmode = ROAR_RPGMODE_ALBUMTRACK; } g_config->streams[ROAR_DIR_PLAY ].flags = ROAR_FLAG_META; g_config->streams[ROAR_DIR_OUTPUT ].flags = ROAR_FLAG_PASSMIXER; g_config->streams[ROAR_DIR_FILTER ].flags = ROAR_FLAG_SYNC; g_config->streams[ROAR_DIR_MIDI_OUT].flags = ROAR_FLAG_SYNC; g_config->streams[ROAR_DIR_BIDIR ].flags = ROAR_FLAG_ANTIECHO; g_config->location = CONF_DEF_STRING; g_config->description = CONF_DEF_STRING; g_config->contact = NULL; g_config->serial = NULL; g_config->uiurl = NULL; g_config->memlock_level = -1; #ifdef ROAR_HAVE_SYSTEM g_config->scripts.post_shutdown = NULL; #endif return 0; } #ifdef ROAR_SUPPORT_LISTEN int init_listening (void) { int i; memset(g_listen, 0, sizeof(g_listen)); for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) { g_listen[i].proto = ROAR_PROTO_ROARAUDIO; server[i] = NULL; } return 0; } int get_listen(struct roard_listen ** sock, const char *** sockname) { int i; if ( sock == NULL ) return -1; for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) { if ( ! g_listen[i].used ) { server[i] = NULL; *sock = &(g_listen[i]); if ( sockname != NULL ) *sockname = &(server[i]); return 0; } } return -1; } #ifdef ROAR_SUPPORT_LISTEN static const struct _listen_profile { const char * name; int type; int port; const char * sockaddr; int proto; int dir; const char * aiprofile; const char * desc; } _g_listen_profiles[] = { // RoarAudio: #ifdef ROAR_HAVE_UNIX {"roar-usock", ROAR_SOCKET_TYPE_UNIX, 0, "~/" ROAR_DEFAULT_SOCK_USER, ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio default user profile"}, {"roar-gsock", ROAR_SOCKET_TYPE_UNIX, 0, ROAR_DEFAULT_SOCK_GLOBAL, ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio default global profile"}, #endif #ifdef ROAR_HAVE_IPV4 {"roar-tcp", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_PORT, ROAR_DEFAULT_INET4_HOST, ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio local TCP profile"}, {"roar-tcp-pub", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_PORT, ROAR_NET_INET4_ANYHOST, ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio network TCP profile"}, #endif #ifdef ROAR_HAVE_IPV6 {"roar-tcp6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_PORT, ROAR_DEFAULT_INET6_HOST, ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio local TCP profile"}, {"roar-tcp-pub6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_PORT, ROAR_NET_INET6_ANYHOST, ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio network TCP profile"}, #endif #ifdef ROAR_HAVE_LIBDNET {"roar-dnet", ROAR_SOCKET_TYPE_DECNET, 0, ROAR_DEFAULT_LISTEN_OBJECT, ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio default DECnet"}, #endif #ifdef ROAR_HAVE_UNIX {"roar-abstract", ROAR_SOCKET_TYPE_UNKNOWN, 0, "+abstract", ROAR_PROTO_ROARAUDIO, -1, NULL, "RoarAudio abstract namespace profile"}, #endif // EsounD: #if !defined(ROAR_WITHOUT_DCOMP_EMUL_ESD) && defined(ROAR_HAVE_H_ESD) #ifdef ROAR_HAVE_UNIX {"esd-unix", ROAR_SOCKET_TYPE_UNIX, 0, ROAR_DEFAULT_ESD_GSOCK, ROAR_PROTO_ESOUND, -1, NULL, "EsounD default local profile"}, #endif #ifdef ROAR_HAVE_IPV4 {"esd-tcp", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_ESD_PORT, ROAR_NET_INET4_LOCALHOST, ROAR_PROTO_ESOUND, -1, NULL, "EsounD local TCP profile"}, {"esd-tcp-pub", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_ESD_PORT, ROAR_NET_INET4_ANYHOST, ROAR_PROTO_ESOUND, -1, NULL, "EsounD network TCP profile"}, #endif #ifdef ROAR_HAVE_IPV6 {"esd-tcp6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_ESD_PORT, ROAR_NET_INET6_LOCALHOST, ROAR_PROTO_ESOUND, -1, NULL, "EsounD local TCP profile"}, {"esd-tcp-pub6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_ESD_PORT, ROAR_NET_INET6_ANYHOST, ROAR_PROTO_ESOUND, -1, NULL, "EsounD network TCP profile"}, #endif #endif // RSound: #ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND #ifdef ROAR_HAVE_UNIX {"rsound-unix", ROAR_SOCKET_TYPE_UNIX, 0, ROAR_DEFAULT_RSOUND_GSOCK, ROAR_PROTO_RSOUND, -1, NULL, "RSound default local profile"}, #endif #ifdef ROAR_HAVE_IPV4 {"rsound-tcp", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_RSOUND_PORT, ROAR_NET_INET4_LOCALHOST, ROAR_PROTO_RSOUND, -1, NULL, "RSound local TCP profile"}, {"rsound-tcp-pub", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_RSOUND_PORT, ROAR_NET_INET4_ANYHOST, ROAR_PROTO_RSOUND, -1, NULL, "RSound network TCP profile"}, #endif #ifdef ROAR_HAVE_IPV6 {"rsound-tcp6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_RSOUND_PORT, ROAR_NET_INET6_LOCALHOST, ROAR_PROTO_RSOUND, -1, NULL, "RSound local TCP profile"}, {"rsound-tcp-pub6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_RSOUND_PORT, ROAR_NET_INET6_ANYHOST, ROAR_PROTO_RSOUND, -1, NULL, "RSound network TCP profile"}, #endif #ifdef ROAR_HAVE_LIBDNET {"rsound-dnet", ROAR_SOCKET_TYPE_DECNET, 0, ROAR_DEFAULT_RSOUND_OBJECT, ROAR_PROTO_RSOUND, -1, NULL, "RSound DECnet profile"}, #endif #endif // PulseAudio Simple: #ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE #ifdef ROAR_HAVE_IPV4 {"pas-play-tcp", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_PA_PORT, ROAR_NET_INET4_ANYHOST, ROAR_PROTO_SIMPLE, ROAR_DIR_PLAY, "default", "PulseAudio Simple TCP play profile"}, {"pas-mon-tcp", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_PA_PORT, ROAR_NET_INET4_ANYHOST, ROAR_PROTO_SIMPLE, ROAR_DIR_MONITOR, "default", "PulseAudio Simple TCP monitor profile"}, #endif #ifdef ROAR_HAVE_IPV6 {"pas-play-tcp6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_PA_PORT, ROAR_NET_INET6_ANYHOST, ROAR_PROTO_SIMPLE, ROAR_DIR_PLAY, "default", "PulseAudio Simple TCP play profile"}, {"pas-mon-tcp6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_PA_PORT, ROAR_NET_INET6_ANYHOST, ROAR_PROTO_SIMPLE, ROAR_DIR_MONITOR, "default", "PulseAudio Simple TCP monitor profile"}, #endif #endif // RPlay: #ifndef ROAR_WITHOUT_DCOMP_EMUL_RPLAY #ifdef ROAR_HAVE_IPV4 {"rplay-tcp", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_RPLAY_PORT, ROAR_NET_INET4_LOCALHOST, ROAR_PROTO_RPLAY, -1, NULL, "RPlay local TCP profile"}, {"rplay-tcp-pub", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_RPLAY_PORT, ROAR_NET_INET4_ANYHOST, ROAR_PROTO_RPLAY, -1, NULL, "RPlay network TCP profile"}, #endif #ifdef ROAR_HAVE_IPV6 {"rplay-tcp6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_RPLAY_PORT, ROAR_NET_INET6_LOCALHOST, ROAR_PROTO_RPLAY, -1, NULL, "RPlay local TCP profile"}, {"rplay-tcp-pub6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_RPLAY_PORT, ROAR_NET_INET6_ANYHOST, ROAR_PROTO_RPLAY, -1, NULL, "RPlay network TCP profile"}, #endif #endif // Gopher: #ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER #ifdef ROAR_HAVE_IPV4 {"gopher-tcp", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_GOPHER_PORT, ROAR_NET_INET4_LOCALHOST, ROAR_PROTO_GOPHER, -1, NULL, "Gopher local TCP profile"}, {"gopher-tcp-pub", ROAR_SOCKET_TYPE_TCP, ROAR_DEFAULT_GOPHER_PORT, ROAR_NET_INET4_ANYHOST, ROAR_PROTO_GOPHER, -1, NULL, "Gopher network TCP profile"}, #endif #ifdef ROAR_HAVE_IPV6 {"gopher-tcp6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_GOPHER_PORT, ROAR_NET_INET6_LOCALHOST, ROAR_PROTO_GOPHER, -1, NULL, "Gopher local TCP profile"}, {"gopher-tcp-pub6", ROAR_SOCKET_TYPE_TCP6, ROAR_DEFAULT_GOPHER_PORT, ROAR_NET_INET6_ANYHOST, ROAR_PROTO_GOPHER, -1, NULL, "Gopher network TCP profile"}, #endif #endif // End of List: {NULL, -1, -1, NULL, -1, -1, NULL, NULL} }; void listen_listen_profiles (void) { const struct _listen_profile * p; char * type; int i; char port[8]; printf("Name Type Address Port Protocol Dir Audio Profile - Description\n"); printf("-------------------------------------------------------------------------------------------------\n"); //roar-tcp-pub 0.0.0.0 16002 RoarAudio unknown (null) - (null) for (i = 0; (p = &(_g_listen_profiles[i]))->name != NULL; i++) { switch (p->type) { case ROAR_SOCKET_TYPE_UNIX: type = "UNIX"; break; case ROAR_SOCKET_TYPE_TCP: type = "TCP"; break; case ROAR_SOCKET_TYPE_DECNET: type = "DECnet"; break; case ROAR_SOCKET_TYPE_TCP6: type = "TCP6"; break; default: type = "unknown"; break; } if ( p->port ) { snprintf(port, sizeof(port)-1, "%i", p->port); port[sizeof(port)-1] = 0; } else { strcpy(port, "(none)"); } printf("%-15s %-7s %-16s %-7s %-9s %-10s %-13s - %s\n", p->name, type, p->sockaddr, port, roar_proto2str(p->proto), p->dir == -1 ? "(none)" : roar_dir2str(p->dir), p->aiprofile == NULL ? "(none)" : p->aiprofile, p->desc == NULL ? "" : p->desc); } } int get_listen_profile (const char * name, int * port, const char ** sockaddr, int * type, int * proto, int * dir, struct roar_audio_info * info) { static char buf[1024]; const struct _listen_profile * p; int i; for (i = 0; (p = &(_g_listen_profiles[i]))->name != NULL; i++) { if ( !strcasecmp(p->name, name) ) { *port = p->port; if ( p->type == ROAR_SOCKET_TYPE_UNIX && p->sockaddr[0] != '+' ) { if ( roar_env_render_path_r(buf, sizeof(buf), p->sockaddr) == -1 ) continue; } else { strncpy(buf, p->sockaddr, sizeof(buf)); } *sockaddr = buf; *type = p->type; *proto = p->proto; *dir = p->dir; if ( p->aiprofile != NULL ) { if ( roar_profile2info(info, p->aiprofile) == -1 ) { ROAR_ERR("Unknown audio profile: %s", p->aiprofile); return -1; } } return 0; } } return -1; } #endif int add_listen (const char * addr, int port, int sock_type, char * user, char * group, int proto, int dir, struct roar_audio_info * info) { #if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_IO_POSIX) struct group * grp = NULL; #endif #if defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX) struct passwd * pwd = NULL; #endif #ifdef ROAR_HAVE_UNIX char * env_roar_proxy_backup; #endif int sockid = -1; #ifdef ROAR_HAVE_UNIX int sock; #endif int i; ROAR_INFO("add_listen(addr='%s', port=%i, sock_type=%i, user='%s', group='%s', proto=%s(%i), dir=%s(%i), info={.rate=%u, .bits=%u, .channels=%u, .codec=%s(%u)}): trying to add listen socket", ROAR_DBG_INFO_INFO, addr, port, sock_type, user, group, roar_proto2str(proto), proto, roar_dir2str(dir), dir, info->rate, info->bits, info->channels, roar_codec2str(info->codec), info->codec); if ( *addr != 0 ) { for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) { if ( ! g_listen[i].used ) { sockid = i; break; } } if ( sockid == -1 ) return -1; g_listen[sockid].proto = proto; ROAR_DBG("add_listen(*): proto=0x%.4x", proto); if ( roar_vio_open_socket_listen(&(g_listen[sockid].sock), sock_type, addr, port) == -1 ) { #ifdef ROAR_HAVE_UNIX if ( *addr == '/' ) { if ( (env_roar_proxy_backup = (char*)roar_env_get("ROAR_PROXY")) != NULL ) { env_roar_proxy_backup = roar_mm_strdup(env_roar_proxy_backup); unsetenv("ROAR_PROXY"); } if ( (sock = roar_socket_connect(ROAR_SOCKET_TYPE_UNKNOWN, addr, port)) != -1 ) { close(sock); ROAR_ERR("Can not open listen socket: Socket allready in use"); return -1; } else { unlink(addr); if ( roar_vio_open_socket_listen(&(g_listen[sockid].sock), sock_type, addr, port) == -1 ) { ROAR_ERR("Can not open listen socket: %s", strerror(errno)); return -1; } } if ( env_roar_proxy_backup != NULL ) { setenv("ROAR_PROXY", env_roar_proxy_backup, 0); roar_mm_free(env_roar_proxy_backup); } #else if (0) { // noop #endif } else { ROAR_ERR("Can not open listen socket: %s", strerror(errno)); return -1; } } ROAR_DBG("add_listen(*) = ?"); #if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_IO_POSIX) if ( group != NULL ) { if ( (grp = getgrnam(group)) == NULL ) { ROAR_ERR("Can not get GID for group %s: %s", group, strerror(errno)); } } #endif ROAR_DBG("add_listen(*) = ?"); #if defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX) if ( user != NULL ) { if ( (pwd = getpwnam(user)) == NULL ) { ROAR_ERR("Can not get UID for user %s: %s", user, strerror(errno)); } } #endif ROAR_DBG("add_listen(*) = ?"); #if defined(ROAR_HAVE_IO_POSIX) && defined(ROAR_HAVE_UNIX) if ( *addr == '/' ) { if ( grp != NULL || pwd != NULL ) { if ( chown(addr, pwd != NULL ? pwd->pw_uid : (uid_t)-1, grp != NULL ? grp->gr_gid : (gid_t)-1) == -1 ) return -1; } #ifdef ROAR_HAVE_GETUID if ( grp != NULL ) { if ( getuid() == 0 ) if ( chmod(addr, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1 ) return -1; } #endif } #endif } ROAR_DBG("add_listen(*) = ?"); // in case we opened the listening socket correctly. if ( dir == -1 ) dir = ROAR_DIR_PLAY; g_listen[sockid].inst.stpl.dir = dir; memcpy(&(g_listen[sockid].inst.stpl.info), info, sizeof(struct roar_audio_info)); switch (dir) { case ROAR_DIR_PLAY: case ROAR_DIR_RECORD: case ROAR_DIR_MONITOR: case ROAR_DIR_FILTER: case ROAR_DIR_BIDIR: case ROAR_DIR_RECPLAY: if ( !g_listen[sockid].inst.stpl.info.rate ) g_listen[sockid].inst.stpl.info.rate = g_sa->rate; if ( !g_listen[sockid].inst.stpl.info.bits ) g_listen[sockid].inst.stpl.info.bits = g_sa->bits; if ( !g_listen[sockid].inst.stpl.info.channels ) g_listen[sockid].inst.stpl.info.channels = g_sa->channels; if ( !g_listen[sockid].inst.stpl.info.codec ) g_listen[sockid].inst.stpl.info.codec = g_sa->codec; break; } g_listen[sockid].used = 1; server[sockid] = addr; return 0; } static int check_listen(void) { const struct roard_proto_handle * proto; const char * protoname; char buffer[80]; size_t i, j; for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) { if ( g_listen[i].used ) { proto = clients_get_protohandle(g_listen[i].proto); if ( proto != NULL ) continue; protoname = roar_proto2str(g_listen[i].proto); if ( protoname == NULL ) { ROAR_ERR("check_listen(void): protocol %i is unknown (protocol ID not assigned?).", g_listen[i].proto); } else { ROAR_DBG("check_listen(void): Unknown protocol %s(%i) is used.", protoname, g_listen[i].proto); snprintf(buffer, sizeof(buffer), "protocol-%s", protoname); for (j = 0; buffer[j]; j++) buffer[j] = tolower(buffer[j]); ROAR_DBG("check_listen(void): Trying to load plugin \"%s\"", buffer); if ( plugins_load(buffer, NULL) == -1 ) { ROAR_WARN("check_listen(void): unabled to load plugin: %s: %s", buffer, roar_errorstring); } } // recheck: proto = clients_get_protohandle(g_listen[i].proto); if ( proto == NULL ) { ROAR_WARN("check_listen(void): Protocol %s(%i) is still unknown. Deleting listen socket.", protoname, g_listen[i].proto); roar_vio_close(&(g_listen[i].sock)); #ifdef ROAR_HAVE_UNIX if ( server[i] != NULL ) if ( server[i][0] == '/' ) unlink(server[i]); #endif g_listen[i].used = 0; server[i] = NULL; } } } return 0; } #endif #ifdef ROAR_HAVE_MAIN_ARGS static void list_aiprofiles (void) { struct roar_audio_info info; const char * list[1024]; const char * mime; ssize_t ret; ssize_t i; ret = roar_profiles_list(list, 1024, 0); if ( ret == -1 ) return; printf(" Name Rate Bits Channels Codec\n"); printf("-----------------------------------------------------------------------------\n"); for (i = 0; i < ret; i++) { if ( roar_profile2info(&info, list[i]) == -1 ) { printf(" %-10s --- unknown parameters ---\n", list[i]); continue; } mime = roar_codec2mime(info.codec); printf(" %-16s %5u %4u %8u %3u (%s%s%s%s)\n", list[i], info.rate, info.bits, info.channels, info.codec, roar_codec2str(info.codec), info.codec == ROAR_CODEC_DEFAULT ? " native" : "", mime == NULL ? "" : " mimetype:", mime == NULL ? "" : mime ); } } #endif int update_stream_flags (char * str) { int dir; char * flags; char * k; int op; int flag; if ( (flags = strstr(str, "=")) == NULL ) return -1; *flags = 0; flags++; if ( (dir = roar_str2dir(str)) == -1 ) return -1; while (flags != NULL) { k = flags; flags = strstr(flags, ","); if ( flags != NULL ) *(flags++) = 0; switch (*k) { case '+': k++; op = ROAR_SET_FLAG; break; case '-': k++; op = ROAR_RESET_FLAG; break; default: op = ROAR_SET_FLAG; } flag = 0; if ( !strcmp(k, "sync") ) { flag = ROAR_FLAG_SYNC; } else if ( !strcmp(k, "meta") ) { flag = ROAR_FLAG_META; } else if ( !strcmp(k, "cleanmeta") ) { flag = ROAR_FLAG_CLEANMETA; } else if ( !strcmp(k, "pause") ) { flag = ROAR_FLAG_PAUSE; } else if ( !strcmp(k, "mute") ) { flag = ROAR_FLAG_MUTE; } else if ( !strcmp(k, "antiecho") ) { flag = ROAR_FLAG_ANTIECHO; } else if ( !strcmp(k, "passmixer") ) { flag = ROAR_FLAG_PASSMIXER; } else if ( !strcmp(k, "recsource") ) { flag = ROAR_FLAG_RECSOURCE; } else { return -1; } g_config->streams[dir].flags |= flag; if ( op == ROAR_RESET_FLAG ) g_config->streams[dir].flags -= flag; } return 0; } int add_authfile (const char * file, const char * type, enum af_mode mode, enum roard_client_acclev acclev) { struct roar_authfile * authfile = NULL; struct roar_authfile_key * key = NULL; int af_type = ROAR_AUTHFILE_TYPE_AUTO; void * keydata; int i; if ( type == NULL ) { // noop. } else if ( !strcasecmp(type, "roar") ) { af_type = ROAR_AUTHFILE_TYPE_ROAR; } else if ( !strcasecmp(type, "roar") ) { af_type = ROAR_AUTHFILE_TYPE_ROAR; } else if ( !strcasecmp(type, "esd") ) { af_type = ROAR_AUTHFILE_TYPE_ESD; } else if ( !strcasecmp(type, "pulse") ) { af_type = ROAR_AUTHFILE_TYPE_PULSE; } else if ( !strcasecmp(type, "htpasswd") ) { af_type = ROAR_AUTHFILE_TYPE_HTPASSWD; } else if ( !strcasecmp(type, "xauth") ) { af_type = ROAR_AUTHFILE_TYPE_XAUTH; } else { ROAR_ERR("add_authfile(*): unknown authfile type '%s'.", type); return -1; } if ( mode == AF_MODE_GEN && af_type == ROAR_AUTHFILE_TYPE_AUTO ) af_type = ROAR_AUTHFILE_TYPE_ESD; switch (mode) { case AF_MODE_NONE: return 0; break; case AF_MODE_GEN: switch (af_type) { case ROAR_AUTHFILE_TYPE_ESD: key = roar_authfile_key_new_random(ROAR_AUTH_T_COOKIE, 16, NULL); break; case ROAR_AUTHFILE_TYPE_PULSE: key = roar_authfile_key_new_random(ROAR_AUTH_T_COOKIE, 256, NULL); break; default: return -1; break; } if ( key == NULL ) { ROAR_ERR("add_authfile(*): Can not generate key."); return -1; } if ( (authfile = roar_authfile_open(af_type, file, 1, ROAR_AUTHFILE_VERSION_AUTO)) == NULL ) { roar_authfile_key_unref(key); return -1; } if ( roar_authfile_add_key(authfile, key) == -1 ) { ROAR_WARN("add_authfile(*): Can not add key to authfile."); } keydata = roar_mm_memdup(key->data, key->len); if ( keydata == NULL ) { ROAR_WARN("add_authfile(*): Can not allocate memory for key."); } else if ( auth_addkey_cookie(acclev, keydata, key->len) == -1 ) { ROAR_WARN("add_authfile(*): Can not add key to internal key storage."); } roar_authfile_key_unref(key); if ( roar_authfile_close(authfile) != 0 ) return -1; return 0; break; case AF_MODE_LOAD: if ( (authfile = roar_authfile_open(af_type, file, 0, ROAR_AUTHFILE_VERSION_AUTO)) == NULL ) { return -1; } for (i = 0; ; i++) { key = roar_authfile_lookup_key(authfile, ROAR_AUTH_T_AUTO, i, NULL); if ( key == NULL ) break; if ( key->type == ROAR_AUTH_T_COOKIE ) { keydata = roar_mm_memdup(key->data, key->len); if ( keydata == NULL ) { ROAR_WARN("add_authfile(*): Can not allocate memory for key."); } else if ( auth_addkey_cookie(acclev, keydata, key->len) == -1 ) { ROAR_WARN("add_authfile(*): Can not add key to internal key storage."); } } else { ROAR_WARN("add_authfile(*): Unknown key type: %i", key->type); } roar_authfile_key_unref(key); } if ( roar_authfile_close(authfile) != 0 ) return -1; return 0; break; } return -1; } // X11: #ifdef ROAR_HAVE_LIBX11 int register_x11 (int unreg, const char * sockname) { struct roar_x11_connection * x11con = NULL; int ret = 0; if ( (x11con = roar_x11_connect(x11display)) == NULL ) { ROAR_ERR("Can not connect to X11 server for %sregistering", unreg ? "un" : ""); return -1; } if ( unreg ) { if ( roar_x11_delete_prop(x11con, "ROAR_SERVER") == -1 ) { ret = -1; ROAR_ERR("Error while unregistereing from X11"); } else { ROAR_INFO("Successfully unregistered from X11", ROAR_DBG_INFO_INFO); } } else { if ( roar_x11_set_prop(x11con, "ROAR_SERVER", sockname) == -1 ) { ret = -1; ROAR_ERR("Error while registereing to X11"); } else { ROAR_INFO("Successfully registered to X11", ROAR_DBG_INFO_INFO); } } roar_x11_disconnect(x11con); return ret; } #endif // SLP: void register_slp_callback(SLPHandle hslp, SLPError errcode, void * cookie) { (void)hslp; /* return the error code in the cookie */ *(SLPError*)cookie = errcode; } int register_slp (int unreg, const char * sockname) { #ifdef ROAR_HAVE_LIBSLP static int regged = 0; static const char * sn = NULL; SLPError err; SLPError callbackerr; SLPHandle hslp; char addr[1024]; char attr[1024] = ""; char * location; char * description; char * standards; if ( sockname != NULL ) sn = sockname; snprintf(addr, sizeof(addr), ROAR_SLP_URL_TYPE_ROAR "://%s", sn); err = SLPOpen("en", SLP_FALSE, &hslp); if (err != SLP_OK) { ROAR_ERR("Error opening slp handle: Error #%i", err); return -1; } if (!unreg) { if ( SLPEscape(g_config->location, &location, SLP_FALSE) != SLP_OK ) { ROAR_ERR("Error using SLPEscape() on server location, really bad!"); SLPClose(hslp); return -1; } if ( SLPEscape(g_config->description, &description, SLP_FALSE) != SLP_OK ) { ROAR_ERR("Error using SLPEscape() on server location, really bad!"); SLPClose(hslp); return -1; } standards = stds_string(); if ( standards == NULL ) { if ( (standards = roar_mm_malloc(1)) == NULL ) { SLPClose(hslp); return -1; } standards[0] = 0; } snprintf(attr, sizeof(attr), "(wave-rate=%i),(wave-channels=%i),(wave-bits=%i)," #ifndef ROAR_WITHOUT_DCOMP_LIGHT "(light-channels=%i)," #endif "(standards=%s)," "(location=%s),(description=%s)", g_sa->rate, g_sa->channels, g_sa->bits, #ifndef ROAR_WITHOUT_DCOMP_LIGHT g_light_state.channels, #endif standards, location, description ); roar_mm_free(standards); /* Register a service with SLP */ err = SLPReg(hslp, addr, SLP_LIFETIME_MAXIMUM, 0, attr, SLP_TRUE, register_slp_callback, &callbackerr); regged = 1; } else if ( unreg && regged ) { err = SLPDereg(hslp, addr, register_slp_callback, &callbackerr); regged = 0; } else { SLPClose(hslp); return -1; } /* err may contain an error code that occurred as the slp library */ /* _prepared_ to make the call. */ if ( err != SLP_OK ) { ROAR_ERR("Error (de)registering service with slp: Error #%i", err); return -1; } /* callbackerr may contain an error code (that was assigned through */ /* the callback cookie) that occurred as slp packets were sent on */ /* the wire */ if (callbackerr != SLP_OK) { ROAR_ERR("Error (de)registering service with slp: Error #%i", callbackerr); return -1; } SLPClose(hslp); return 0; #else return -1; #endif } static int auth_setup (enum roard_client_acclev none_acclev, enum roard_client_acclev trust_acclev, int trust_root, uid_t trust_uid, gid_t trust_gid) { union auth_typeunion * key; size_t i; // Info: // if a authlevel is <= ACCLEV_IDENTED we do not need to add this to the keyring // as ACCLEV_IDENTED is already gained if IDENTIFY call was done correctly. if ( !(none_acclev <= ACCLEV_IDENTED) ) { if ( auth_addkey_anonymous(none_acclev) == -1 ) return -1; } if ( !(trust_acclev <= ACCLEV_IDENTED) ) { if ( (key = auth_regkey_simple(ROAR_AUTH_T_TRUST, trust_acclev)) == NULL ) return -1; // zerosize all counters. memset(key, 0, sizeof(union auth_typeunion)); i = 0; if ( trust_uid != (uid_t)-1 ) key->trust.uids[i++] = trust_uid; #ifdef ROAR_ROOT_UID if ( trust_root ) key->trust.uids[i++] = ROAR_ROOT_UID; #endif key->trust.uids_len = i; i = 0; if ( trust_gid != (gid_t)-1 ) key->trust.gids[i++] = trust_gid; key->trust.gids_len = i; } return 0; } // MAIN: #ifdef ROAR_HAVE_MAIN_ARGS int main (int argc, char * argv[]) { #else int main (void) { #endif #ifdef ROAR_HAVE_MAIN_ARGS enum metaaction metaaction = MA_ACTION; enum action action = START; int i; char * k; enum output_format print_format = FORMAT_NATIVE; const struct rolestack * rolestack; const char * plugin_args = NULL; #endif #if defined(ROAR_SUPPORT_LISTEN) && defined(ROAR_HAVE_GETUID) char user_sock[80] = {0}; #endif struct roar_audio_info sa, max_sa; struct roard_config config; #if defined(ROAR_HAVE_FORK) || defined(ROAR_TARGET_WIN32) int daemon = 0; #endif int_least32_t watchdog_time = 0; // -1: default, 0: disabled, > 0: user set time. int realtime = 0; int sysclocksync = 0; // char * server = ROAR_DEFAULT_SOCK_GLOBAL; #ifdef ROAR_SUPPORT_LISTEN int port = ROAR_DEFAULT_PORT; const char * sock_addr = NULL; int sock_proto = ROAR_PROTO_ROARAUDIO; int sock_dir = -1; struct roar_audio_info sock_info = {0, 0, 0, 0}; #endif #ifndef ROAR_WITHOUT_DCOMP_SOURCES char * s_drv = NULL; char * s_dev = NULL; char * s_con = NULL; char * s_opt = NULL; int s_prim = 0; #endif char * o_drv = NULL; char * o_dev = NULL; char * o_opts = NULL; int o_prim = 0; int o_count = 0; #ifndef ROAR_WITHOUT_DCOMP_MIXER char * m_drv = NULL; char * m_dev = NULL; char * m_opts = NULL; int m_prim = 0; int m_count = 0; #endif enum roard_client_acclev none_acclev = ACCLEV_ALL; enum roard_client_acclev trust_acclev = ACCLEV_ALL; int trust_root = 1; char * af_file = NULL; char * af_type = NULL; enum af_mode af_mode = AF_MODE_NONE; enum roard_client_acclev af_acclev = ACCLEV_ALL; #ifndef ROAR_WITHOUT_DCOMP_LIGHT uint32_t light_channels = LIGHT_CHANNELS_DEFAULT; #endif #ifdef ROAR_DEFAULT_SOCKGRP char * sock_grp = ROAR_DEFAULT_SOCKGRP; #else char * sock_grp = NULL; #endif char * sock_user = NULL; #ifdef ROAR_SUPPORT_LISTEN int sock_type = ROAR_SOCKET_TYPE_UNKNOWN; #endif #ifdef ROAR_HAVE_LIBSLP int reg_slp = 0; #endif #ifdef ROAR_HAVE_LIBX11 int reg_x11 = 0; #endif #ifdef ROAR_HAVE_CHROOT char * chrootdir = NULL; #endif #if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_IO_POSIX) struct group * grp = NULL; #endif #if defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX) struct passwd * pwd = NULL; #endif #ifdef ROAR_HAVE_GETSERVBYNAME struct servent * serv = NULL; #endif struct roar_client * self = NULL; #ifdef ROAR_HAVE_LIBDNET char decnethost[80]; #endif #ifdef SUPPORT_PIDFILE struct roar_vio_calls pidfile_vio; #endif ROAR_DBG("main(*): starting roard..."); // NOTE: those to lions can generate a memory leak. The OS will clean that up on exit. if ( roar_env_get("ROAR_DRIVER") != NULL ) o_drv = roar_mm_strdup(roar_env_get("ROAR_DRIVER")); if ( roar_env_get("ROAR_DEVICE") != NULL ) o_dev = roar_mm_strdup(roar_env_get("ROAR_DEVICE")); g_standby = 0; g_autostandby = 0; alive = 1; #ifdef ROAR_SUPPORT_LISTEN g_no_listen = 0; #else g_terminate = 1; #endif g_verbose = ROAR_DBG_INFO_NONE; _LIBROAR_IGNORE_RET(roar_profile2info(&sa, "default-server")); g_sa = &sa; g_max_sa = &max_sa; memcpy(g_max_sa, g_sa, sizeof(max_sa)); counters_init(); g_config = &config; if ( init_config() == -1 ) { ROAR_ERR("Can not init default config!"); return 1; } // load config _LIBROAR_IGNORE_RET(roar_libroar_get_config()); // init notify core: // TODO: reconsider number of lists. if ( roar_notify_core_new_global(-1) == -1 ) { ROAR_ERR("Can not init notify core!"); return 1; } if ( roar_notify_core_register_proxy(NULL, roar_notify_proxy_std, NULL) == -1 ) { ROAR_ERR("Can not init notify core!"); return 1; } rolestack_init(); if ( auth_init() == -1 ) { ROAR_ERR("Can not init auth subsystem!"); return 1; } #ifdef ROAR_SUPPORT_LISTEN if ( init_listening() == -1 ) { ROAR_ERR("Can not init listening sockets!"); return 1; } #endif #ifndef ROAR_WITHOUT_DCOMP_MIDI if ( midi_init_config() == -1 ) { ROAR_ERR("Can not init MIDI config!"); return 1; } #endif #ifndef ROAR_WITHOUT_DCOMP_SSYNTH if ( ssynth_init_config() == -1 ) { ROAR_ERR("Can not init ssynth config!"); return 1; } #endif #ifndef ROAR_WITHOUT_DCOMP_RDTCS if ( rdtcs_init_config() == -1 ) { ROAR_ERR("Can not init RDTCS config!"); return 1; } #endif if ( plugins_preinit() == -1 ) { ROAR_ERR("Can not pre-init plugins!"); return 1; } #ifdef ROAR_SUPPORT_LISTEN #ifndef ROAR_TARGET_WIN32 sock_addr = ROAR_DEFAULT_SOCK_GLOBAL; #else sock_addr = ROAR_DEFAULT_HOST; #endif #ifdef ROAR_HAVE_GETUID if ( getuid() != 0 && roar_env_get("HOME") != NULL ) { /* snprintf(user_sock, 79, "%s/%s", (char*)getenv("HOME"), ROAR_DEFAULT_SOCK_USER); */ if ( roar_env_render_path_r(user_sock, sizeof(user_sock), "~/" ROAR_DEFAULT_SOCK_USER) == -1 ) { strncpy(user_sock, "/NX-SOCK", sizeof(user_sock)); } sock_addr = user_sock; ROAR_DBG("main(*): setting sock_addr='%s'", sock_addr); } #endif if ( roar_env_get("ROAR_SERVER") != NULL ) sock_addr = roar_env_get("ROAR_SERVER"); #endif if ( clients_init() == -1 ) { ROAR_ERR("Can not init clients!"); return 1; } if ( streams_init() == -1 ) { ROAR_ERR("Can not init streams!"); return 1; } if ( (g_self_client = clients_new()) == -1 ) { ROAR_ERR("Can not create self client!"); return 1; } #ifndef ROAR_WITHOUT_DCOMP_SOURCES if ( sources_init() == -1 ) { ROAR_ERR("Can not init sources!"); return 1; } if ( (sources_set_client(g_self_client)) == -1 ) { ROAR_ERR("Can not init set source client!"); return 1; } #endif #ifdef ROAR_HAVE_MAIN_ARGS for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "-h") == 0 || strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( strcmp(k, "--start") == 0 ) { // this is a no op action = START; } else if ( strcmp(k, "--restart") == 0 ) { action = RESTART; #ifdef ROAR_SUPPORT_LISTEN if ( restart_server(sock_addr, 1) == -1 ) { ROAR_WARN("Can not terminate old server (not running at %s?), will retry later.", sock_addr); action = RESTART_RETRY; } #else ROAR_ERR("--restart not supported"); #endif } else if ( strcmp(k, "--shutdown") == 0 ) { action = SHUTDOWN; } else if ( strcmp(k, "--stop") == 0 ) { action = STOP; } else if ( strcmp(k, "--demon") == 0 || strcmp(k, "--daemon") == 0 ) { #if defined(ROAR_HAVE_FORK) || defined(ROAR_TARGET_WIN32) daemon = 1; #else ROAR_ERR("--daemon not supported"); #endif } else if ( strcmp(k, "--verbose") == 0 ) { g_verbose++; } else if ( strcmp(k, "--print-format") == 0 ) { k = argv[++i]; if ( !strcasecmp(k, "native") ) { print_format = FORMAT_NATIVE; } else if ( !strcasecmp(k, "wiki") ) { print_format = FORMAT_WIKI; } else if ( !strcasecmp(k, "csv") ) { print_format = FORMAT_CSV; } else { ROAR_WARN("Unknown print format: %s", k); } } else if ( strcmp(k, "--print-format") == 0 ) { ROAR_CKHAVEARGS(1); } else if ( strcmp(k, "--terminate") == 0 ) { g_terminate = 1; } else if ( strcmp(k, "--sysclocksync") == 0 ) { sysclocksync = 1000; } else if ( strcmp(k, "--realtime") == 0 ) { realtime++; } else if ( strcmp(k, "--memlock") == 0 ) { ROAR_CKHAVEARGS(1); g_config->memlock_level = memlock_str2level(argv[++i]); } else if ( strcmp(k, "--watchdog") == 0 ) { if ( watchdog_time == 0 ) watchdog_time = -1; } else if ( strcmp(k, "--watchdog-time") == 0 ) { ROAR_CKHAVEARGS(1); watchdog_time = atoi(argv[++i]); } else if ( strcmp(k, "--chroot") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_HAVE_CHROOT chrootdir = argv[++i]; #else ROAR_ERR("--chroot not supported"); i++; #endif } else if ( strcmp(k, "--setgid") == 0 ) { #ifdef ROAR_HAVE_SETGID setids |= R_SETGID; #else ROAR_ERR("--setgid not supported"); #endif } else if ( strcmp(k, "--setuid") == 0 ) { #ifdef ROAR_HAVE_SETUID setids |= R_SETUID; #else ROAR_ERR("--setuid not supported"); #endif } else if ( strcmp(k, "--location") == 0 ) { ROAR_CKHAVEARGS(1); g_config->location = argv[++i]; } else if ( strcmp(k, "--description") == 0 ) { ROAR_CKHAVEARGS(1); g_config->description = argv[++i]; } else if ( strcmp(k, "--contact") == 0 ) { ROAR_CKHAVEARGS(1); g_config->contact = argv[++i]; } else if ( strcmp(k, "--serial") == 0 ) { ROAR_CKHAVEARGS(1); g_config->serial = argv[++i]; } else if ( strcmp(k, "--uiurl") == 0 ) { ROAR_CKHAVEARGS(1); g_config->uiurl = argv[++i]; } else if ( strcmp(k, "--pidfile") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef SUPPORT_PIDFILE pidfile = argv[++i]; #else ROAR_ERR("--pidfile not supported"); i++; #endif } else if ( strcmp(k, "--log-syslog") == 0 ) { #ifdef ROAR_HAVE_SYSLOG roar_debug_set_stderr_mode(ROAR_DEBUG_MODE_SYSLOG); #else ROAR_ERR("--log-syslog not supported"); #endif } else if ( strcmp(k, "--script-postdown") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_HAVE_SYSTEM g_config->scripts.post_shutdown = argv[++i]; #else ROAR_ERR("--script-postdown not supported"); i++; #endif } else if ( strcmp(k, "--plugin-load") == 0 ) { ROAR_CKHAVEARGS(1); if ( plugins_load(argv[++i], plugin_args) == -1 ) { ROAR_ERR("Can not load plugin"); } plugin_args = NULL; } else if ( strcmp(k, "--plugin-args") == 0 ) { ROAR_CKHAVEARGS(1); plugin_args = argv[++i]; } else if ( strcmp(k, "--list-plugins") == 0 ) { metaaction = MA_LIST_PLUGIN; } else if ( strcmp(k, "--guest-acclev") == 0 ) { ROAR_CKHAVEARGS(1); none_acclev = clients_str2acclev(argv[++i]); if ( none_acclev == -1 ) { ROAR_ERR("Invalid access level: %s", argv[i]); return 1; } } else if ( strcmp(k, "--trust-acclev") == 0 ) { ROAR_CKHAVEARGS(1); trust_acclev = clients_str2acclev(argv[++i]); if ( trust_acclev == -1 ) { ROAR_ERR("Invalid access level: %s", argv[i]); return 1; } } else if ( strcmp(k, "--trust-root") == 0 ) { trust_root = 1; } else if ( strcmp(k, "--no-trust-root") == 0 ) { trust_root = 0; } else if ( strcmp(k, "--authfile-gen") == 0 ) { ROAR_CKHAVEARGS(1); af_file = argv[++i]; af_mode = AF_MODE_GEN; } else if ( strcmp(k, "--authfile-load") == 0 ) { ROAR_CKHAVEARGS(1); af_file = argv[++i]; af_mode = AF_MODE_LOAD; } else if ( strcmp(k, "--authfile-type") == 0 ) { ROAR_CKHAVEARGS(1); af_type = argv[++i]; } else if ( strcmp(k, "--authfile-acclev") == 0 ) { ROAR_CKHAVEARGS(1); af_acclev = clients_str2acclev(argv[++i]); } else if ( strcmp(k, "--new-authfile") == 0 ) { if ( af_mode != AF_MODE_NONE ) { if ( add_authfile(af_file, af_type, af_mode, af_acclev) == -1 ) { ROAR_ERR("main(*): adding authfile '%s' failed!", af_file); } } af_file = NULL; af_type = NULL; af_mode = AF_MODE_NONE; af_acclev = ACCLEV_ALL; } else if ( strcmp(k, "--list-cf") == 0 ) { print_codecfilterlist(); return 0; } else if ( strcmp(k, "-R") == 0 || strcmp(k, "--rate") == 0 ) { ROAR_CKHAVEARGS(1); sa.rate = atoi(argv[++i]); } else if ( strcmp(k, "-B") == 0 || strcmp(k, "--bits") == 0 ) { ROAR_CKHAVEARGS(1); sa.bits = atoi(argv[++i]); } else if ( strcmp(k, "-C") == 0 || strcmp(k, "--chans") == 0 ) { ROAR_CKHAVEARGS(1); sa.channels = atoi(argv[++i]); } else if ( strcmp(k, "--aiprofile") == 0 ) { ROAR_CKHAVEARGS(1); if ( roar_profile2info(&sa, argv[++i]) == -1 ) { ROAR_ERR("Unknown audio profile: %s", argv[i]); return 1; } sa.codec = ROAR_CODEC_DEFAULT; } else if ( strcmp(k, "--stream-flags") == 0 ) { ROAR_CKHAVEARGS(1); if ( update_stream_flags(argv[++i]) == -1 ) { ROAR_ERR("Can not set stream flags"); return 1; } } else if ( strcmp(k, "--list-rolestack") == 0 ) { print_rolestack(); return 0; } else if ( strcmp(k, "--rolestack-push") == 0 ) { ROAR_CKHAVEARGS(1); if ( (rolestack = rolestack_parse(argv[++i])) == NULL ) { ROAR_ERR("Can not parse rolestack request: %s", roar_error2str(roar_error)); } else { if ( rolestack_push(rolestack) == -1 ) { ROAR_ERR("Can not push request to rolestack: %s", roar_error2str(roar_error)); } } } else if ( strcmp(k, "--list-aiprofiles") == 0 ) { list_aiprofiles(); return 0; } else if ( strcmp(k, "--list-driver") == 0 ) { print_driverlist(print_format); return 0; } else if ( strcmp(k, "-o") == 0 || strcmp(k, "--odriver") == 0 ) { ROAR_CKHAVEARGS(1); o_drv = argv[++i]; } else if ( strcmp(k, "-O") == 0 || strcmp(k, "--odevice") == 0 ) { ROAR_CKHAVEARGS(1); o_dev = argv[++i]; } else if ( strcmp(k, "-oO") == 0 ) { ROAR_CKHAVEARGS(1); o_opts = argv[++i]; } else if ( strcmp(k, "-oP") == 0 ) { o_prim = 1; } else if ( strcmp(k, "-oN") == 0 ) { if ( action == START || action == RESTART ) { if ( output_add(o_drv, o_dev, o_opts, o_prim, o_count) != -1 ) o_count++; o_drv = o_dev = o_opts = NULL; o_prim = 0; } } else if ( strcmp(k, "-s") == 0 || strcmp(k, "--source") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_SOURCES s_drv = argv[++i]; #else ROAR_ERR("main(*): No support for sources compiled in"); i++; #endif } else if ( strcmp(k, "-S") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_SOURCES s_dev = argv[++i]; #else ROAR_ERR("main(*): No support for sources compiled in"); i++; #endif } else if ( strcmp(k, "-sO") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_SOURCES s_opt = argv[++i]; #else ROAR_ERR("main(*): No support for sources compiled in"); i++; #endif } else if ( strcmp(k, "-sC") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_SOURCES s_con = argv[++i]; #else ROAR_ERR("main(*): No support for sources compiled in"); i++; #endif } else if ( strcmp(k, "-sP") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_SOURCES s_prim = 1; #else ROAR_ERR("main(*): No support for sources compiled in"); #endif } else if ( strcmp(k, "-sN") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_SOURCES if ( sources_add(s_drv, s_dev, s_con, s_opt, s_prim) == -1 ) { ROAR_ERR("main(*): adding source '%s' via '%s' failed!", s_dev, s_drv); } s_opt = s_dev = s_con = NULL; s_drv = NULL; s_prim = 0; #else ROAR_ERR("main(*): No support for sources compiled in"); #endif } else if ( strcmp(k, "--list-sources") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_SOURCES print_sourcelist(); return 0; #else ROAR_ERR("main(*): No support for sources compiled in"); return 1; #endif } else if ( strcmp(k, "-m") == 0 || strcmp(k, "--mixer") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_MIXER m_drv = argv[++i]; #else ROAR_ERR("main(*): No support for mixer compiled in"); return 1; #endif } else if ( strcmp(k, "-M") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_MIXER m_dev = argv[++i]; #else ROAR_ERR("main(*): No support for mixer compiled in"); return 1; #endif } else if ( strcmp(k, "-mO") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_MIXER m_opts = argv[++i]; #else ROAR_ERR("main(*): No support for mixer compiled in"); return 1; #endif } else if ( strcmp(k, "-mP") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_MIXER m_prim = 1; #else ROAR_ERR("main(*): No support for mixer compiled in"); return 1; #endif } else if ( strcmp(k, "-mN") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_MIXER if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) != -1 ) m_count++; m_drv = o_dev = o_opts = NULL; m_prim = 0; #else ROAR_ERR("main(*): No support for mixer compiled in"); return 1; #endif } else if ( strcmp(k, "--list-mixers") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_MIXER print_hwmixerlist(); return 0; #else ROAR_ERR("main(*): No support for mixer compiled in"); return 1; #endif } else if ( strcmp(k, "--light-channels") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_LIGHT light_channels = atoi(argv[++i]); #else ROAR_WARN("main(*): no light subsystem compiled in"); i++; #endif } else if ( strcmp(k, "--rds-pi") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_RDTCS g_rdtcs.rds.pi = atoi(argv[++i]); #else ROAR_WARN("main(*): no RDTCS subsystem compiled in"); i++; #endif } else if ( strcmp(k, "--rds-ps") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_RDTCS if ( rdtcs_rds_set_ps(argv[++i]) == -1 ) { ROAR_ERR("Can not set RDS PS to '%s' (longer than 8 chars?)", argv[i]); return 1; } #else ROAR_WARN("main(*): no RDTCS subsystem compiled in"); i++; #endif } else if ( strcmp(k, "--rds-pty") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_RDTCS if ( rdtcs_rds_set_pty(argv[++i]) == -1 ) { ROAR_ERR("Can not set RDS PTY to '%s'", argv[i]); return 1; } #else ROAR_WARN("main(*): no RDTCS subsystem compiled in"); i++; #endif } else if ( strcmp(k, "--rds-tp") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_RDTCS if ( rdtcs_rds_set_flag(RDTCS_RDS_FLAG_TP, 0) == -1 ) { ROAR_ERR("Can not set RDS TP flag"); return 1; } #else ROAR_WARN("main(*): no RDTCS subsystem compiled in"); #endif } else if ( strcmp(k, "--rds-ct") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_RDTCS if ( rdtcs_rds_set_flag(RDTCS_RDS_FLAG_CT, 0) == -1 ) { ROAR_ERR("Can not set RDS CT flag"); return 1; } #else ROAR_WARN("main(*): no RDTCS subsystem compiled in"); #endif } else if ( strcmp(k, "--midi-no-console") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_CB midi_config.init_cb = 0; #else // no warning here as this is the disable option #endif } else if ( strcmp(k, "--midi-console-enable") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_CB midi_config.init_cb = 1; #else ROAR_ERR("main(*): No support for MIDI subsystem part CB compiled in"); #endif } else if ( strcmp(k, "--midi-console") == 0 ) { ROAR_CKHAVEARGS(1); #ifndef ROAR_WITHOUT_DCOMP_CB midi_config.console_dev = argv[++i]; midi_config.init_cb = 1; #else ROAR_ERR("main(*): No support for MIDI subsystem part CB compiled in"); i++; #endif } else if ( strcmp(k, "--ssynth-enable") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_SSYNTH ssynth_conf.enable = 1; #else ROAR_ERR("main(*): No support for ssynth compiled in"); #endif } else if ( strcmp(k, "--ssynth-disable") == 0 ) { #ifndef ROAR_WITHOUT_DCOMP_SSYNTH ssynth_conf.enable = 0; #else // we can safely ignore the disable #endif } else if ( strcmp(k, "--x11-display") == 0 || strcmp(k, "--display") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_HAVE_LIBX11 x11display = argv[++i]; #else ROAR_ERR("No X11 support compiled in!"); return 1; #endif } else if ( strcmp(k, "-p") == 0 || strcmp(k, "--port") == 0 ) { ROAR_CKHAVEARGS(1); // This is only useful in INET not UNIX mode. #ifdef ROAR_SUPPORT_LISTEN if ( *sock_addr == '/' ) sock_addr = ROAR_DEFAULT_HOST; errno = 0; if ( (port = atoi(argv[++i])) < 1 ) { #ifdef ROAR_HAVE_GETSERVBYNAME if ( (serv = getservbyname(argv[i], "tcp")) == NULL ) { ROAR_ERR("Unknown service: %s: %s", argv[i], strerror(errno)); return 1; } // NOTE: we need to use ROAR_NET2HOST16() here even if s_port is of type int! ROAR_DBG("main(*): serv = {s_name='%s', s_aliases={...}, s_port=%i, s_proto='%s'}", serv->s_name, ROAR_NET2HOST16(serv->s_port), serv->s_proto); port = ROAR_NET2HOST16(serv->s_port); #else ROAR_ERR("invalite port number: %s", argv[i]); return 1; #endif } #endif } else if ( strcmp(k, "-b") == 0 || strcmp(k, "--bind") == 0 || strcmp(k, "--sock") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN sock_addr = argv[++i]; #else i++; #endif } else if ( strcmp(k, "--proto") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN if ( (sock_proto = roar_str2proto(argv[++i])) == -1 ) { ROAR_ERR("Unknown protocol: %s", argv[i]); return 1; } #endif } else if ( strcmp(k, "--proto-dir") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN if ( (sock_dir = roar_str2dir(argv[++i])) == -1 ) { ROAR_ERR("Unknown stream direction: %s", argv[i]); return 1; } #else i++; #endif } else if ( strcmp(k, "--proto-rate") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN sock_info.rate = atoi(argv[++i]); #else i++; #endif } else if ( strcmp(k, "--proto-bits") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN sock_info.bits = atoi(argv[++i]); #else i++; #endif } else if ( strcmp(k, "--proto-chans") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN sock_info.channels = atoi(argv[++i]); #else i++; #endif } else if ( strcmp(k, "--proto-codec") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN if ( (sock_info.codec = roar_str2codec(argv[++i])) == -1 ) { ROAR_ERR("Unknown codec: %s", argv[i]); return 1; } #else i++; #endif } else if ( strcmp(k, "--proto-aiprofile") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN if ( roar_profile2info(&sock_info, argv[++i]) == -1 ) { ROAR_ERR("Unknown audio profile: %s", argv[i]); return 1; } #else i++; #endif } else if ( strcmp(k, "--list-profiles") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN listen_listen_profiles(); return 0; #endif } else if ( strcmp(k, "--proto-profile") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_SUPPORT_LISTEN if ( get_listen_profile(argv[++i], &port, &sock_addr, &sock_type, &sock_proto, &sock_dir, &sock_info) == -1 ) { ROAR_ERR("Unknown listen profile: %s", argv[i]); return 1; } #else i++; #endif } else if ( strcmp(k, "--list-proto") == 0 ) { metaaction = MA_LIST_PROTO; } else if ( strcmp(k, "-t") == 0 || strcmp(k, "--tcp") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN if ( sock_type != ROAR_SOCKET_TYPE_TCP && sock_type != ROAR_SOCKET_TYPE_TCP6 ) sock_type = ROAR_SOCKET_TYPE_TCP; if ( *sock_addr == '/' ) sock_addr = ROAR_DEFAULT_HOST; #endif } else if ( strcmp(k, "-4") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN sock_type = ROAR_SOCKET_TYPE_TCP; if ( *sock_addr == '/' ) sock_addr = ROAR_DEFAULT_HOST; #endif } else if ( strcmp(k, "-6") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN #ifdef AF_INET6 sock_type = ROAR_SOCKET_TYPE_TCP6; if ( *sock_addr == '/' ) sock_addr = ROAR_DEFAULT_HOST; #else ROAR_ERR("No IPv6 support compiled in!"); return 1; #endif #endif } else if ( strcmp(k, "-u") == 0 || strcmp(k, "--unix") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN // ignore this case as it is the default behavor. sock_type = ROAR_SOCKET_TYPE_UNIX; #endif } else if ( strcmp(k, "-n") == 0 || strcmp(k, "--decnet") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN #ifdef ROAR_HAVE_LIBDNET port = ROAR_DEFAULT_NUM; strcpy(decnethost, ROAR_DEFAULT_LISTEN_OBJECT); sock_addr = decnethost; sock_type = ROAR_SOCKET_TYPE_DECNET; #else ROAR_ERR("No DECnet support compiled in!"); return 1; #endif #endif } else if ( strcmp(k, "--new-sock") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN if ( action == START || action == RESTART ) { if ( add_listen(sock_addr, port, sock_type, sock_user, sock_grp, sock_proto, sock_dir, &sock_info) != 0 ) { ROAR_ERR("Can not open listen socket!"); return 1; } } #endif } else if ( strcmp(k, "--slp") == 0 ) { #ifdef ROAR_HAVE_LIBSLP reg_slp = 1; #else ROAR_ERR("No OpenSLP support compiled in!"); return 1; #endif } else if ( strcmp(k, "--x11") == 0 ) { #ifdef ROAR_HAVE_LIBX11 reg_x11 = 1; #else ROAR_ERR("No X11 support compiled in!"); return 1; #endif } else if ( strcmp(k, "--jumbo-mtu") == 0 ) { ROAR_CKHAVEARGS(1); g_config->jumbo_mtu = atoi(argv[++i]); } else if ( strcmp(k, "-G") == 0 ) { ROAR_CKHAVEARGS(1); sock_grp = argv[++i]; } else if ( strcmp(k, "-U") == 0 ) { ROAR_CKHAVEARGS(1); sock_user = argv[++i]; } else if ( strcmp(k, "--no-listen") == 0 ) { #ifdef ROAR_SUPPORT_LISTEN sock_addr = ""; g_terminate = 1; g_no_listen = 1; #endif } else if ( strcmp(k, "--client-fh") == 0 ) { ROAR_CKHAVEARGS(1); if ( clients_new_from_fh(atoi(argv[++i]), ROAR_PROTO_ROARAUDIO, ROAR_BYTEORDER_NETWORK, 1) == -1 ) { ROAR_ERR("main(*): Can not set client's fh"); return 1; } } else if ( strcmp(k, "--close-fh") == 0 ) { ROAR_CKHAVEARGS(1); #ifdef ROAR_HAVE_IO_POSIX close(atoi(argv[++i])); #else i++; ROAR_WARN("can not close file handle %s (closing not supported)", argv[i]); #endif } else if ( strcmp(k, "--standby") == 0 ) { g_standby = 1; } else if ( strcmp(k, "--auto-standby") == 0 ) { g_autostandby = 1; } else { ROAR_ERR("Unknown option: %s", k); usage(); return 1; } } #endif #ifdef ROAR_HAVE_MAIN_ARGS if ( metaaction != MA_ACTION ) action = START; switch (action) { case START: // NO-OP. break; case RESTART: // NO-OP, done before. break; case STOP: #ifdef ROAR_SUPPORT_LISTEN if ( restart_server(sock_addr, 0) == -1 ) { ROAR_WARN("Can not stop old server (not running at %s?)", sock_addr); return 1; } return 0; #else ROAR_ERR("--stop not supported"); return 1; #endif break; case SHUTDOWN: #ifdef ROAR_SUPPORT_LISTEN if ( restart_server(sock_addr, 1) == -1 ) { ROAR_WARN("Can not terminate old server (not running at %s?)", sock_addr); return 1; } return 0; #else ROAR_ERR("--shutdown not supported"); return 1; #endif break; case RESTART_RETRY: #ifdef ROAR_SUPPORT_LISTEN if ( restart_server(sock_addr, 1) == -1 ) { ROAR_WARN("Can not terminate old server (again) (not running at %s?), tring to continue anyway", sock_addr); action = RESTART; } #endif break; } #endif // if g_verbose is high we load external debugging modules. if ( g_verbose >= 4 ) { if ( plugins_load("debug-notify", NULL) == -1 ) { ROAR_WARN("main(*): Can not load debugger plugin: %s", roar_error2str(roar_error)); } } if ( af_mode != AF_MODE_NONE ) { if ( add_authfile(af_file, af_type, af_mode, af_acclev) == -1 ) { ROAR_ERR("main(*): adding authfile '%s' failed!", af_file); } } #ifndef ROAR_WITHOUT_DCOMP_MIXER if ( m_drv != NULL ) { if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) == -1 ) { ROAR_ERR("main(*): adding mixer '%s' via '%s' failed!", m_dev, m_drv); } } #endif #ifndef ROAR_WITHOUT_DCOMP_SOURCES if ( s_drv != NULL || s_dev != NULL ) { if ( sources_add(s_drv, s_dev, s_con, s_opt, s_prim) == -1 ) { ROAR_ERR("main(*): adding source '%s' via '%s' failed!", s_dev, s_drv); } } #endif if ( output_add_default(o_drv, o_dev, o_opts, o_prim, o_count) == -1 ) { ROAR_ERR("Can not initialize default driver"); return 1; } ROAR_INFO("Server config: rate=%i, bits=%i, chans=%i", ROAR_DBG_INFO_NOTICE, sa.rate, sa.bits, sa.channels); if ( waveform_init() == -1 ) { ROAR_ERR("Can not initialize Waveform subsystem"); return 1; } #ifndef ROAR_WITHOUT_DCOMP_MIDI if ( midi_init() == -1 ) { ROAR_ERR("Can not initialize MIDI subsystem"); } #endif #ifndef ROAR_WITHOUT_DCOMP_SSYNTH if ( ssynth_init() == -1 ) { ROAR_ERR("Can not initialize ssynth subsystem"); } #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT if ( light_init(light_channels) == -1 ) { ROAR_ERR("Can not initialize light control subsystem"); } #endif #ifndef ROAR_WITHOUT_DCOMP_RDTCS if ( rdtcs_init() == -1 ) { ROAR_ERR("Can not initialize RDTCS subsystem"); } #endif if ( plugins_init() == -1 ) { ROAR_ERR("Can not initialize plugins"); } #ifdef ROAR_SUPPORT_LISTEN if ( !g_no_listen ) { if ( add_listen(sock_addr, port, sock_type, sock_user, sock_grp, sock_proto, sock_dir, &sock_info) != 0 ) { ROAR_ERR("Can not open listen socket!"); return 1; } } #endif if ( output_buffer_init(&sa) == -1 ) { ROAR_ERR("Can not init output buffer!"); return 1; } if ( samples_init() == -1 ) { ROAR_ERR("Can not init samples!"); return 1; } if ( check_listen() == -1 ) { ROAR_ERR("Can not check listen sockets. BAD."); return 1; } #ifdef ROAR_HAVE_MAIN_ARGS // check meta action now as everything is set up. switch (metaaction) { case MA_ACTION: /* noop */; break; case MA_LIST_PROTO: print_protolist(print_format); return 0; break; case MA_LIST_PLUGIN: print_pluginlist(print_format); return 0; break; } #endif // we should handle this on microcontrollers, too. #if !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_TARGET_WIN32) signal(SIGINT, on_sig_int); signal(SIGTERM, on_sig_term); signal(SIGCHLD, on_sig_chld); signal(SIGUSR1, on_sig_usr1); signal(SIGPIPE, SIG_IGN); // ignore broken pipes #endif if ( g_config->memlock_level == -1 ) { g_config->memlock_level = MEMLOCK_DEFAULT; // do not print warning in case of failure and useage of default level. memlock_set_level(g_config->memlock_level); } else { if ( memlock_set_level(g_config->memlock_level) == -1 ) { ROAR_WARN("Can not set memory locking level to target level."); } } if ( realtime ) { #ifdef DEBUG ROAR_WARN("compiled with -DDEBUG but realtime is enabled: for real realtime support compile without -DDEBUG"); #endif #ifdef ROAR_HAVE_NICE // this stupid error check is because type of returned data of nice() changed // too often. On some systems it may return 0/-1, on some new nice value or // mixed forms of both. errno = 0; (void)nice(-5*realtime); // -5 for each --realtime if ( errno ) { ROAR_WARN("Can not decrease nice value by %i: %s", 5*realtime, strerror(errno)); } #else ROAR_WARN("Can not decrease nice value by %i: %s", 5*realtime, strerror(errno)); #endif /* #ifdef __linux__ if ( ioprio_set(IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0)) == -1 ) ROAR_WARN("Can not set io priority: %s", strerror(errno)); #endif */ } #if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_IO_POSIX) if ( setids & R_SETGID ) { if ( sock_grp == NULL ) { ROAR_ERR("Can not set GID if no groupname is supplied"); return 1; } if ( (grp = getgrnam(sock_grp)) == NULL ) { ROAR_ERR("Can not get GID for group %s: %s", sock_grp, strerror(errno)); return 1; } if ( setgroups(0, (const gid_t *) NULL) == -1 ) { ROAR_ERR("Can not clear supplementary group IDs: %s", strerror(errno)); } if ( grp == NULL || setgid(grp->gr_gid) == -1 ) { ROAR_ERR("Can not set GroupID: %s", strerror(errno)); } } #endif clients_set_pid(g_self_client, getpid()); #ifdef ROAR_HAVE_GETUID clients_set_uid(g_self_client, getuid()); #endif #ifdef ROAR_HAVE_GETGID clients_set_gid(g_self_client, getgid()); #endif clients_get(g_self_client, &self); if ( self == NULL ) { ROAR_ERR("Can not get self client!"); return 1; } strcpy(self->name, "RoarAudio daemon internal"); if ( roar_nnode_free(&(self->nnode)) == -1 ) return 1; // not fully correct but ok as workaorund // so tools assume that roard runs on the same machine as // they in case they use AF_UNIX: if ( roar_nnode_new(&(self->nnode), ROAR_SOCKET_TYPE_UNIX) == -1 ) return 1; #if defined(ROAR_HAVE_FORK) || defined(ROAR_TARGET_WIN32) if ( daemon ) { #ifdef ROAR_HAVE_SYSLOG roar_debug_set_stderr_mode(ROAR_DEBUG_MODE_SYSLOG); #else roar_debug_set_stderr_fh(-1); #endif #ifdef ROAR_TARGET_WIN32 FreeConsole(); #else close(ROAR_STDIN ); close(ROAR_STDOUT); close(ROAR_STDERR); if ( roar_fork(NULL) ) ROAR_U_EXIT(0); #ifdef ROAR_HAVE_SETSID setsid(); #endif clients_set_pid(g_self_client, getpid()); // reset pid as it changed #endif } #endif if ( watchdog_time ) { if ( watchdog_time == -1 ) watchdog_time = 5000; roar_watchdog_start(ROAR_WATCHDOG_CONF_DEFAULTS, watchdog_time, NULL); } #if defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX) // early test for UID as we need this for the pidfile and the setuid() if ( sock_user != NULL ) { if ( (pwd = getpwnam(sock_user)) == NULL ) { ROAR_ERR("Can not get UID for user %s: %s", sock_user, strerror(errno)); return 1; } } #endif ROAR_INFO("Process ID: %i", ROAR_DBG_INFO_INFO, (int)getpid()); #ifdef SUPPORT_PIDFILE if ( pidfile != NULL ) { if ( roar_vio_open_dstr_simple(&pidfile_vio, pidfile, O_WRONLY|O_CREAT) == -1 ) { ROAR_ERR("Can not write pidfile: %s", pidfile); } else { roar_vio_printf(&pidfile_vio, "%i\n", getpid()); roar_vio_close(&pidfile_vio); } #if defined(ROAR_HAVE_SETGID) && defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX) if ( pwd != NULL || grp != NULL ) { if ( chown(pidfile, pwd != NULL ? pwd->pw_uid : (uid_t)-1, grp != NULL ? grp->gr_gid : (gid_t)-1) == -1 ) { ROAR_WARN("Can not change ownership of pidfile: %s: %s", pidfile, strerror(errno)); } } if ( chmod(pidfile, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1 ) { ROAR_WARN("Can not change permissions of pidfile: %s: %s", pidfile, strerror(errno)); } #endif } #endif #ifdef ROAR_HAVE_CHROOT if (chrootdir) { if ( chroot(chrootdir) == -1 ) { ROAR_ERR("Can not chroot to %s: %s", chrootdir, strerror(errno)); return 2; } if ( chdir("/") == -1 ) { ROAR_ERR("Can not chdir to /: %s", strerror(errno)); return 2; } } #endif #if defined(ROAR_HAVE_SETUID) && defined(ROAR_HAVE_IO_POSIX) if ( setids & R_SETUID ) { if ( sock_user == NULL ) { ROAR_ERR("Can not set UID if no username is supplied"); return 1; } if ( pwd == NULL || setuid(pwd->pw_uid) == -1 ) { ROAR_ERR("Can not set UserID: %s", strerror(errno)); return 3; } #ifdef ROAR_HAVE_GETUID clients_set_uid(g_self_client, getuid()); #endif } #endif // setup auth: #if defined(ROAR_HAVE_GETUID) && defined(ROAR_HAVE_GETGID) if ( auth_setup(none_acclev, trust_acclev, trust_root, getuid(), getgid()) == -1 ) { #else if ( auth_setup(none_acclev, trust_acclev, trust_root, -1, -1) == -1 ) { #endif ROAR_ERR("Can not set up auth. Bad."); alive = 0; } // Register with OpenSLP: #ifdef ROAR_HAVE_LIBSLP if ( reg_slp ) { register_slp(0, sock_addr); } #endif #ifdef ROAR_HAVE_LIBX11 if ( reg_x11 ) { register_x11(0, sock_addr); } #endif // update sync counter. streams_change_sync_num(-1, 0); ROAR_INFO("Startup complet", ROAR_DBG_INFO_INFO); // start main loop... ROAR_INFO("Entering main loop", ROAR_DBG_INFO_INFO); main_loop(&sa, sysclocksync); ROAR_INFO("Left main loop", ROAR_DBG_INFO_INFO); // clean up. clean_quit_prep(); output_buffer_free(); roar_notify_core_free(NULL); ROAR_INFO("Shuting down complete", ROAR_DBG_INFO_INFO); #ifdef ROAR_HAVE_SYSTEM if ( g_config->scripts.post_shutdown != NULL ) system(g_config->scripts.post_shutdown); #endif ROAR_INFO("Exiting, no error", ROAR_DBG_INFO_INFO); return 0; } void cleanup_listen_socket (int terminate) { int i; ROAR_DBG("cleanup_listen_socket(terminate=%i) = (void)?", terminate); ROAR_INFO("Cleaning up listen sockets", ROAR_DBG_INFO_INFO); // Deregister from SLP: #ifdef ROAR_HAVE_LIBSLP register_slp(1, NULL); #endif #ifdef ROAR_HAVE_LIBX11 register_x11(1, NULL); #endif #ifdef ROAR_SUPPORT_LISTEN for (i = 0; i < ROAR_MAX_LISTEN_SOCKETS; i++) { if ( g_listen[i].used ) { roar_vio_close(&(g_listen[i].sock)); g_listen[i].used = 0; #ifdef ROAR_HAVE_UNIX if ( server[i] != NULL ) if ( *(server[i]) == '/' ) unlink(server[i]); #endif } } #endif if ( terminate ) g_terminate = 1; } void clean_quit_prep (void) { cleanup_listen_socket(0); plugins_free(); #ifndef ROAR_WITHOUT_DCOMP_SOURCES sources_free(); #endif streams_free(); clients_free(); #ifndef ROAR_WITHOUT_DCOMP_SSYNTH ssynth_free(); #endif #ifndef ROAR_WITHOUT_DCOMP_CB midi_cb_stop(); // stop console beep #endif #ifndef ROAR_WITHOUT_DCOMP_MIDI midi_free(); #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT light_free(); #endif #ifndef ROAR_WITHOUT_DCOMP_RDTCS rdtcs_free(); #endif waveform_free(); #ifdef SUPPORT_PIDFILE if ( pidfile != NULL ) unlink(pidfile); #endif auth_free(); } void clean_quit (void) { ROAR_INFO("Shuting down", ROAR_DBG_INFO_INFO); counters_print(ROAR_DEBUG_TYPE_INFO, 0); clean_quit_prep(); // output_buffer_free(); roar_notify_core_free(NULL); ROAR_INFO("Shuting down complete", ROAR_DBG_INFO_INFO); #ifdef ROAR_HAVE_SYSTEM if ( g_config->scripts.post_shutdown != NULL ) system(g_config->scripts.post_shutdown); #endif ROAR_INFO("Exiting, no error", ROAR_DBG_INFO_INFO); exit(0); } //ll roaraudio-1.0beta11/roard/rolestack.c0000644000175000017500000000674312264733677015754 0ustar phiphi//rolestack.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #define STACKSIZE 16 static struct rolestack g_rolestack[STACKSIZE]; void rolestack_init(void) { int i; for (i = 0; i < STACKSIZE; i++) { g_rolestack[i].index = i; g_rolestack[i].role = ROAR_ROLE_UNKNOWN; g_rolestack[i].action = RS_MIX; } g_rolestack[0].role = ROAR_ROLE_NONE; } void print_rolestack(void) { int i; printf("Index Role Action\n"); printf("-----------------------------\n"); for (i = 0; i < STACKSIZE && g_rolestack[i].role != ROAR_ROLE_UNKNOWN; i++) { printf("%-5i %-16s %s\n", g_rolestack[i].index, roar_role2str(g_rolestack[i].role), rolestack_action2str(g_rolestack[i].action)); } } const struct rolestack * rolestack_get_role(int role) { int i; ROAR_DBG("rolestack_get_role(role=%i) = ?", role); if ( role == -1 ) return &(g_rolestack[0]); for (i = STACKSIZE - 1; i >= 0; i--) if ( g_rolestack[i].role == role ) return &(g_rolestack[i]); return &(g_rolestack[0]); } int rolestack_push(const struct rolestack * role) { int i; for (i = 0; i < STACKSIZE; i++) { if ( g_rolestack[i].role == ROAR_ROLE_UNKNOWN ) { memcpy(&(g_rolestack[i]), role, sizeof(g_rolestack[i])); g_rolestack[i].index = i; return 0; } } roar_err_set(ROAR_ERROR_NOMEM); return -1; } enum rs_action rolestack_str2action(const char * str) { if ( str == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if (!strcasecmp(str, "mix")) { return RS_MIX; } else if (!strcasecmp(str, "kick")) { return RS_KICK; } else if (!strcasecmp(str, "mute")) { return RS_MUTE; } else if (!strcasecmp(str, "pause")) { return RS_PAUSE; } return RS_ERROR; } const char * rolestack_action2str(enum rs_action action) { switch (action) { case RS_ERROR: return "(error)"; break; case RS_MIX: return "mix"; break; case RS_MUTE: return "mute"; break; case RS_PAUSE: return "pause"; break; case RS_KICK: return "kick"; break; } return "(unknown)"; } const struct rolestack * rolestack_parse(const char * str) { static struct rolestack ret; char * role, * action; if ( str == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return NULL; } role = roar_mm_strdup(str); if ( role == NULL ) return NULL; if ( (action = strstr(role, ":")) == NULL ) { roar_mm_free(role); roar_err_set(ROAR_ERROR_BADMSG); return NULL; } *action = 0; action++; ret.index = -1; ret.role = roar_str2role(role); ret.action = rolestack_str2action(action); roar_mm_free(role); if ( ret.role == -1 || ret.action == RS_ERROR ) { roar_err_set(ROAR_ERROR_BADMSG); return NULL; } return &ret; } //ll roaraudio-1.0beta11/roard/sample.c0000644000175000017500000000470612264733677015243 0ustar phiphi//sample.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" // declared 'extern' struct roar_sample * g_samples[ROAR_SAMPLES_MAX]; int samples_init (void) { int i; for (i = 0; i < ROAR_SAMPLES_MAX; i++) g_samples[i] = NULL; return 0; } int samples_free (void) { int i; for (i = 0; i < ROAR_SAMPLES_MAX; i++) if ( g_samples[i] != NULL ) samples_delete(i); return 0; } int samples_new (void) { struct roar_sample * c = roar_mm_malloc(sizeof(struct roar_sample)); int i; if ( c == NULL ) return -1; c->name[0] = 0; c->data = NULL; for (i = 0; i < ROAR_SAMPLES_MAX; i++) { if ( g_samples[i] == NULL ) { g_samples[i] = c; return i; } } roar_mm_free(c); return -1; } int samples_delete (int id) { struct roar_sample * c = g_samples[id]; if ( c == NULL ) return -1; if ( c->data != NULL ) roar_buffer_free(c->data); roar_mm_free(c); g_samples[id] = NULL; return 0; } int samples_set_name (int id, char * name) { struct roar_sample * c = g_samples[id]; if ( c == NULL ) return -1; strncpy(c->name, name, ROAR_BUFFER_NAME-1); c->name[ROAR_BUFFER_NAME-1] = 0; return 0; } int samples_add_data (int id, void * data, size_t len) { struct roar_buffer * new; struct roar_sample * c = g_samples[id]; int save_err; if ( c == NULL ) return -1; if ( roar_buffer_new(&new, len) == -1 ) return -1; if ( c->data == NULL ) { c->data = new; } else { if ( roar_buffer_moveinto(c->data, &new) == -1 ) { save_err = roar_error; roar_buffer_free(new); roar_err_set(save_err); return -1; } } return 0; } //ll roaraudio-1.0beta11/roard/signals.c0000644000175000017500000000326412264733700015403 0ustar phiphi//signals.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" // we should add signal handling on micro controllsers here. #if !defined(ROAR_TARGET_MICROCONTROLLER) && !defined(ROAR_TARGET_WIN32) void on_sig_int (int signum) { ROAR_INFO("got SIGINT", ROAR_DBG_INFO_NOTICE); // TODO: implement some kind of termonate/force depending on how many ^Cs we get on_sig_term(signum); } void on_sig_term (int signum) { (void)signum; ROAR_INFO("got SIGTERM (or called by SIGINT handler)", ROAR_DBG_INFO_NOTICE); alive = 0; clean_quit(); } void on_sig_chld (int signum) { (void)signum; ROAR_INFO("got SIGCHLD", ROAR_DBG_INFO_NOTICE); wait(NULL); signal(SIGCHLD, on_sig_chld); } void on_sig_usr1 (int signum) { (void)signum; ROAR_INFO("got SIGUSR1", ROAR_DBG_INFO_NOTICE); cleanup_listen_socket(1); } #endif //ll roaraudio-1.0beta11/roard/sources.c0000644000175000017500000003047112264733700015426 0ustar phiphi//sources.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_SOURCES static int g_source_client = -1; #define ROAR_SOURCE_DEFAULT "cf" struct roar_source g_source[] = { {"raw", "DSTR source", "/some/file", SRC_FLAG_FHSEC, ROAR_SUBSYS_WAVEFORM, NULL, sources_add_dstr}, {"cf", "Old CF source", "/some/file.ext", SRC_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, sources_add_cf, NULL}, {"roar", "New simple RoarAudio source", "some.host", SRC_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, sources_add_roar}, #ifndef ROAR_WITHOUT_DCOMP_CDRIVER {"oss", "OSS CDriver", "/dev/audio", SRC_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, sources_add_cdriver}, #endif {"radionoise", "Noise source at -102dB", NULL, SRC_FLAG_NONE, ROAR_SUBSYS_WAVEFORM, NULL, sources_add_radionoise}, {NULL, NULL, NULL, SRC_FLAG_NONE, 0, NULL, NULL} // EOL }; int sources_init (void) { return 0; } void print_sourcelist (void) { int i; char subsys[7] = " "; printf(" Source Flag Subsys - Description (devices)\n"); printf("-------------------------------------------------------\n"); for (i = 0; g_source[i].name != NULL; i++) { strncpy(subsys, " ", 6); if ( g_source[i].subsystems & ROAR_SUBSYS_WAVEFORM ) subsys[0] = 'W'; if ( g_source[i].subsystems & ROAR_SUBSYS_MIDI ) subsys[1] = 'M'; if ( g_source[i].subsystems & ROAR_SUBSYS_CB ) subsys[2] = 'C'; if ( g_source[i].subsystems & ROAR_SUBSYS_LIGHT ) subsys[3] = 'L'; if ( g_source[i].subsystems & ROAR_SUBSYS_RAW ) subsys[4] = 'R'; if ( g_source[i].subsystems & ROAR_SUBSYS_COMPLEX ) subsys[5] = 'X'; if ( g_source[i].devices != NULL ) { printf(" %-10s %c%c%c %6s - %s (devices: %s)\n", g_source[i].name, g_source[i].flags & SRC_FLAG_FHSEC ? 's' : ' ', g_source[i].old_open != NULL ? 'S' : ' ', g_source[i].new_open != NULL ? 'N' : ' ', subsys, g_source[i].desc, g_source[i].devices); } else { printf(" %-9s %c%c%c %6s - %s\n", g_source[i].name, g_source[i].flags & SRC_FLAG_FHSEC ? 's' : ' ', g_source[i].old_open != NULL ? 'S' : ' ', g_source[i].new_open != NULL ? 'N' : ' ', subsys, g_source[i].desc); } } } int sources_set_client (int client) { if ( client >= 0 ) { g_source_client = client; return 0; } else { return -1; } } int sources_free (void) { return 0; } int sources_add (char * driver, char * device, char * container, char * options, int primary) { int i; if ( driver == NULL ) driver = ROAR_SOURCE_DEFAULT; for (i = 0; g_source[i].name != NULL; i++) { if ( !strcmp(g_source[i].name, driver) ) { if ( g_source[i].new_open != NULL ) { return sources_add_new(&(g_source[i]), driver, device, options, primary); } else if ( g_source[i].old_open != NULL ) { return g_source[i].old_open(driver, device, container, options, primary); } else { ROAR_ERR("sources_add(driver='%s', ...): Found source but did not find any open rutine", driver); return -1; } } } ROAR_ERR("sources_add(driver='%s', ...): Source not found", driver); return -1; } int sources_add_new (struct roar_source * source, char * driver, char * device, char * options, int primary) { int stream; int fh = -1; struct roar_stream * s; struct roar_stream_server * ss; char * k, * v; int error = 0; int f_sync = 0, f_mmap = 0; int codec; char * strtok_store; if ( source == NULL ) return -1; if ( (stream = streams_new()) == -1 ) { return -1; } if ( streams_get(stream, &ss) == -1 ) { streams_delete(stream); return -1; } s = ROAR_STREAM(ss); memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); codec = s->info.codec; if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) { streams_delete(stream); return -1; } s->pos_rel_id = -1; if ( options == NULL ) { k = NULL; } else { k = roar_mm_strtok_r(options, ",", &strtok_store); } while (k != NULL) { if ( (v = strstr(k, "=")) != NULL ) { *v++ = 0; } if ( strcmp(k, "rate") == 0 ) { s->info.rate = roar_str2rate(v); } else if ( strcmp(k, "channels") == 0 ) { s->info.channels = roar_str2channels(v); } else if ( strcmp(k, "bits") == 0 ) { s->info.bits = roar_str2bits(v); } else if ( strcmp(k, "codec") == 0 ) { if ( (codec = roar_str2codec(v)) == -1 ) { ROAR_ERR("sources_add_new(*): unknown codec '%s'", v); error++; } } else if ( strcmp(k, "name") == 0 ) { if ( streams_set_name(stream, v) == -1 ) { ROAR_ERR("add_output(*): Can not set Stream name"); error++; } } else if ( strcmp(k, "mmap") == 0 ) { f_mmap = 1; } else if ( strcmp(k, "sync") == 0 ) { f_sync = 1; } else if ( strcmp(k, "primary") == 0 ) { primary = 1; } else if ( strcmp(k, "meta") == 0 ) { streams_set_flag(stream, ROAR_FLAG_META); } else if ( strcmp(k, "cleanmeta") == 0 ) { streams_set_flag(stream, ROAR_FLAG_CLEANMETA); } else if ( strcmp(k, "autoconf") == 0 ) { streams_set_flag(stream, ROAR_FLAG_AUTOCONF); } else { ROAR_ERR("sources_add_new(*): unknown option '%s'", k); error++; } if ( error ) { streams_delete(stream); if ( primary ) alive = 0; return -1; } k = roar_mm_strtok_r(NULL, ",", &strtok_store); } if ( primary ) streams_mark_primary(stream); streams_set_flag(stream, ROAR_FLAG_SOURCE); client_stream_add(g_source_client, stream); if ( codec == ROAR_CODEC_ALAW || codec == ROAR_CODEC_MULAW ) s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter s->info.codec = codec; ROAR_STREAM_SERVER(s)->codec_orgi = codec; if ( source->new_open(stream, device, fh, driver) == -1 ) { streams_delete(stream); return -1; } _LIBROAR_IGNORE_RET(roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream)); // ignore errors here _LIBROAR_IGNORE_RET(roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM, s)); // ignore errors here if ( f_sync ) { streams_set_flag(stream, ROAR_FLAG_SYNC); } else { streams_reset_flag(stream, ROAR_FLAG_SYNC); } if ( f_mmap ) streams_set_flag(stream, ROAR_FLAG_MMAP); return 0; } int sources_add_dstr (int stream , const char * device, int fh, const char * driver) { struct roar_stream_server * ss; struct roar_vio_defaults def; (void)driver; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 ) return -1; streams_get(stream, &ss); if ( fh > -1 ) { if ( roar_vio_open_fh(&(ss->vio), fh) == -1 ) return -1; } else { if ( roar_vio_open_dstr(&(ss->vio), device, &def, 1) == -1 ) return -1; } return streams_set_fh(stream, -2); } #define _ret(x) streams_delete(stream); return (x) int sources_add_cf (const char * driver, const char * device, const char * container, const char * options, int primary) { int stream; int codec; int len; char buf[64]; struct roar_stream * s; struct roar_vio_calls * vio; struct roar_vio_defaults def; (void)driver, (void)container; if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 ) return -1; if ( (stream = streams_new()) == -1 ) { return -1; } streams_get_clientobj(stream, &s); memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) { streams_delete(stream); return -1; } s->pos_rel_id = -1; /* if ( (fh = open(device, O_RDONLY, 0644)) == -1 ) { return -1; } */ vio = &(ROAR_STREAM_SERVER(s)->vio); if ( roar_vio_open_dstr(vio, device, &def, 1) == -1 ) { roar_vio_clear_calls(vio); // clear the VIO object again // from things roar_vio_open_dstr() left. _ret(-1); } ROAR_DBG("sources_add_cf(*) = ?"); // TODO: find out a better way of doing auto detetion without need for seek! if ( options == NULL ) { if ( (len = roar_vio_read(vio, buf, 64)) < 1 ) { _ret(-1); } if ( roar_vio_lseek(vio, -len, SEEK_CUR) == (roar_off_t)-1 ) { _ret(-1); } if ( (codec = roar_file_codecdetect(buf, len)) == -1 ) { _ret(-1); } } else { if ( !strncmp(options, "codec=", 6) ) options += 6; if ( (codec = roar_str2codec(options)) == -1 ) { _ret(-1); } } s->info.codec = codec; ROAR_STREAM_SERVER(s)->codec_orgi = codec; ROAR_DBG("sources_add_cf(*) = ?"); streams_set_fh(stream, -2); ROAR_DBG("sources_add_cf(*) = ?"); streams_set_socktype(stream, ROAR_SOCKET_TYPE_FILE); if ( primary ) streams_mark_primary(stream); streams_set_flag(stream, ROAR_FLAG_SOURCE); client_stream_add(g_source_client, stream); return 0; } #undef _ret #ifndef ROAR_WITHOUT_DCOMP_CDRIVER int sources_add_cdriver (int stream , const char * device, int fh, const char * driver) { struct roar_stream_server * ss; if ( fh > -1 ) return -1; if ( streams_get(stream, &ss) == -1 ) return -1; if ( !strncmp(driver, "cdriver:", 8) ) driver += 8; ROAR_DBG("sources_add_cdriver(stream=%i, device='%s', fh=%i, driver='%s') = ?", stream, device, fh, driver); if ( roar_cdriver_open(&(ss->vio), driver, device, &(ROAR_STREAM(ss)->info), ROAR_DIR_RECORD) == -1 ) return -1; return streams_set_fh(stream, -2); } #endif static ssize_t sources_radionoise_read (struct roar_vio_calls * vio, void *buf, size_t count) { int32_t * pcm = buf; int16_t noise; size_t len, i; (void)vio; ROAR_DBG("sources_radionoise_read(vio=%p, buf=%p, count=%llu) = 0", vio, buf, (long long unsigned int)count); // ensure size is a multiple of 4. count -= count & 0x03LLU; if ( count == 0 ) return 0; if ( buf == NULL ) return -1; roar_random_gen_nonce(buf, count); len = count / 4; for (i = 0; i < len; i++) { noise = pcm[i] & 0xFFFF; pcm[i] = ((int32_t)noise << 16) >> 17; } ROAR_DBG("sources_radionoise_read(vio=%p, buf=%p, count=?) = %llu", vio, buf, (long long unsigned int)count); return count; } static int sources_radionoise_return_zero (struct roar_vio_calls * vio) { (void)vio; ROAR_DBG("sources_radionoise_return_zero(vio=%p) = 0", vio); return 0; } static int sources_radionoise_ctl(struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) { (void)vio, (void)data; if ( cmd == ROAR_VIO_CTL_NONBLOCK ) return 0; roar_err_set(ROAR_ERROR_BADRQC); return -1; } int sources_add_radionoise (int stream, const char * device, int fh, const char * driver) { struct roar_stream_server * ss; struct roar_audio_info * info; (void)device, (void)driver; if ( fh > -1 ) return -1; if ( streams_get(stream, &ss) == -1 ) return -1; info = &(ROAR_STREAM(ss)->info); info->codec = ROAR_CODEC_DEFAULT; info->bits = 32; memset(&(ss->vio), 0, sizeof(struct roar_vio_calls)); ss->vio.flags = ROAR_VIO_FLAGS_NONE; ss->vio.refc = 1; ss->vio.read = sources_radionoise_read; ss->vio.close = sources_radionoise_return_zero; ss->vio.sync = sources_radionoise_return_zero; ss->vio.ctl = sources_radionoise_ctl; return streams_set_fh(stream, -2); } int sources_add_roar (int stream, const char * device, int fh, const char * driver) { struct roar_stream_server * ss; struct roar_stream * s; (void)driver; if ( fh > -1 ) return -1; if ( streams_get(stream, &ss) == -1 ) return -1; s = ROAR_STREAM(ss); if ( roar_vio_simple_stream(&(ss->vio), s->info.rate, s->info.channels, s->info.bits, s->info.codec, device, ROAR_DIR_MONITOR, "roard", -1) == -1 ) return -1; return streams_set_fh(stream, -2); } #endif //ll roaraudio-1.0beta11/roard/ssynth.c0000644000175000017500000001661012264733700015272 0ustar phiphi//ssynth.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" #ifndef ROAR_WITHOUT_DCOMP_SSYNTH static const float ssynth_polys[SSYNTH_POLY_POLYMAX][SSYNTH_POLY_COEFF] = { {0.300000, 0.958333, -0.550000, 0.091667}, {0.700010, -0.083333, -0.150000, 0.033333} }; struct ssynth_conf ssynth_conf; struct ssynth_state { int stream; struct { int stage; char vv_down, vv_up; struct roar_note_octave note; struct roar_synth_state synth; struct roar_fader_state fader; struct roar_buffer * buf; } notes[SSYNTH_NOTES_MAX]; } g_ssynth; int ssynth_init_config(void) { memset(&ssynth_conf, 0, sizeof(ssynth_conf)); return 0; } #define _err() streams_delete(sid); return -1 int ssynth_init (void) { struct roar_stream_server * ss; struct roar_stream * s; int sid; if ( !ssynth_conf.enable ) return 0; memset(&g_ssynth, 0, sizeof(g_ssynth)); g_ssynth.stream = -1; if ( (sid = streams_new()) == -1 ) return -1; if ( streams_set_client(sid, g_self_client) == -1 ) { _err(); } if ( streams_set_dir(sid, ROAR_DIR_BRIDGE, 1) == -1 ) { _err(); } if ( streams_set_flag(sid, ROAR_FLAG_PRIMARY) == -1 ) { _err(); } if ( streams_set_name(sid, "Simple Synthesizer") == -1 ) { _err(); } if ( streams_get(sid, &ss) == -1 ) { _err(); } s = ROAR_STREAM(ss); memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); s->info.channels = 1; s->info.codec = ROAR_CODEC_DEFAULT; g_ssynth.stream = sid; return 0; } int ssynth_free (void) { int i; if ( !ssynth_conf.enable ) return 0; for (i = 0; i < SSYNTH_NOTES_MAX; i++) { if ( g_ssynth.notes[i].buf != NULL ) { roar_buffer_free(g_ssynth.notes[i].buf); g_ssynth.notes[i].buf = NULL; } } return streams_delete(g_ssynth.stream); } int ssynth_update (void) { struct roar_stream_server * ss; struct roar_stream * s; struct roar_buffer * buf; struct roar_buffer * outbuf; void * outbufdata; void * indbufs[SSYNTH_NOTES_MAX+1]; int curin = 0; size_t buflen; size_t needlen; int i; if ( !ssynth_conf.enable ) return 0; ROAR_DBG("ssynth_update(void) = ?"); if ( streams_get(g_ssynth.stream, &ss) == -1 ) { return -1; } memset(indbufs, 0, sizeof(indbufs)); s = ROAR_STREAM(ss); needlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(&(s->info)); ROAR_DBG("ssynth_update(void): needlen=%lu", (unsigned long)needlen); for (i = 0; i < SSYNTH_NOTES_MAX; i++) { if ( g_ssynth.notes[i].stage != SSYNTH_STAGE_UNUSED ) { ROAR_DBG("ssynth_update(void): used note slot: %i", i); if ( g_ssynth.notes[i].buf == NULL ) { if ( roar_buffer_new(&buf, needlen) == -1 ) continue; g_ssynth.notes[i].buf = buf; } else { buf = g_ssynth.notes[i].buf; if ( roar_buffer_get_len(buf, &buflen) == -1 ) continue; if ( buflen < needlen ) { if ( roar_buffer_set_len(buf, needlen) == -1 ) continue; } } if ( roar_buffer_get_data(buf, &(indbufs[curin])) == -1 ) continue; if ( ssynth_note_render(i, indbufs[curin]) == -1 ) continue; curin++; } } ROAR_DBG("ssynth_update(void): found streams: %i", curin); if ( curin > 0 ) { if ( roar_buffer_new(&outbuf, needlen) == -1 ) return -1; if ( roar_buffer_get_data(outbuf, &outbufdata) == -1 ) { roar_buffer_free(outbuf); return -1; } if ( roar_mix_pcm(outbufdata, g_sa->bits, indbufs, ROAR_OUTPUT_BUFFER_SAMPLES) == -1 ) { roar_buffer_free(outbuf); return -1; } if ( stream_add_buffer(g_ssynth.stream, &outbuf) == -1 ) { roar_buffer_free(outbuf); return -1; } } ROAR_DBG("ssynth_update(void) = 0"); return 0; } int ssynth_note_new(struct roar_note_octave * note, char vv) { int i; ROAR_DBG("ssynth_note_new(note=%p, vv=%i) = ?", note, vv); for (i = 0; i < SSYNTH_NOTES_MAX; i++) { if ( g_ssynth.notes[i].stage == SSYNTH_STAGE_UNUSED ) { // TODO: do some error checking here g_ssynth.notes[i].vv_down = vv; memcpy(&(g_ssynth.notes[i].note), note, sizeof(struct roar_note_octave)); roar_synth_init(&(g_ssynth.notes[i].synth), &(g_ssynth.notes[i].note), g_sa->rate); roar_synth_set_volume(&(g_ssynth.notes[i].synth), 0.25); roar_synth_set_func(&(g_ssynth.notes[i].synth), ROAR_SYNTH_SYNF_TRAP); ssynth_note_set_stage(i, SSYNTH_STAGE_KEYSTROKE); ROAR_DBG("ssynth_note_new(note=%p, vv=%i) = %i", note, vv, i); return i; } } ROAR_DBG("ssynth_note_new(note=%p, vv=%i) = -1", note, vv); return -1; } int ssynth_note_free(int id) { g_ssynth.notes[id].stage = SSYNTH_STAGE_UNUSED; return 0; } int ssynth_note_find(struct roar_note_octave * note) { struct roar_note_octave * cn; int i; for (i = 0; i < SSYNTH_NOTES_MAX; i++) { if ( g_ssynth.notes[i].stage == SSYNTH_STAGE_UNUSED ) continue; cn = &(g_ssynth.notes[i].note); if ( !(note->note == cn->note && note->octave == cn->octave) ) continue; return i; } return -1; } int ssynth_note_set_stage(int id, int stage) { int r = -1; switch (stage) { case SSYNTH_STAGE_UNUSED: r = ssynth_note_free(id); break; case SSYNTH_STAGE_KEYSTROKE: r = roar_fader_init(&(g_ssynth.notes[id].fader), ssynth_polys[SSYNTH_POLY_KEYDOWN], SSYNTH_POLY_COEFF); break; case SSYNTH_STAGE_MIDSECTION: r = 0; break; case SSYNTH_STAGE_KEYRELEASE: r = roar_fader_init(&(g_ssynth.notes[id].fader), ssynth_polys[SSYNTH_POLY_KEYUP], SSYNTH_POLY_COEFF); break; } if ( r == 0 ) g_ssynth.notes[id].stage = stage; return r; } int ssynth_note_render (int id, void * data) { if ( g_sa->bits != 16 ) return -1; return roar_synth_pcmout_i161(&(g_ssynth.notes[id].synth), data, ROAR_OUTPUT_BUFFER_SAMPLES); } int ssynth_note_on (struct roar_note_octave * note, char vv) { ROAR_DBG("ssynth_note_on(note=%p, vv=%i) = ?", note, vv); return ssynth_note_new(note, vv); } int ssynth_note_off (struct roar_note_octave * note, char vv) { int id; (void)vv; ROAR_DBG("ssynth_note_off(note=%p, vv=%i) = ?", note, vv); if ( (id = ssynth_note_find(note)) == -1 ) return -1; // add support to for keyups... return ssynth_note_free(id); } int ssynth_eval_message (struct midi_message * mes) { if ( !ssynth_conf.enable ) return -1; ROAR_DBG("ssynth_eval_message(mes=%p) = ?", mes); switch (mes->type) { case MIDI_TYPE_NOTE_OFF: return ssynth_note_off(&(mes->d.note), mes->vv); break; case MIDI_TYPE_NOTE_ON: return ssynth_note_on(&(mes->d.note), mes->vv); break; default: /* ignore all other events at the moment */ return 0; } ROAR_DBG("ssynth_eval_message(mes=%p) = -1", mes); return -1; } #endif //ll roaraudio-1.0beta11/roard/streams.c0000644000175000017500000021022712264733700015420 0ustar phiphi//streams.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" // declared 'extern' struct roar_stream_server * g_streams[ROAR_STREAMS_MAX]; #define _CHECK_SID_RET(id,ret) if ( (id) < 0 || (id) > ROAR_STREAMS_MAX || g_streams[(id)] == NULL ) return (ret) #define _CHECK_SID(id) _CHECK_SID_RET((id), -1) static int streams_thru_num = 0; static int streams_sync_num = 0; int streams_recsource_id = -1; static const struct rolestack * streams_rolestack = NULL; static int streams_role_num = 0; static void _streams_change_state(struct roar_stream_server * s, const int new, const char * func) { register int id = ROAR_STREAM(s)->id; register int old = s->state; s->state = new; if ( func == NULL ) { func = "(unknown)"; } ROAR_INFO("_streams_change_state[by %s](id=%i): stream state: %s->%s", ROAR_DBG_INFO_VERBOSE, func, ROAR_STREAM(s)->id, roar_streamstate2str(old), roar_streamstate2str(new)); roar_notify_core_emit_simple(ROAR_OE_BASICS_CHANGE_STATE, -1, id, ROAR_OT_STREAM, old, new, NULL, 0); } void streams_change_sync_num(int id, int diff) { struct roar_stream_server * ss; int i; if ( diff != 0 ) if ( streams_get_dir(id) != ROAR_DIR_OUTPUT ) return; ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Number of sync streams changed from %i to %i", ROAR_DBG_INFO_VERBOSE, id, diff, streams_sync_num, streams_sync_num + diff); streams_sync_num += diff; if ( !streams_sync_num && alive ) { ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Number of sync streams changed to zero. Bad.", ROAR_DBG_INFO_VERBOSE, id, diff ); for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (ss = g_streams[i]) == NULL ) continue; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_OUTPUT ) continue; if ( !ss->ready ) continue; if ( ss->state == ROAR_STREAMSTATE_CLOSING ) continue; if ( streams_get_flag(i, ROAR_FLAG_PRIMARY) ) { ROAR_DBG("streams_change_sync_num(*): try to set sync on primary stream %i", i); streams_set_flag(i, ROAR_FLAG_SYNC); if ( streams_sync_num ) return; } } for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (ss = g_streams[i]) == NULL ) continue; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_OUTPUT ) continue; if ( !ss->ready ) continue; if ( ss->state == ROAR_STREAMSTATE_CLOSING ) continue; if ( !streams_get_flag(i, ROAR_FLAG_PRIMARY) ) { ROAR_DBG("streams_change_sync_num(*): try to set sync on non-primary stream %i", i); streams_set_flag(i, ROAR_FLAG_SYNC); if ( streams_sync_num ) return; } } ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Can not auto set sync flag to an output. Very Bad", ROAR_DBG_INFO_VERBOSE, id, diff ); ROAR_WARN("streams_change_sync_num(id=%i, diff=%i): Lost all sync streams and failed to set a new one. Very Bad.", id, diff); } } int streams_init (void) { int i; streams_rolestack = rolestack_get_role(-1); // get default for (i = 0; i < ROAR_STREAMS_MAX; i++) g_streams[i] = NULL; return 0; } int streams_free (void) { int i; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL ) { streams_delete(i); } } return 0; } int streams_new (void) { int i, j; struct roar_stream * n = NULL; struct roar_stream_server * s = NULL; #ifdef ROAR_SUPPORT_LISTEN if ( g_terminate && !g_no_listen ) // don't accept new streams in case of termination state return -1; #else if ( g_terminate ) // don't accept new streams in case of termination state return -1; #endif for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] == NULL ) { s = ROAR_STREAM_SERVER(n = ROAR_STREAM(roar_mm_malloc(sizeof(struct roar_stream_server)))); if ( n == NULL ) { ROAR_ERR("streams_new(void): can not allocate memory for new stream: %s", strerror(errno)); ROAR_DBG("streams_new(void) = -1"); return -1; } memset(s, 0, sizeof(struct roar_stream_server)); n->id = i; n->fh = -1; n->pos_rel_id = -1; /* n->database = NULL; n->dataoff = NULL; n->datalen = 0; n->offset = 0; */ n->pos = 0; s->name = NULL; s->state = ROAR_STREAMSTATE_INITING; s->client = -1; s->socktype = ROAR_SOCKET_TYPE_UNKNOWN; s->buffer = NULL; s->need_extra = 0; s->output = NULL; s->is_new = 1; s->codecfilter = -1; s->pre_underruns = 0; s->post_underruns = 0; s->delay = 0; s->codec_orgi = -1; s->primary = 0; s->ready = 0; s->outputbuffer = NULL; s->prethru = NULL; s->mixer_stream = -1; s->role = ROAR_ROLE_UNKNOWN; s->parent_stream = -1; s->single_sink_c = 0; s->single_sink_self_c = 0; s->mixer.scale = 65535; s->mixer.rpg_mul = 1; s->mixer.rpg_div = 1; for (j = 0; j < ROAR_MAX_CHANNELS; j++) s->mixer.mixer[j] = 65535; #ifdef ROAR_SUPPORT_META for (j = 0; j < ROAR_META_MAX_PER_STREAM; j++) { s->meta[j].type = ROAR_META_TYPE_NONE; s->meta[j].key[0] = 0; s->meta[j].value = NULL; } #endif roar_vio_clear_calls(&(s->vio)); roar_vio_clear_calls(&(s->jumbo)); s->viop = &(s->vio); s->driver_id = -1; s->flags = ROAR_FLAG_NONE; #ifndef ROAR_WITHOUT_DCOMP_MIXER s->mixerstream = NULL; #endif s->rpgmode = ROAR_RPGMODE_DEFAULT; //roardsp_fchain_init(&(s->fc)); g_streams[i] = s; counters_inc(streams, 1); ROAR_INFO("streams_new(void): New stream %i created (state=initing)", ROAR_DBG_INFO_VERBOSE, i); ROAR_DBG("streams_new(void): n->id=%i", n->id); roar_notify_core_emit_snoargs(ROAR_OE_BASICS_NEW, -1, i, ROAR_OT_STREAM); ROAR_DBG("streams_new(void) = %i", i); return i; } } return -1; } int streams_delete (int id) { struct roar_stream_server * s; int prim; int no_vio_close = 0; int i; int client; _CHECK_SID(id); if ( (s = g_streams[id]) == NULL ) return 0; ROAR_DBG("streams_delete(id=%i) = ?", id); ROAR_DBG("streams_delete(id=%i): g_streams[id]->id=%i", id, ROAR_STREAM(s)->id); // in case we are allready closing it... if ( s->state == ROAR_STREAMSTATE_CLOSING ) return 0; _streams_change_state(s, ROAR_STREAMSTATE_CLOSING, "streams_delete"); roar_notify_core_emit_snoargs(ROAR_OE_BASICS_DELETE, -1, id, ROAR_OT_STREAM); streams_set_role(id, -1); prim = s->primary; if ( prim ) alive = 0; if ( s->flags & ROAR_FLAG_SINGLESINK ) streams_set_single_sink(id, 1); counters_inc(streams, -1); if ( streams_get_flag(id, ROAR_FLAG_RECSOURCE) == 1 ) streams_reset_flag(id, ROAR_FLAG_RECSOURCE); for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL && ROAR_STREAM(g_streams[i])->pos_rel_id == id ) { switch (ROAR_STREAM(g_streams[i])->dir) { case ROAR_DIR_THRU: case ROAR_DIR_RAW_IN: if ( i != id ) streams_delete(i); break; default: if ( streams_get_flag(i, ROAR_FLAG_VIRTUAL) == 1 ) { if ( i != id ) { ROAR_DBG("streams_delete(id=%i): Deleting virtual child stream %i", id, i); streams_delete(i); } } else { ROAR_STREAM(g_streams[i])->pos_rel_id = -1; } } } } if ( ROAR_STREAM(s)->dir == ROAR_DIR_THRU ) streams_thru_num--; if ( streams_get_flag(id, ROAR_FLAG_VIRTUAL) == 1 ) { // we un-group the stream here to avoid a client deleting the parent deleting the client deleting ... i = ROAR_STREAM(s)->pos_rel_id; if ( i != -1 ) { ROAR_STREAM(s)->pos_rel_id = -1; client = streams_get_client(id); streams_set_client(id, -1); ROAR_DBG("streams_delete(id=%i): Stream has flag virtual, notifying parent stream %i", id, i); streams_ctl(i, ROAR_CODECFILTER_CTL_VIRTUAL_DELETE|ROAR_STREAM_CTL_TYPE_INT, &id); ROAR_DBG("streams_delete(id=%i): Notify send to stream %i", id, i); streams_set_client(id, client); ROAR_STREAM(s)->pos_rel_id = i; } } #ifdef ROAR_SUPPORT_META // delete meta data form other meta streams if needed if ( streams_get_flag(id, ROAR_FLAG_META) == 1 ) { ROAR_DBG("streams_delete(id=%i): deleting meta stream!", id); stream_meta_clear(id); stream_meta_finalize(id); } #endif if ( s->codecfilter != -1 ) { codecfilter_close(s->codecfilter_inst, s->codecfilter); s->codecfilter_inst = NULL; s->codecfilter = -1; } if ( s->driver_id != -1 ) { driver_closevio(&(s->vio), s->driver_id); roar_vio_clear_calls(&(s->vio)); s->driver_id = -1; no_vio_close = 1; } #ifndef ROAR_WITHOUT_DCOMP_MIXER if ( s->mixerstream != NULL ) { hwmixer_close(id); } #endif // all IO is no disconnected: s->ready = 0; // re-try reset after all IO is disconnected. if ( streams_get_flag(id, ROAR_FLAG_RECSOURCE) == 1 ) streams_reset_flag(id, ROAR_FLAG_RECSOURCE); //roardsp_fchain_uninit(&(s->fc)); if ( s->client != -1 ) { ROAR_DBG("streams_delete(id=%i): Stream is owned by client %i", id, g_streams[id]->client); client_stream_delete(s->client, id); } stream_outputbuffer_destroy(id); stream_prethru_destroy(id); if ( s->buffer != NULL ) roar_buffer_free(s->buffer); if ( s->output != NULL ) roar_mm_free(s->output); /* if ( ROAR_STREAM(s)->fh != -1 ) close(ROAR_STREAM(s)->fh); */ if ( s->flags & ROAR_FLAG_SYNC ) streams_change_sync_num(id, -1); if ( !no_vio_close ) roar_vio_close(s->viop); if ( s->name != NULL ) roar_mm_free(s->name); roar_mm_free(s); g_streams[id] = NULL; if ( prim && alive ) { alive = 0; clean_quit(); } ROAR_INFO("streams_delete(id=%i): stream deleted", ROAR_DBG_INFO_VERBOSE, id); ROAR_DBG("streams_delete(id=%i) = 0", id); return 0; } int streams_set_client (int id, int client) { _CHECK_SID(id); ROAR_DBG("streams_set_client(id=%i): g_streams[id]->id=%i", id, ROAR_STREAM(g_streams[id])->id); g_streams[id]->client = client; return 0; } int streams_get_client (int id) { _CHECK_SID(id); return g_streams[id]->client; } int streams_set_dir (int id, int dir, int defaults) { struct roar_stream_server * ss; int mixer; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) { ROAR_ERR("streams_set_dir(id=%i, dir=%i, defaults=%i) = -1 // error=NOENT", id, dir, defaults); roar_err_set(ROAR_ERROR_NOENT); return -1; } ROAR_STREAM(ss)->dir = dir; if ( dir == ROAR_DIR_THRU ) streams_thru_num++; if ( defaults ) { if ( dir <= 0 || dir >= ROAR_DIR_DIRIDS ) { ROAR_ERR("streams_set_dir(id=%i, dir=%i, defaults=%i) = -1 // error=INVAL", id, dir, defaults); roar_err_set(ROAR_ERROR_INVAL); return -1; } ROAR_DBG("streams_set_dir(*): g_config->streams[dir=%i].flags = 0x%.4x", dir, g_config->streams[dir].flags); if ( streams_set_flag(id, g_config->streams[dir].flags) == -1 ) { ROAR_WARN("streams_set_dir(*) = -1 // can not set stream flags"); return -1; } ss->mixer.scale = g_config->streams[dir].mixer.scale; ss->mixer.rpg_mul = g_config->streams[dir].mixer.rpg_mul; ss->mixer.rpg_div = g_config->streams[dir].mixer.rpg_div; } if ( dir != ROAR_DIR_MIXING ) { switch (streams_get_subsys(id)) { case ROAR_SUBSYS_WAVEFORM: streams_set_mixer_stream(id, g_waveform_mixer.stream); roardsp_chanlist_init(ss->chanmap.in, ROAR_STREAM(ss)->info.channels, ROARDSP_CHANLIST_MAP_ROARAUDIO); break; #ifndef ROAR_WITHOUT_DCOMP_MIDI case ROAR_SUBSYS_MIDI: roardsp_chanlist_init(ss->chanmap.in, ROAR_STREAM(ss)->info.channels, ROARDSP_CHANLIST_MAP_MIDI); streams_set_mixer_stream(id, g_midi_mixer.stream); break; #endif #ifndef ROAR_WITHOUT_DCOMP_LIGHT case ROAR_SUBSYS_LIGHT: streams_set_mixer_stream(id, g_light_mixer.stream); break; #endif } if ( streams_get_ssdir(id) & STREAM_DIR_OUT ) { if ( (mixer = streams_get_mixer_stream(id)) != -1 ) { if ( g_streams[mixer]->flags & ROAR_FLAG_SINGLESINK ) { streams_set_mixer_stream(id, -1); return -1; } } } memcpy(ss->chanmap.out, ss->chanmap.in, sizeof(ss->chanmap.out)); streams_set_map(id, NULL, 0); } else { streams_set_mixer_stream(id, id); } ROAR_DBG("streams_set_dir(*) = 0"); return 0; } int streams_get_dir (int id) { struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; return ROAR_STREAM(ss)->dir; } int streams_set_mixer_stream(int id, int mixer) { struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; ss->mixer_stream = mixer; return 0; } int streams_get_mixer_stream(int id) { struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; return ss->mixer_stream; } static int streams_set_role_handle(int id) { switch (streams_rolestack->action) { case RS_ERROR: /* nothing to do */; break; case RS_MIX: /* nothing to do */; break; case RS_KICK: streams_delete(id); break; case RS_MUTE: streams_set_flag(id, ROAR_FLAG_MUTE); break; case RS_PAUSE: streams_set_flag(id, ROAR_FLAG_PAUSE); break; } return 0; } int streams_set_role (int id, int role) { struct roar_stream_server * ss; const struct rolestack * rs; int old_role; int i; ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role); _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; old_role = ss->role; ss->role = role; ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role); if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY ) return 0; ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role); if ( old_role == role ) { ROAR_DBG("streams_set_role(id=%i, role=%i) = 0", id, role); return 0; } if ( old_role != role && old_role != -1 && role != -1 ) { streams_set_role(id, -1); streams_set_role(id, role); } ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role); if ( ss->role != -1 && ss->role == streams_rolestack->role ) { ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role); streams_role_num--; if ( streams_role_num == 0 ) { streams_rolestack = rolestack_get_role(-1); // get default for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (ss = g_streams[i]) == NULL ) continue; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY ) continue; if ( ss->role == -1 ) continue; rs = rolestack_get_role(ss->role); if ( rs->index > streams_rolestack->role ) { streams_rolestack = rs; } } for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (ss = g_streams[i]) == NULL ) continue; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY ) continue; if ( ss->role == streams_rolestack->role ) streams_role_num++; } } } else if ( role != -1 ) { ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role); rs = rolestack_get_role(role); ROAR_DBG("streams_set_role(id=%i, role=%i): rs->index=%i, streams_rolestack->index=%i", id, role, rs->index, streams_rolestack->index); if ( rs->index == streams_rolestack->index ) { ROAR_DBG("streams_set_role(id=%i, role=%i): rs->index=%i, streams_rolestack->index=%i", id, role, rs->index, streams_rolestack->index); streams_role_num++; } else if ( rs->index > streams_rolestack->index ) { ROAR_DBG("streams_set_role(id=%i, role=%i): rs=%p{.index=%i, .action=%s}", id, role, rs, rs->index, rolestack_action2str(rs->action)); streams_role_num = 1; streams_rolestack = rs; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (ss = g_streams[i]) == NULL ) continue; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY ) continue; rs = rolestack_get_role(ss->role); ROAR_DBG("streams_set_role(id=%i, role=%i): i=%i, rs->index=%i, streams_rolestack->index=%i", id, role, i, rs->index, streams_rolestack->index); if ( rs->index < streams_rolestack->index ) streams_set_role_handle(i); } } else { ROAR_DBG("streams_set_role(id=%i, role=%i): streams_rolestack->action=%s", id, role, rolestack_action2str(streams_rolestack->action)); streams_set_role_handle(id); } } ROAR_DBG("streams_set_role(id=%i, role=%i) = 0", id, role); return 0; } int streams_get_subsys (int id) { struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( ROAR_STREAM(ss)->dir == ROAR_DIR_THRU ) return streams_get_subsys(ROAR_STREAM(ss)->pos_rel_id); return streams_dir2subsys(ROAR_STREAM(ss)->dir); } int streams_dir2subsys (int dir) { switch (dir) { case ROAR_DIR_PLAY: case ROAR_DIR_RECORD: case ROAR_DIR_MONITOR: case ROAR_DIR_FILTER: case ROAR_DIR_OUTPUT: case ROAR_DIR_BIDIR: case ROAR_DIR_RECPLAY: return ROAR_SUBSYS_WAVEFORM; break; case ROAR_DIR_MIDI_IN: case ROAR_DIR_MIDI_OUT: return ROAR_SUBSYS_MIDI; break; case ROAR_DIR_LIGHT_IN: case ROAR_DIR_LIGHT_OUT: return ROAR_SUBSYS_LIGHT; break; case ROAR_DIR_RAW_IN: case ROAR_DIR_RAW_OUT: return ROAR_SUBSYS_RAW; break; case ROAR_DIR_COMPLEX_IN: case ROAR_DIR_COMPLEX_OUT: return ROAR_SUBSYS_COMPLEX; break; case ROAR_DIR_MIXING: return ROAR_SUBSYS_NONE; break; } return -1; } int streams_get_ssdir (int id) { struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; switch (ROAR_STREAM(ss)->dir) { case ROAR_DIR_PLAY: case ROAR_DIR_MIDI_IN: case ROAR_DIR_LIGHT_IN: case ROAR_DIR_RAW_IN: case ROAR_DIR_COMPLEX_IN: return STREAM_DIR_IN; break; case ROAR_DIR_RECORD: case ROAR_DIR_MONITOR: case ROAR_DIR_OUTPUT: case ROAR_DIR_MIDI_OUT: case ROAR_DIR_LIGHT_OUT: case ROAR_DIR_RAW_OUT: case ROAR_DIR_COMPLEX_OUT: return STREAM_DIR_OUT; break; case ROAR_DIR_MIXING: return STREAM_DIR_NONE; break; case ROAR_DIR_FILTER: case ROAR_DIR_BIDIR: case ROAR_DIR_RECPLAY: return STREAM_DIR_BIDIR; break; case ROAR_DIR_THRU: return streams_get_ssdir(ROAR_STREAM(ss)->pos_rel_id); break; } return -1; } #define _err() streams_delete(id); return -1; int streams_new_virtual (int parent, struct roar_stream_server ** stream) { struct roar_stream_server * parent_ss, * ss; struct roar_stream * parent_s , * s; int id = -1; int client, dir; if ( streams_get(parent, &parent_ss) == -1 ) return -1; if ( (client = streams_get_client(parent)) == -1 ) return -1; if ( (dir = streams_get_dir(parent)) == -1 ) return -1; if ( (id = streams_new()) == -1 ) { return -1; } if ( client_stream_add(client, id) == -1 ) { _err(); } if ( streams_get(id, &ss) == -1 ) { _err(); } if ( streams_set_dir(id, dir, 1) == -1 ) { _err(); } s = ROAR_STREAM( ss); parent_s = ROAR_STREAM(parent_ss); s->pos_rel_id = parent; if ( streams_set_rawflag(id, ROAR_FLAG_VIRTUAL) == -1 ) { _err(); } if ( stream != NULL ) *stream = ss; return id; } #undef _err int streams_set_fh (int id, int fh) { struct roar_stream_server * ss; struct roar_stream * s; int dir; int nonblock = 1; _CHECK_SID(id); if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL ) return -1; if ( ss->ready && !(s->fh == -1 && fh == -2) ) { ROAR_DBG("streams_set_fh(id=%i, fh=%i) = -1 // try to set fh for stream which is already ready", id, fh); return -1; } dir = s->dir; ROAR_DBG("streams_set_fh(id=%i, fh=%i): g_streams[id]->id=%i", id, fh, s->id); s->fh = fh; ROAR_DBG("streams_set_fh(id=%i, fh=%i): driverID=%i", id, fh, ss->driver_id); if ( ss->driver_id == -1 && fh != -2 ) { #ifndef ROAR_TARGET_WIN32 roar_vio_open_fh(&(ss->vio), fh); #else roar_vio_open_fh_socket(&(ss->vio), fh); #endif } ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh); switch (dir) { case ROAR_DIR_THRU: case ROAR_DIR_RAW_IN: case ROAR_DIR_RAW_OUT: break; default: ROAR_DBG("streams_set_fh(id=%i, fh=%i): codec=%s(%i)", id, fh, roar_codec2str(s->info.codec), s->info.codec); if ( codecfilter_open(&(ss->codecfilter_inst), &(ss->codecfilter), NULL, s->info.codec, ss) == -1 ) { streams_delete(id); // TODO: FIXME: is this correct? shoudn't we return -1 in any case here? ROAR_DBG("streams_set_fh(id=%i, fh=%i) = -1", id, fh); return -1; } break; } ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh); if ( fh == -2 ) { ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh); if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_GET_READ_FH, &fh) == -1 ) { fh = -2; } else { ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh); if ( fh < 0 ) { fh = -2; } else { s->fh = fh; } } } ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh); if ( fh == -1 || fh == -2 ) { // yes, this is valid, indecats full vio! ss->ready = 1; //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh"); ROAR_DBG("streams_set_fh(id=%i, fh=%i): s->fh=%i", id, fh, s->fh); ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh); return 0; } ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh); switch (dir) { case ROAR_DIR_MONITOR: case ROAR_DIR_RECORD: case ROAR_DIR_OUTPUT: case ROAR_DIR_MIDI_OUT: case ROAR_DIR_LIGHT_OUT: case ROAR_DIR_RAW_OUT: ROAR_SHUTDOWN(fh, SHUT_RD); break; } if ( dir >= ROAR_DIR_DIRIDS ) return -1; if ( g_config->streams[dir].flags & ROAR_FLAG_SYNC ) { switch (dir) { case ROAR_DIR_BRIDGE: case ROAR_DIR_MIDI_OUT: break; default: nonblock = 0; break; } } if ( !nonblock ) { ss->ready = 1; //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh"); ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh); return 0; } else { #ifndef ROAR_TARGET_WIN32 if ( roar_socket_nonblock(fh, ROAR_SOCKET_NONBLOCK) == -1 ) return -1; #endif ss->ready = 1; //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh"); ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh); return 0; } } int streams_get_fh (int id) { int ret; ROAR_DBG("streams_get_fh(id=%i) = ?", id); _CHECK_SID(id); ROAR_DBG("streams_get_fh(id=%i) = ?", id); ret = ROAR_STREAM(g_streams[id])->fh; ROAR_DBG("streams_get_fh(id=%i) = %i", id, ret); return ret; } int streams_set_null_io(int id) { struct roar_stream_server * ss; struct roar_stream * s; _CHECK_SID(id); if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL ) return -1; s->fh = -1; return 0; } int streams_get (int id, struct roar_stream_server ** stream) { _CHECK_SID(id); *stream = g_streams[id]; return 0; } int streams_get_clientobj (int id, struct roar_stream ** stream) { _CHECK_SID(id); *stream = ROAR_STREAM(g_streams[id]); return 0; } int streams_set_socktype (int id, int socktype) { _CHECK_SID(id); g_streams[id]->socktype = socktype; return 0; } int streams_get_socktype (int id) { _CHECK_SID(id); return g_streams[id]->socktype; } int streams_is_ready (int id) { _CHECK_SID(id); return g_streams[id]->ready; } int streams_is_new (int id) { _CHECK_SID(id); return g_streams[id]->ready; } int streams_set_primary (int id, int prim) { _CHECK_SID(id); g_streams[id]->primary = prim; return 0; } int streams_mark_primary (int id) { return streams_set_primary(id, 1); } int streams_set_sync (int id, int sync) { int fh = streams_get_fh(id); ROAR_DBG("streams_set_sync(id=%i, sync=%i) = ?", id, sync); _CHECK_SID(id); if ( fh > -1 ) { if ( roar_socket_nonblock(fh, sync ? ROAR_SOCKET_BLOCK : ROAR_SOCKET_NONBLOCK) == -1 ) return -1; #ifdef ROAR_FDATASYNC ROAR_FDATASYNC(fh); #endif return 0; } else { return roar_vio_nonblock(&(g_streams[id]->vio), sync); } } int streams_set_mmap (int id, int reset) { int use = !reset; _CHECK_SID(id); return roar_vio_ctl(&(g_streams[id]->vio), ROAR_VIO_CTL_SET_UMMAP, &use); } int streams_set_single_sink(int id, int reset) { struct roar_stream_server * self_ss, * ss; struct roar_stream * s; int mixer; size_t count = 0; int i; int ssdir; /* FIXME: This code only uses one refc for the mixer shared with the inputs. * If the flag is unset on the mixer but got set by the sources the counter * may/will become corrupted. */ _CHECK_SID(id); self_ss = g_streams[id]; mixer = self_ss->mixer_stream; ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer); if ( !reset && id != mixer ) if ( self_ss->flags & ROAR_FLAG_SINGLESINK ) return 0; if ( id == mixer ) { if ( reset ) { if ( self_ss->single_sink_self_c ) { ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer); self_ss->single_sink_self_c--; self_ss->single_sink_c--; if ( self_ss->single_sink_c == 0 ) { ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer); self_ss->flags |= ROAR_FLAG_SINGLESINK; self_ss->flags -= ROAR_FLAG_SINGLESINK; } return 0; } else { return -1; } } else { if ( self_ss->single_sink_c ) { self_ss->single_sink_self_c++; self_ss->single_sink_c++; return 0; } } } else if ( reset ) { ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer); if ( (ss = g_streams[mixer]) == NULL ) return -1; if ( ss->single_sink_c == 0 ) return -1; ss->single_sink_c--; if ( ss->single_sink_c == 0 ) { self_ss->flags |= ROAR_FLAG_SINGLESINK; self_ss->flags -= ROAR_FLAG_SINGLESINK; ss->flags |= ROAR_FLAG_SINGLESINK; ss->flags -= ROAR_FLAG_SINGLESINK; } return 0; } for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (s = ROAR_STREAM((ss = g_streams[i]))) != NULL ) { if ( s->dir == ROAR_DIR_THRU ) if ( s->pos_rel_id == id || s->pos_rel_id == mixer || g_streams[s->pos_rel_id]->mixer_stream == mixer ) return -1; if ( ss->mixer_stream != mixer ) continue; ssdir = streams_get_ssdir(i); if ( ssdir & STREAM_DIR_OUT ) count++; } } if ( count > 1 ) return -1; ss = g_streams[mixer]; if ( id == mixer ) ss->single_sink_self_c++; ss->single_sink_c++; self_ss->flags |= ROAR_FLAG_SINGLESINK; ss->flags |= ROAR_FLAG_SINGLESINK; return 0; } int streams_set_flag (int id, uint32_t flag) { int parent; int tmp; ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); _CHECK_SID(id); ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_IMMUTABLE ) flag |= ROAR_FLAG_PRIMARY; ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); // check if flags we are going to change are protected: if ( g_streams[id]->flags_protection & flag ) return -1; flag |= g_streams[id]->flags; flag -= g_streams[id]->flags; ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_MMAP ) { if ( streams_set_mmap(id, 0) == -1 ) { flag -= ROAR_FLAG_MMAP; return -1; } } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_PRIMARY ) { streams_set_primary(id, 1); flag -= ROAR_FLAG_PRIMARY; } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_SINGLESINK ) { if ( streams_set_single_sink(id, 0) == -1 ) { return -1; } flag -= ROAR_FLAG_SINGLESINK; } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_VIRTUAL ) { if ( (parent = ROAR_STREAM(g_streams[id])->pos_rel_id) == -1 ) return -1; if ( streams_ctl(parent, ROAR_CODECFILTER_CTL_VIRTUAL_NEW|ROAR_STREAM_CTL_TYPE_INT, &id) == -1 ) { // flag -= ROAR_FLAG_VIRTUAL; return -1; } if ( client_stream_move(streams_get_client(parent), id) == -1 ) { return -1; } } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_SYNC ) { ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); switch (ROAR_STREAM(g_streams[id])->dir) { // for this stream types the flag is used in the subsystem: case ROAR_DIR_BRIDGE: case ROAR_DIR_MIDI_OUT: break; // normal behavor (vio blocking): default: ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); // the fh is updated as soon as the fh get ready in case the default ask to set sync if ( g_streams[id]->ready || (!g_streams[id]->ready && !(g_config->streams[ROAR_STREAM(g_streams[id])->dir].flags & ROAR_FLAG_SYNC)) ) { ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( streams_set_sync(id, 1) == -1 ) { ROAR_WARN("streams_set_flag(id=%i, flag=0x%.8X): Can not set SYNC flag.", id, flag); flag -= ROAR_FLAG_SYNC; } } break; } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_SYNC ) { g_streams[id]->flags |= ROAR_FLAG_SYNC; streams_change_sync_num(id, +1); } } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_HWMIXER ) { // currently not supported -> ignored g_streams[id]->flags |= flag; if ( streams_set_mixer(id) == -1 ) { g_streams[id]->flags -= flag; return -1; } } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_RECSOURCE ) { if ( streams_recsource_id != -1 ) { if ( streams_reset_flag(streams_recsource_id, ROAR_FLAG_RECSOURCE) == -1 ) return -1; } if ( g_streams[id]->ready ) { tmp = 1; if ( stream_vio_ctl(id, ROAR_VIO_CTL_SET_RECORD, &tmp) == -1 ) return -1; } streams_recsource_id = id; } ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag); g_streams[id]->flags |= flag; #ifdef ROAR_SUPPORT_META if ( flag & ROAR_FLAG_META ) stream_meta_finalize(id); #endif ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = 0", id, flag); return 0; } int streams_set_rawflag (int id, uint32_t flag) { _CHECK_SID(id); g_streams[id]->flags |= flag; if ( flag & ROAR_FLAG_SYNC ) streams_change_sync_num(id, +1); return 0; } int streams_reset_flag (int id, uint32_t flag) { int tmp; ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = ?", id, flag); _CHECK_SID(id); // check if flags we are going to change are protected: if ( g_streams[id]->flags_protection & flag ) return -1; if ( g_streams[id]->flags & ROAR_FLAG_IMMUTABLE ) { flag |= ROAR_FLAG_PRIMARY; flag -= ROAR_FLAG_PRIMARY; } flag &= g_streams[id]->flags; ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( (flag & ROAR_FLAG_RECSOURCE) && streams_recsource_id == id ) { if ( g_streams[id]->ready ) { tmp = 0; if ( stream_vio_ctl(id, ROAR_VIO_CTL_SET_RECORD, &tmp) == -1 ) { if ( alive ) { // do not warn if we are shutting down anyway. ROAR_WARN("streams_reset_flag(id=%i, flag=0x%.8X): Driver refused to reset record flag.", id, flag); } ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = -1", id, flag); return -1; } } streams_recsource_id = -1; } ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = ?", id, flag); if ( flag & ROAR_FLAG_MMAP ) { if ( streams_set_mmap(id, 1) == -1 ) { flag -= ROAR_FLAG_MMAP; return -1; } } if ( flag & ROAR_FLAG_PRIMARY ) { streams_set_primary(id, 0); flag -= ROAR_FLAG_PRIMARY; } if ( flag & ROAR_FLAG_SINGLESINK ) { if ( streams_set_single_sink(id, 1) == -1 ) { return -1; } flag -= ROAR_FLAG_SINGLESINK; } if ( flag & ROAR_FLAG_SYNC ) { // we refuse to reset the flag on FILTER streams if ( streams_get_dir(id) == ROAR_DIR_FILTER ) { // flags -= ROAR_FLAG_SYNC; return -1; } else { if ( streams_set_sync(id, 0) == -1 ) return -1; g_streams[id]->flags |= ROAR_FLAG_SYNC; g_streams[id]->flags -= ROAR_FLAG_SYNC; flag -= ROAR_FLAG_SYNC; streams_change_sync_num(id, -1); } } g_streams[id]->flags |= flag; g_streams[id]->flags -= flag; ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = 0", id, flag); return 0; } int streams_get_flag (int id, uint32_t flag) { _CHECK_SID(id); return g_streams[id]->flags & flag ? 1 : 0; } int streams_protect_flag (int id, uint32_t flag) { _CHECK_SID(id); g_streams[id]->flags_protection |= flag; return 0; } int streams_set_name (int id, char * name) { char * str; _CHECK_SID(id); if ( (str = roar_mm_strdup(name)) == NULL ) return -1; if ( g_streams[id]->name != NULL ) roar_mm_free(g_streams[id]->name); g_streams[id]->name = str; return 0; } char * streams_get_name (int id) { _CHECK_SID_RET(id, NULL); return g_streams[id]->name; } int streams_calc_delay (int id) { struct roar_stream_server * ss; struct roar_stream * s; register uint_least32_t d = 0; uint_least32_t t[1]; uint64_t tmp; _CHECK_SID(id); if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL ) return -1; // mixer store there value in ss->delay directly if ( s->dir == ROAR_DIR_MIXING ) return 0; #if 0 // this only confuses the user... if ( ss->mixer_stream != id ) { if ( streams_calc_delay(ss->mixer_stream) != -1 ) { d += g_streams[ss->mixer_stream]->delay; // in case we can calc the delay // the stream must exist, so no check here } } #endif if ( ss->codecfilter != -1 ) { if ( codecfilter_delay(ss->codecfilter_inst, ss->codecfilter, t) != -1 ) d += *t; } if ( ss->vio.ctl != NULL ) { if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_GET_DELAY, t) != -1 ) { // *t is in byte ROAR_DBG("streams_calc_delay(id=%i): VIO delay in byte: %i", id, *t); tmp = *t; tmp *= 1000000; // musec per sec tmp /= s->info.rate * s->info.channels * (s->info.bits/8); ROAR_DBG("streams_calc_delay(id=%i): VIO delay in musec: %llu", id, tmp); d += tmp; } } ROAR_DBG("streams_calc_delay(id=%i): delay in musec: %i", id, d); ss->delay = d; return 0; } int streams_set_mixer (int id) { struct roar_stream_server * ss; struct roar_stream_server * pmss; int i; int subsys; int tsubsys; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( streams_get_flag(id, ROAR_FLAG_PASSMIXER) == 1 ) { if ( (subsys = streams_get_subsys(id)) == -1 ) return -1; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (pmss = g_streams[i]) != NULL ) { if ( streams_get_flag(i, ROAR_FLAG_PASSMIXER) == 1 ) { tsubsys = streams_get_subsys(i); if ( tsubsys == subsys || tsubsys == ROAR_SUBSYS_NONE ) { if ( &(pmss->mixer) != &(ss->mixer) ) { if ( roar_conv_volume(&(pmss->mixer), &(ss->mixer), ROAR_STREAM(pmss)->info.channels, ROAR_STREAM(ss)->info.channels) == -1 ) { ROAR_WARN("streams_set_mixer(id=%i): Can not convert mixer settings for stream %i", id, i); } } // update hwmixers and the like but do not set mixer value recrusivly. streams_reset_flag(i, ROAR_FLAG_PASSMIXER); streams_set_mixer(i); streams_set_flag(i, ROAR_FLAG_PASSMIXER); } } } } } roar_notify_core_emit_snoargs(ROAR_OE_STREAM_CHANGE_VOLUME, -1, id, ROAR_OT_STREAM); if ( !streams_get_flag(id, ROAR_FLAG_HWMIXER) ) return 0; if ( ss->driver_id != -1 ) { return driver_set_volume(id, &(ss->mixer)); #ifndef ROAR_WITHOUT_DCOMP_MIXER } else if ( ss->mixerstream != NULL ) { return hwmixer_set_volume(id, ss, ss->mixerstream, &(ss->mixer)); #endif } else { return 0; } } int streams_set_map (int id, char * map, size_t len) { struct roar_stream_server * ss; int ssdir; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( map != NULL ) { if ( ROAR_STREAM(ss)->info.channels != len ) return -1; } ssdir = streams_get_ssdir(id); switch (ssdir) { case STREAM_DIR_IN: case STREAM_DIR_NONE: memset(ss->chanmap.in, 0, sizeof(ss->chanmap.in)); if ( map != NULL ) memcpy(ss->chanmap.in, map, len); roardsp_chanmap_calc(&(ss->chanmap), ROARDSP_CHANMAP_MAP, 0); break; case STREAM_DIR_OUT: memset(ss->chanmap.out, 0, sizeof(ss->chanmap.out)); if ( map != NULL ) memcpy(ss->chanmap.out, map, len); roardsp_chanmap_calc(&(ss->chanmap), ROARDSP_CHANMAP_MAP, 0); break; default: return -1; } return 0; } int streams_get_rpg (int id, struct roar_stream_rpg * rpg) { _CHECK_SID(id); if ( rpg == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } rpg->mode = g_streams[id]->rpgmode; rpg->mul = g_streams[id]->mixer.rpg_mul; rpg->div = g_streams[id]->mixer.rpg_div; if ( rpg->mode == ROAR_RPGMODE_DEFAULT ) rpg->mode = g_config->streams[ROAR_STREAM(g_streams[id])->dir].rpgmode; return 0; } int streams_set_rpg (int id, const struct roar_stream_rpg * rpg) { int mode; _CHECK_SID(id); if ( rpg == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } // test if we have a valid value at all. if ( rpg->mode > ROAR_RPGMODE_TRACKALBUM || rpg->mode < ROAR_RPGMODE_DEFAULT ) { roar_err_set(ROAR_ERROR_RANGE); return -1; } mode = g_streams[id]->rpgmode = rpg->mode; if ( mode == ROAR_RPGMODE_DEFAULT ) mode = g_config->streams[ROAR_STREAM(g_streams[id])->dir].rpgmode; switch (mode) { case ROAR_RPGMODE_NONE: g_streams[id]->mixer.rpg_mul = 1; g_streams[id]->mixer.rpg_div = 1; break; case ROAR_RPGMODE_USER: g_streams[id]->mixer.rpg_mul = rpg->mul; g_streams[id]->mixer.rpg_div = rpg->div; break; } return 0; } int streams_ltm_ctl (int id, int mt, int window, int cmd) { struct roar_stream_server * ss; struct roar_stream_ltm * ltm; int i; _CHECK_SID(id); // currently we only support the WORKBLOCK window if ( window != ROAR_LTM_WIN_WORKBLOCK ) return -1; // currently we only support ROAR_LTM_MT_RMS if ( (mt | ROAR_LTM_MT_RMS) - ROAR_LTM_MT_RMS ) return -1; if ( (ss = g_streams[id]) == NULL ) return -1; switch (cmd) { case ROAR_LTM_SST_NOOP: return 0; break; case ROAR_LTM_SST_REGISTER: // test if the window is already registered: for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) { ltm = &(ss->ltm[i]); if ( ltm->refc && ltm->window == window ) { ltm->refc++; ltm->mt |= mt; return 0; } } // register for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) { ltm = &(ss->ltm[i]); if ( ltm->refc == 0 ) { memset(ltm, 0, sizeof(struct roar_stream_ltm)); ltm->refc = 1; ltm->window = window; ltm->parent_window = -1; ltm->mt = mt; ltm->channels = ROAR_STREAM(ss)->info.channels; if ( (ltm->cur = roar_mm_malloc(ltm->channels*sizeof(struct roar_ltm_vals))) == NULL ) { ltm->refc = 0; // reset return -1; } memset(ltm->cur, 0, ltm->channels*sizeof(struct roar_ltm_vals)); return 0; } } return -1; break; case ROAR_LTM_SST_UNREGISTER: for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) { ltm = &(ss->ltm[i]); if ( ltm->refc && ltm->window == window ) { ltm->refc--; if ( ! ltm->refc ) { roar_mm_free(ltm->cur); return 0; } } } return -1; break; default: return -1; break; } } int streams_ltm_calc (int id, struct roar_audio_info * info, void * data, size_t len) { struct roar_stream_server * ss; struct roar_stream_ltm * ltm = NULL; int64_t rmsbuf_real[8]; int64_t * rmsbuf = rmsbuf_real; size_t samples = 0; int i; _CHECK_SID(id); if ( data == NULL || info == NULL ) return -1; if ( info->codec != ROAR_CODEC_DEFAULT ) return -1; if ( (ss = g_streams[id]) == NULL ) return -1; for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) { if ( ss->ltm[i].refc && ss->ltm[i].window == ROAR_LTM_WIN_WORKBLOCK ) { ltm = &(ss->ltm[i]); break; } } if ( ltm == NULL ) return -1; // TODO: support change of number of channels if ( ltm->channels != info->channels ) return -1; if ( len == 0 ) { memset(ltm->cur, 0, ltm->channels * sizeof(struct roar_ltm_vals)); return 0; } // TODO: support more channels then rmsbuf_real has space for if ( ltm->channels > (sizeof(rmsbuf_real)/sizeof(*rmsbuf_real)) ) { return -1; } samples = len / info->bits; if ( ltm->mt & ROAR_LTM_MT_RMS ) { if ( roar_rms2_1_b_n(data, samples, rmsbuf, ltm->channels, info->bits) == -1 ) return -1; for (i = 0; i < ltm->channels; i++) { ltm->cur[i].rms = rmsbuf[i] << (64 - info->bits*2); } ROAR_DBG("streams_ltm_calc(id=%i,...): rmsbuf[0]=%lli", id, (long long int)rmsbuf[0]); } return 0; } struct roar_stream_ltm * streams_ltm_get(int id, int mt, int window) { struct roar_stream_server * ss; struct roar_stream_ltm * ltm = NULL; int i; _CHECK_SID_RET(id, NULL); if ( (ss = g_streams[id]) == NULL ) return NULL; for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) { if ( ss->ltm[i].refc && ss->ltm[i].window == window ) { ltm = &(ss->ltm[i]); break; } } if ( ltm == NULL ) return NULL; if ( (ltm->mt & mt) != mt ) return NULL; return ltm; } #ifndef ROAR_WITHOUT_DCOMP_MIXER struct hwmixer_stream * streams_get_mixerstream(int id) { _CHECK_SID_RET(id, NULL); return g_streams[id]->mixerstream; } int streams_set_mixerstream(int id, struct hwmixer_stream * mstream) { _CHECK_SID(id); g_streams[id]->mixerstream = mstream; return 0; } int streams_read_mixervalues(int id) { struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( ss->mixerstream == NULL ) return -1; return hwmixer_get_volume(id, ss, ss->mixerstream, &(ss->mixer)); } #endif int streams_ctl (int id, int_least32_t cmd, void * data) { struct roar_stream_server * ss; int_least32_t comp; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; comp = cmd & ROAR_STREAM_CTL_COMPMASK; cmd &= ~comp; ROAR_DBG("streams_ctl(id=%i, cmd=?, data=%p): comp=0x%.8x, cmd=0x%.4x", id, data, comp, cmd); switch (comp) { case ROAR_STREAM_CTL_COMP_BASE: break; case ROAR_STREAM_CTL_COMP_CF: return codecfilter_ctl(ss->codecfilter_inst, ss->codecfilter, cmd, data); break; case ROAR_STREAM_CTL_COMP_DRV: break; default: return -1; } return -1; } int streams_get_outputbuffer (int id, void ** buffer, size_t size) { _CHECK_SID(id); // output buffer size does never change. if ( g_streams[id]->output != NULL ) { *buffer = g_streams[id]->output; return 0; } if ( (g_streams[id]->output = roar_mm_malloc(size)) == NULL ) { ROAR_ERR("streams_get_outputbuffer(*): Can not alloc: %s", strerror(errno)); return -1; } *buffer = g_streams[id]->output; return 0; } int streams_fill_mixbuffer2 (int id, struct roar_audio_info * info) { size_t outlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(info); void * outdata; size_t inlen; size_t inlen_got; void * indata = NULL; size_t buflen; void * bufdata = NULL; struct roar_buffer * bufbuf = NULL; int is_the_same = 0; struct roar_audio_info * stream_info; struct roar_stream * s; struct roar_stream_server * ss; _CHECK_SID(id); if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL ) return -1; // set up stream_info stream_info = &(s->info); // calc todo_in inlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(stream_info); buflen = ROAR_OUTPUT_CALC_OUTBUFSIZE_MAX(info, stream_info); ROAR_DBG("streams_fill_mixbuffer2(id=%i, info=%p{...}): inlen=%lu, buflen=%lu", id, info, (unsigned long)inlen, (unsigned long)buflen); if ( inlen == 0 ) { ROAR_WARN("streams_fill_mixbuffer2(id=%i, info=%p{...}): inlen == 0, this should not happen!", id, info); return -1; } if ( streams_get_outputbuffer(id, &outdata, outlen) == -1 ) { return -1; } if ( outdata == NULL ) { return -1; } ROAR_DBG("streams_fill_mixbuffer2(*): outdata=%p, len=%i->%i (in->out)", outdata, inlen, outlen); is_the_same = stream_info->rate == info->rate && stream_info->bits == info->bits && stream_info->channels == info->channels && stream_info->codec == info->codec; ROAR_DBG("streams_fill_mixbuffer2(*): is_the_same=%i", is_the_same); if ( !is_the_same && buflen > outlen ) { /* // this is not supported at the moment memset(outdata, 0, outlen); return -1; */ if ( roar_buffer_new(&bufbuf, buflen) == -1 ) return -1; if ( roar_buffer_get_data(bufbuf, &bufdata) == -1 ) return -1; indata = bufdata; } else { indata = outdata; bufdata = outdata; } inlen_got = inlen; ROAR_DBG("streams_fill_mixbuffer2(id=%i, info=...): inlen_got=%u", id, inlen_got); if ( stream_shift_out_buffer(id, indata, &inlen_got) == -1 ) { if ( ss->is_new ) { ss->pre_underruns++; roar_notify_core_emit_simple(ROAR_OE_STREAM_XRUN, -1, id, ROAR_OT_STREAM, ROAR_XRUN_UNDER_PRE, ss->pre_underruns, NULL, 0); } else { ROAR_WARN("streams_fill_mixbuffer2(id=%i, info=...): underrun in stream", id); ss->post_underruns++; roar_notify_core_emit_simple(ROAR_OE_STREAM_XRUN, -1, id, ROAR_OT_STREAM, ROAR_XRUN_UNDER_POST, ss->post_underruns, NULL, 0); } memset(outdata, 0, outlen); return 0; } ROAR_DBG("streams_fill_mixbuffer2(id=%i, info=...): inlen_got=%u", id, inlen_got); if ( ss->is_new ) { //ROAR_INFO("streams_fill_mixbuffer2(id=%i, info=...): stream state: new->old", ROAR_DBG_INFO_VERBOSE, id); _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_fill_mixbuffer2"); } ss->is_new = 0; // check channel map: #if 0 if ( roardsp_chanmap_mappcm(indata, indata, inlen, stream_info->channels, &(ss->chanmap), stream_info->bits) == -1 ) { if ( bufbuf != NULL ) roar_buffer_free(bufbuf); return -1; } #endif // TODO: this only works in case a we have a amp for the given stream parameters. if ( !streams_get_flag(id, ROAR_FLAG_HWMIXER) && !streams_get_flag(id, ROAR_FLAG_PASSMIXER) ) { ROAR_DBG("streams_fill_mixbuffer2(*): CALL roar_amp_pcm(*)..."); if ( roar_amp_pcm(indata, stream_info->bits, indata, 8*inlen / stream_info->bits, stream_info->channels, &(ss->mixer)) == -1 ) return -1; } // check codec, bits, channels, rate... if ( is_the_same ) { if ( indata != outdata ) memcpy(outdata, indata, inlen); if ( inlen < outlen ) memset(outdata+inlen, 0, outlen-inlen); } else { // if ( roar_conv(outdata, indata, (8*inlen_got*info->rate)/(stream_info->rate * stream_info->bits), stream_info, info) == -1 ) { ROAR_DBG("streams_fill_mixbuffer2(*): CALL roar_conv2(*)..."); if ( roar_conv2(bufdata, indata, inlen, stream_info, info, outlen) == -1 ) { if ( bufbuf != NULL ) roar_buffer_free(bufbuf); return -1; } // memset(outdata, 0, outlen); } if ( bufbuf != NULL ) { memcpy(outdata, bufdata, outlen); roar_buffer_free(bufbuf); } streams_ltm_calc(id, stream_info, outdata, outlen); if ( streams_get_flag(id, ROAR_FLAG_ANTIECHO) ) { ROAR_DBG("streams_fill_mixbuffer2(*): Calcing antiecho..."); // we can ignore errors here: if ( stream_outputbuffer_request(id, &bufbuf, buflen) == 0 ) { if ( roar_buffer_get_data(bufbuf, &bufdata) != -1 ) memcpy(bufdata, outdata, outlen); } } ROAR_DBG("streams_fill_mixbuffer2(*): inlen_got=%llu, stream_info={.bits=%i, .rate=%i,...}", (long long unsigned int)inlen_got, stream_info->bits, stream_info->rate); s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, (inlen_got*8)/stream_info->bits); ROAR_DBG("streams_fill_mixbuffer2(*) = 0"); return 0; } int streams_get_mixbuffers (void *** bufferlist, struct roar_audio_info * info, unsigned int pos) { static void * bufs[ROAR_STREAMS_MAX+1]; int i; int have = 0; int dir; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL ) { dir = streams_get_dir(i); switch (dir) { case ROAR_DIR_PLAY: case ROAR_DIR_BIDIR: case ROAR_DIR_RECPLAY: break; case ROAR_DIR_BRIDGE: if ( g_streams[i]->buffer == NULL ) continue; break; default: continue; } if ( streams_get_flag(i, ROAR_FLAG_PAUSE) ) continue; if ( streams_get_outputbuffer(i, &bufs[have], ROAR_OUTPUT_CALC_OUTBUFSIZE(info)) == -1 ) { ROAR_ERR("streams_get_mixbuffer(*): Can not alloc output buffer for stream %i, BAD!", i); ROAR_ERR("streams_get_mixbuffer(*): Ignoring stream for this round."); continue; } if ( streams_fill_mixbuffer2(i, info) == -1 ) { ROAR_ERR("streams_get_mixbuffer(*): Can not fill output buffer for stream %i, this should not happen", i); continue; } // printf("D: bufs[have=%i] = %p\n", have, bufs[have]); ROAR_DBG("streams_get_mixbuffers(*): bufs[have] = %p", bufs[have]); ROAR_DBG("streams_get_mixbuffers(*): *bufs[have] = 0x%08x...", *(uint32_t*)bufs[have]); if ( !streams_get_flag(i, ROAR_FLAG_MUTE) ) have++; // we have a new stream! } } bufs[have] = NULL; //printf("D: bufs[have=%i] = %p\n", have, bufs[have]); ROAR_DBG("streams_get_mixbuffers(*): have = %i", have); *bufferlist = bufs; return have; } int stream_add_buffer (int id, struct roar_buffer ** buf) { ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = ?", id, buf); _CHECK_SID(id); if ( g_streams[id]->buffer == NULL ) { g_streams[id]->buffer = *buf; *buf = NULL; ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = 0", id, buf); return 0; } ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = ?", id, buf); return roar_buffer_moveinto(g_streams[id]->buffer, buf); } int stream_shift_out_buffer (int id, void * data, size_t * len) { _CHECK_SID(id); if ( g_streams[id]->buffer == NULL ) return -1; return roar_buffer_shift_out(&(g_streams[id]->buffer), data, len); } int stream_outputbuffer_request(int id, struct roar_buffer ** buf, size_t len) { register struct roar_stream_server * ss; size_t buflen; void * bufdata; int ret; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( buf != NULL ) /* just be be sure */ *buf = NULL; if ( ss->outputbuffer != NULL ) { if ( roar_buffer_get_len(ss->outputbuffer, &buflen) == 0 ) { if ( buflen == len ) { if ( buf != NULL ) *buf = ss->outputbuffer; return 0; } else if ( buflen > len ) { if ( roar_buffer_set_len(ss->outputbuffer, len) == 0 ) { if ( buf != NULL ) *buf = ss->outputbuffer; return 0; } } } // if the buffer is not suitable: ret = roar_buffer_free(ss->outputbuffer); ss->outputbuffer = NULL; if ( ret == -1 ) return ret; } if ( roar_buffer_new(&(ss->outputbuffer), len) == -1 ) return -1; if ( roar_buffer_get_data(ss->outputbuffer, &bufdata) == -1 ) { roar_buffer_free(ss->outputbuffer); ss->outputbuffer = NULL; return -1; } memset(bufdata, 0, len); if ( buf != NULL ) *buf = ss->outputbuffer; return 0; } int stream_outputbuffer_destroy(int id) { int ret; register struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( ss->outputbuffer != NULL ) { ret = roar_buffer_free(ss->outputbuffer); ss->outputbuffer = NULL; return ret; } return 0; } int stream_prethru_add(int id, struct roar_buffer ** buf) { register struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( ss->prethru == NULL ) { ss->prethru = *buf; *buf = NULL; return 0; } if ( roar_buffer_moveinto(ss->prethru, buf) == -1 ) { return -1; } return 0; } int stream_prethru_add_data(int id, void ** buf, size_t len) { struct roar_buffer * buffer; _CHECK_SID(id); if ( roar_buffer_new_data(&buffer, len, buf) == -1 ) return -1; if ( stream_prethru_add(id, &buffer) == -1 ) { roar_buffer_free(buffer); return -1; } return 0; } int stream_prethru_destroy(int id) { int ret; register struct roar_stream_server * ss; _CHECK_SID(id); if ( (ss = g_streams[id]) == NULL ) return -1; if ( ss->prethru != NULL ) { ret = roar_buffer_free(ss->prethru); ss->prethru = NULL; return ret; } return 0; } int stream_prethru_send(int dst, int src) { struct roar_stream_server * dst_ss, * src_ss; struct roar_buffer * bufbuf; void * bufdata; size_t buflen; ROAR_DBG("stream_prethru_send(dst=%i, src=%i) = ?", dst, src); _CHECK_SID(dst); _CHECK_SID(src); if ( (dst_ss = g_streams[dst]) == NULL ) return -1; if ( (src_ss = g_streams[src]) == NULL ) return -1; bufbuf = src_ss->prethru; ROAR_DBG("stream_prethru_send(dst=%i, src=%i): prethru buffer at %p", dst, src, bufbuf); roar_buffer_foreach(bufbuf) { ROAR_DBG("stream_prethru_send(dst=%i, src=%i): looping with buffer at %p", dst, src, bufbuf); if ( roar_buffer_get_data(bufbuf, &bufdata) == -1 ) return -1; if ( roar_buffer_get_len(bufbuf, &buflen) == -1 ) return -1; if ( stream_vio_s_write(dst_ss, bufdata, buflen) != buflen ) return -1; } ROAR_DBG("stream_prethru_send(dst=%i, src=%i) = 0", dst, src); return 0; } int streams_check (int id) { int fh; ssize_t req, realreq, done; struct roar_stream * s; struct roar_stream_server * ss; struct roar_buffer * b; void * buf; // char tmp; _CHECK_SID(id); ROAR_DBG("streams_check(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); if ( (fh = s->fh) == -1 ) return 0; if ( streams_get_flag(id, ROAR_FLAG_PAUSE) ) return 0; switch (s->dir) { case ROAR_DIR_LIGHT_IN: #ifndef ROAR_WITHOUT_DCOMP_LIGHT return light_check_stream(id); #else streams_delete(id); return -1; #endif break; case ROAR_DIR_MIDI_IN: #ifndef ROAR_WITHOUT_DCOMP_MIDI return midi_check_stream(id); #else streams_delete(id); return -1; #endif break; case ROAR_DIR_RAW_IN: #ifndef ROAR_WITHOUT_DCOMP_RAW return raw_check_stream(id); #else streams_delete(id); return -1; #endif break; case ROAR_DIR_RDTCS_IN: #ifndef ROAR_WITHOUT_DCOMP_RDTCS return rdtcs_check_stream(id); #else streams_delete(id); return -1; #endif break; case ROAR_DIR_PLAY: case ROAR_DIR_BIDIR: case ROAR_DIR_RECPLAY: break; case ROAR_DIR_OUTPUT: if ( !streams_get_flag(id, ROAR_FLAG_RECSOURCE) ) return 0; break; default: /* ROAR_WARN("streams_check(id=%i): Read event on non input stream of type/dir %s", id, roar_dir2str(s->dir)); errno = 0; req = stream_vio_s_read(ss, &tmp, 1); ROAR_DBG("streams_check(id=%i): stream_vio_s_read(ss, &tmp, 1) = %li // errno=%s(%i)", id, req, strerror(errno), errno); if ( req == 1 ) { ROAR_ERR("streams_check(id=%i): Client violates protocol, got one byte of data on output stream, kicking stream"); streams_delete(id); return -1; } */ return 0; break; } ROAR_DBG("streams_check(id=%i): fh = %i", id, fh); /* ROAR_DBG("streams_check(id=%i): ROAR_OUTPUT_BUFFER_SAMPLES=%i, s->info.channels=%i, s->info.bits=%i, s->info.rat=%i, g_sa->rate=%i", id, ROAR_OUTPUT_BUFFER_SAMPLES, s->info.channels, s->info.bits, s->info.rate, g_sa->rate); */ req = ROAR_OUTPUT_CALC_OUTBUFSIZE(&(s->info)); // optimal size // req = ROAR_OUTPUT_BUFFER_SAMPLES * s->info.channels * (s->info.bits / 8) * ((float)s->info.rate/g_sa->rate); req += ss->need_extra; // bytes left we sould get.... ROAR_DBG("streams_check(id=%i): asking for %i bytes", id, req); if ( roar_buffer_new_data(&b, req, &buf) == -1 ) { ROAR_ERR("streams_check(*): Can not alloc buffer space!"); ROAR_DBG("streams_check(*) = -1"); return -1; } ROAR_DBG("streams_check(id=%i): buffer is up and ready ;)", id); ROAR_DBG("streams_check(id=%i): asking for %i bytes", id, req); if ( ss->codecfilter == -1 ) { realreq = req; /* req = read(fh, buf, req); if ( req < realreq ) { // we can do this as the stream is in nonblocking mode! if ( (realreq = read(fh, buf+req, realreq-req)) > 0 ) req += realreq; } */ done = 0; while (req > 0 && done != realreq) { if ( (req = stream_vio_s_read(ss, buf+done, realreq-done)) > 0 ) done += req; } req = done; } else { req = codecfilter_read(ss->codecfilter_inst, ss->codecfilter, buf, req); } if ( req > 0 ) { ROAR_DBG("streams_check(id=%i): got %i bytes", id, req); if ( roar_buffer_set_len(b, req) != -1 ) { if ( stream_add_buffer(id, &b) != -1 ) return 0; ROAR_ERR("streams_check(id=%i): something is wrong, could not add buffer to stream!", id); } else { ROAR_ERR("streams_check(id=%i): something is wrong, could not set size of buffer!", id); } roar_buffer_free(b); } else { ROAR_DBG("streams_check(id=%i): read() = %i // errno: %s", id, req, strerror(errno)); #ifdef ROAR_HAVE_LIBVORBISFILE if ( errno != EAGAIN && errno != ESPIPE ) { // libvorbis file trys to seek a bit ofen :) #else if ( errno != EAGAIN ) { #endif ROAR_DBG("streams_check(id=%i): EOF!", id); streams_delete(id); ROAR_DBG("streams_check(id=%i) = 0", id); } roar_buffer_free(b); return 0; } ROAR_DBG("streams_check(id=%i) = -1", id); return -1; } #define _return(x) return (x) int streams_send_mon (int id) { // int fh; struct roar_stream * s; struct roar_stream_server * ss; struct roar_buffer * bufbuf = NULL; struct roar_remove_state removalstate; void * ip = g_output_buffer; void * obuf; int olen; int is_the_same = 1; int is_vol_eq = 1; int is_muted; int antiecho = 0; ssize_t ret; _CHECK_SID(id); ROAR_DBG("streams_send_mon(id=%i) = ?", id); s = ROAR_STREAM((ss = g_streams[id])); /* if ( (fh = s->fh) == -1 ) return 0; */ if ( !ss->ready ) return 0; if ( g_config->jumbo_mtu ) roar_vio_sync(ss->viop); if ( streams_get_flag(id, ROAR_FLAG_PAUSE) ) return 0; switch (s->dir) { case ROAR_DIR_LIGHT_OUT: #ifndef ROAR_WITHOUT_DCOMP_LIGHT return light_send_stream(id); #else streams_delete(id); return -1; #endif break; case ROAR_DIR_MIDI_OUT: #ifndef ROAR_WITHOUT_DCOMP_MIDI return midi_send_stream(id); #else streams_delete(id); return -1; #endif break; case ROAR_DIR_RDTCS_OUT: #ifndef ROAR_WITHOUT_DCOMP_RDTCS return rdtcs_send_stream(id); #else streams_delete(id); return -1; #endif break; case ROAR_DIR_COMPLEX_OUT: // send a tick: if ( ss->codecfilter != -1 ) { if ( codecfilter_write(ss->codecfilter_inst, ss->codecfilter, NULL, 0) == 0 ) if ( ss->state != ROAR_STREAMSTATE_OLD ) { //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon"); } } return 0; break; case ROAR_DIR_OUTPUT: if ( g_standby ) return 0; case ROAR_DIR_MONITOR: case ROAR_DIR_BIDIR: break; case ROAR_DIR_RECORD: case ROAR_DIR_RECPLAY: ip = g_input_buffer; break; default: return 0; break; } ROAR_DBG("streams_send_mon(id=%i): fh = %i", id, s->fh); if ( s->info.channels != g_sa->channels || s->info.bits != g_sa->bits || s->info.rate != g_sa->rate || s->info.codec != g_sa->codec ) is_the_same = 0; is_muted = streams_get_flag(id, ROAR_FLAG_MUTE); if ( !is_muted && !streams_get_flag(id, ROAR_FLAG_HWMIXER) ) { is_vol_eq = need_vol_change(g_sa->channels, &(ss->mixer)) ? 0 : 1; } if ( streams_get_flag(id, ROAR_FLAG_ANTIECHO) ) antiecho = 1; if ( !is_the_same || !is_vol_eq || antiecho || is_muted ) { olen = ROAR_OUTPUT_CALC_OUTBUFSIZE(&(s->info)); // we hope g_output_buffer_len // is ROAR_OUTPUT_CALC_OUTBUFSIZE(g_sa) here if ( stream_outputbuffer_request(id, &bufbuf, ROAR_OUTPUT_CALC_OUTBUFSIZE_MAX(&(s->info), g_sa)) == -1 ) return -1; if ( roar_buffer_get_data(bufbuf, &obuf) == -1 ) { _return(-1); } ROAR_DBG("streams_send_mon(id=%i): obuf=%p, olen=%i", id, obuf, olen); } else { obuf = ip; olen = g_output_buffer_len; } if ( antiecho ) { ROAR_DBG("streams_send_mon(id=%i): antiecho=%i", id, antiecho); if ( roar_remove_init(&removalstate) == -1 ) { _return(-1); } ROAR_DBG("streams_send_mon(id=%i): antiecho=%i", id, antiecho); if ( roar_remove_so(obuf, ip, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels, g_sa->bits, &removalstate) == -1 ) { ROAR_DBG("streams_send_mon(id=%i): anti echo failed", id); _return(-1); } ROAR_DBG("streams_send_mon(id=%i): antiecho=%i", id, antiecho); } if ( !is_vol_eq ) { if ( roar_amp_pcm(obuf, g_sa->bits, ip, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels, g_sa->channels, &(ss->mixer)) == -1 ) { _return(-1); } ip = obuf; } if ( is_muted ) { memset(obuf, 0, (g_sa->bits*ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels)/8); ip = obuf; } streams_ltm_calc(id, &(s->info), ip, (ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels*g_sa->bits)/8); if ( !is_the_same ) { if ( roar_conv(obuf, ip, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels, g_sa, &(s->info)) == -1 ) { _return(-1); } } roar_err_clear_errno(); if ( ss->codecfilter == -1 ) { ROAR_DBG("streams_send_mon(id=%i): not a CF stream", id); if ( s->fh == -1 && ss->vio.inst == NULL ) { ROAR_DBG("streams_send_mon(id=%i) = 0", id); _return(0); } ROAR_DBG("streams_send_mon(id=%i) = ?", id); if ( (ret = stream_vio_s_write(ss, obuf, olen)) == olen ) { s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels); if ( ss->state != ROAR_STREAMSTATE_OLD ) { //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon"); } ROAR_DBG("streams_send_mon(id=%i) = 0", id); _return(0); } ROAR_DBG("streams_send_mon(id=%i) = ?", id); if ( ret > 0 && roar_err_is_errno_clear() ) { ROAR_WARN("streams_send_mon(id=%i): Overrun in stream: wrote %i of %i bytes, %i bytes missing", id, (int)ret, olen, olen-(int)ret); roar_notify_core_emit_simple(ROAR_OE_STREAM_XRUN, -1, id, ROAR_OT_STREAM, ROAR_XRUN_OVER_POST, -1, NULL, 0); s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), ret)*s->info.channels); if ( ss->state != ROAR_STREAMSTATE_OLD ) { //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon"); } _return(0); } } else { if ( codecfilter_write(ss->codecfilter_inst, ss->codecfilter, obuf, olen) == olen ) { s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels); if ( ss->state != ROAR_STREAMSTATE_OLD ) { //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon"); } _return(0); } else { // we cann't retry on codec filetered streams if ( errno != EAGAIN ) { streams_delete(id); _return(-1); } } } if ( errno == EAGAIN ) { // ok, the client blocks for a moment, we try to sleep a bit an retry in the hope not to // make any gapes in any output because of this #ifdef ROAR_HAVE_USLEEP roar_usleep(100); // 0.1ms #endif if ( stream_vio_s_write(ss, obuf, olen) == olen ) { s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels); if ( ss->state != ROAR_STREAMSTATE_OLD ) { //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state)); _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon"); } _return(0); } else if ( errno == EAGAIN ) { ROAR_WARN("streams_send_mon(id=%i): Can not send data to client: %s", id, strerror(errno)); _return(0); } } // ug... error... delete stream! streams_delete(id); _return(-1); } #undef _return int streams_send_filter_all(void) { struct roar_stream_server * ss; int i; for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( (ss = g_streams[i]) == NULL ) continue; if ( ROAR_STREAM(ss)->dir != ROAR_DIR_FILTER ) continue; if ( !ss->ready ) continue; if ( ss->state == ROAR_STREAMSTATE_CLOSING ) continue; streams_send_filter(i); } return 0; } int streams_send_filter(int id) { int fh; int have = 0; int len; struct roar_stream * s; struct roar_stream_server * ss; _CHECK_SID(id); ROAR_DBG("streams_send_filter(id=%i) = ?", id); s = ROAR_STREAM(ss = g_streams[id]); if ( (fh = s->fh) == -1 ) return 0; if ( s->dir != ROAR_DIR_FILTER ) return 0; if ( streams_get_flag(id, ROAR_FLAG_PAUSE) ) return 0; ROAR_DBG("streams_send_filter(id=%i): fh = %i", id, fh); if ( stream_vio_s_write(ss, g_output_buffer, g_output_buffer_len) == g_output_buffer_len ) { while ( have < g_output_buffer_len ) { if ( (len = stream_vio_s_read(ss, g_output_buffer+have, g_output_buffer_len-have)) < 1 ) { streams_delete(id); return -1; } have += len; } return 0; } // ug... error... delete stream! streams_delete(id); return -1; } // VIO: ssize_t stream_vio_read (int stream, void *buf, size_t count) { _CHECK_SID(stream); return stream_vio_s_read(g_streams[stream], buf, count); } ssize_t stream_vio_write(int stream, void *buf, size_t count) { _CHECK_SID(stream); return stream_vio_s_write(g_streams[stream], buf, count); } int stream_vio_ctl (int stream, roar_vio_ctl_t cmd, void * data) { _CHECK_SID(stream); return stream_vio_s_ctl(g_streams[stream], cmd, data); } ssize_t stream_vio_s_read (struct roar_stream_server * stream, void *buf, size_t count) { void * orig_buf = buf; size_t len = 0; ssize_t r = -1; int i; errno = 0; if ( stream == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } if ( stream->vio.read == NULL ) { roar_err_set(ROAR_ERROR_NOTSUP); return -1; } while ( (r = roar_vio_read(&(stream->vio), buf, count)) > 0 ) { len += r; buf += r; count -= r; if ( count == 0 ) break; } if ( len == 0 && r == -1 ) return -1; if ( streams_thru_num ) { for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL && ROAR_STREAM(g_streams[i])->pos_rel_id == ROAR_STREAM(stream)->id ) { if ( ROAR_STREAM(g_streams[i])->dir == ROAR_DIR_THRU ) { if ( g_streams[i]->ready ) { if ( stream_vio_write(i, orig_buf, len) != len ) streams_delete(i); if ( g_streams[i] != NULL ) { if ( g_streams[i]->state != ROAR_STREAMSTATE_OLD ) { //ROAR_INFO("stream_vio_s_read(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state)); _streams_change_state(g_streams[i], ROAR_STREAMSTATE_OLD, "stream_vio_s_read"); } } } } } } } return len; } ssize_t stream_vio_s_write(struct roar_stream_server * stream, void *buf, size_t count) { int i; errno = 0; if ( stream == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } // ROAR_WARN("stream_vio_s_write(*): writing..."); if ( streams_thru_num ) { for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL && ROAR_STREAM(g_streams[i])->pos_rel_id == ROAR_STREAM(stream)->id ) { if ( ROAR_STREAM(g_streams[i])->dir == ROAR_DIR_THRU ) { if ( g_streams[i]->ready ) { if ( g_streams[i]->state == ROAR_STREAMSTATE_NEW ) { if ( streams_get_flag(i, ROAR_FLAG_PRETHRU) == 1 ) { if ( stream_prethru_send(i, ROAR_STREAM(stream)->id) == -1 ) { streams_delete(i); } } } if ( stream_vio_write(i, buf, count) != count ) { streams_delete(i); } if ( g_streams[i] != NULL ) { if ( g_streams[i]->state != ROAR_STREAMSTATE_OLD ) { //ROAR_INFO("stream_vio_s_write(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state)); _streams_change_state(g_streams[i], ROAR_STREAMSTATE_OLD, "stream_vio_s_write"); } } } } } } } if ( g_config->jumbo_mtu ) { if ( stream->viop != &(stream->jumbo) ) { if ( roar_vio_open_jumbo(&(stream->jumbo), &(stream->vio), g_config->jumbo_mtu) != -1 ) { // if that works we continue using the jumbo vio, // in case it didn't we dont, just use normal VIO. stream->viop = &(stream->jumbo); } } } return roar_vio_write(stream->viop, buf, count); } int stream_vio_s_ctl (struct roar_stream_server * stream, roar_vio_ctl_t cmd, void * data) { if ( stream == NULL ) { roar_err_set(ROAR_ERROR_FAULT); return -1; } return roar_vio_ctl(stream->viop, cmd, data); } //ll roaraudio-1.0beta11/roard/waveform.c0000644000175000017500000001172612264733701015574 0ustar phiphi//waveform.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014 * * This file is part of roard a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "roard.h" // declared 'extern'. struct waveform_stream g_waveform_mixer, g_waveform_recbridge; static int waveform_init_recbridge (void) { struct roar_stream * s; if ( (g_waveform_recbridge.stream = streams_new()) == -1 ) return -1; client_stream_add(g_self_client, g_waveform_recbridge.stream); streams_get(g_waveform_recbridge.stream, &(g_waveform_recbridge.ss)); s = ROAR_STREAM(g_waveform_recbridge.ss); memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); s->pos_rel_id = g_waveform_mixer.stream; if ( streams_set_dir(g_waveform_recbridge.stream, ROAR_DIR_BRIDGE, 1) == -1 ) { streams_delete(g_waveform_recbridge.stream); g_waveform_recbridge.stream = -1; g_waveform_recbridge.ss = NULL; return -1; } streams_set_name(g_waveform_recbridge.stream, "Record Bridge"); streams_set_flag(g_waveform_recbridge.stream, ROAR_FLAG_PRIMARY); streams_set_flag(g_waveform_recbridge.stream, ROAR_FLAG_SYNC); streams_set_flag(g_waveform_recbridge.stream, ROAR_FLAG_MUTE); return 0; } int waveform_init (void) { struct roar_stream_server * ss; struct roar_stream * s; int i; char cmap[ROAR_MAX_CHANNELS]; // setup mixer: if ( (g_waveform_mixer.stream = add_mixer(ROAR_SUBSYS_WAVEFORM, _MIXER_NAME("Waveform"), &ss)) == -1 ) return -1; g_waveform_mixer.ss = ss; s = ROAR_STREAM(ss); memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info)); roardsp_chanlist_init(cmap, s->info.channels, ROARDSP_CHANLIST_MAP_ROARAUDIO); streams_set_map(g_waveform_mixer.stream, cmap, s->info.channels); ss->state = ROAR_STREAMSTATE_OLD; // setup Record Bridge: if ( waveform_init_recbridge() == -1 ) { ROAR_WARN("waveform_init(void): Can not setup Record Bridge."); streams_delete(g_waveform_mixer.stream); g_waveform_mixer.stream = -1; g_waveform_mixer.ss = NULL; return -1; } streams_set_mixer_stream(g_waveform_recbridge.stream, g_waveform_mixer.stream); // attach all waveform streams to the mixer. for (i = 0; i < ROAR_STREAMS_MAX; i++) { if ( g_streams[i] != NULL ) { if ( streams_get_subsys(i) == ROAR_SUBSYS_WAVEFORM ) { streams_set_mixer_stream(i, g_waveform_mixer.stream); } } } return 0; } int waveform_free (void) { return 0; } int waveform_update_inputs (void) { struct roar_buffer * buf; void * bufdata; // read recorded data...: if ( streams_recsource_id != -1 ) { if ( streams_get_outputbuffer(streams_recsource_id, &bufdata, g_input_buffer_len) == -1 ) { ROAR_WARN("waveform_update_mixer(void): can not request output buffer for record stream %i.", streams_recsource_id); } else { if ( streams_fill_mixbuffer2(streams_recsource_id, g_sa) == -1 ) { ROAR_WARN("waveform_update_mixer(void): can not fill output buffer for record stream %i.", streams_recsource_id); } else { memcpy(g_input_buffer, bufdata, g_input_buffer_len); } } } if ( !(g_waveform_recbridge.ss->flags & (ROAR_FLAG_PAUSE|ROAR_FLAG_MUTE)) ) { if ( roar_buffer_new_no_ma(&buf, g_input_buffer_len, g_input_buffer) == -1 ) { ROAR_ERR("waveform_update_inputs(void): Can not create a new buffer object for Record Bridge. Bad."); return -1; } if ( stream_add_buffer(g_waveform_recbridge.stream, &buf) == -1 ) { ROAR_ERR("waveform_update_inputs(void): Can not attach a new buffer object to the Record Bridge. Bad."); roar_buffer_free(buf); return -1; } } return 0; } int waveform_update_mixer (void) { if ( streams_get_flag(g_waveform_mixer.stream, ROAR_FLAG_MUTE) == 1 ) { memset(g_output_buffer, 0, (g_sa->bits*ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels)/8); return 0; } if ( need_vol_change(ROAR_STREAM(g_waveform_mixer.ss)->info.channels, &(g_waveform_mixer.ss->mixer)) ) { roar_amp_pcm(g_output_buffer, g_sa->bits, g_output_buffer, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels, g_sa->channels, &(g_waveform_mixer.ss->mixer)); } streams_ltm_calc(g_waveform_mixer.stream, &(ROAR_STREAM(g_waveform_mixer.ss)->info), g_output_buffer, (g_sa->bits*ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels)/8); return 0; } //ll roaraudio-1.0beta11/tests/0000755000175000017500000000000012267553202013625 5ustar phiphiroaraudio-1.0beta11/tests/Makefile0000644000175000017500000000263312100223743015257 0ustar phiphiinclude ../Makefile.conf include ../Makefile.inc CLIENTS=roar-config roarbidir roarcat roarcatplay roarcatvio roarctl roarfilt roarmon roarradio roarshout roarsin roarsockconnect roartypes roarvorbis roarvumeter roarinterconnect roarlight roarphone INCLUDE = -I../include CFLAGS += $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(fPIC) LDFLAGS+= $(DEBUG_g) $(Wall) $(Wextra) $(OPTI_O) -L../lib $(LDPATH) all: echo Warning: There is nothing to build clean: sandbox-clean rm -f *.o rat-* new: clean all #test: sandbox-install test-all sandbox-clean test: sandbox-clean sandbox-install test-all sandbox-clean test-all: test-runnable test-roard test-rat test-buffer_set_len test-runnable: PREFIX_BIN=$(PREFIX_BIN) PREFIX_LIB=$(PREFIX_LIB) EXEC_HELPER=$(EXEC_HELPER) ./test-runnable.sh "$(CLIENTS)" test-roard: PREFIX_BIN=$(PREFIX_BIN) PREFIX_LIB=$(PREFIX_LIB) EXEC_HELPER=$(EXEC_HELPER) ./test-roard.sh test-rat: rat.o test-rat.o $(CC) $(LDFLAGS) -o rat-rat rat.o test-rat.o $(EXEC_HELPER) ./rat-rat test-buffer_set_len: rat.o test-buffer_set_len.o $(CC) $(LDFLAGS) -o rat-buffer_set_len rat.o test-buffer_set_len.o $(LIBROAR) LD_LIBRARY_PATH="`pwd`/sandbox/$(PREFIX_LIB)/" PATH="`pwd`/sandbox/$(PREFIX_LIB)/:$$PATH" $(EXEC_HELPER) ./rat-buffer_set_len sandbox-install: sandbox sandbox: mkdir sandbox sh -c 'cd ..; DESTDIR=`pwd`/tests/sandbox/ $(MAKE) install' sandbox-clean: rm -rf sandbox/ roaraudio-1.0beta11/tests/common.sh0000755000175000017500000000122512100223743015442 0ustar phiphi#!/bin/sh PWD=`pwd` PF="$PWD/sandbox" LIB_PATH="$PF/$PREFIX_LIB" if [ "$LD_LIBRARY_PATH" = '' ] then export LD_LIBRARY_PATH="$LIB_PATH" else export LD_LIBRARY_PATH="$LIB_PATH:$LD_LIBRARY_PATH" fi export PATH="$LIB_PATH:$PATH" export BIN_PATH="$PF/$PREFIX_BIN" OK=0 FAILED=0 if [ "$TEST_NAME" != '' ] then echo "Test Name : $TEST_NAME" if [ "$TEST_DESC" != '' ] then echo "Test Description: $TEST_DESC" fi echo '---------------------' fi _ok() { OK=`expr $OK + 1` } _failed() { FAILED=`expr $FAILED + 1` } disp_sum() { SUM=`expr $OK + $FAILED` echo echo "Done $SUM tests: $OK ok, $FAILED failed." echo } ret() { exit $FAILED } #ll roaraudio-1.0beta11/tests/rat.c0000644000175000017500000000540312264733721014564 0ustar phiphi//rat.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of rat a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * */ #include "rat.h" #include struct rat_testgroup { unsigned int ok, fail; }; struct rat_tests { struct rat_testgroup all, subtests, cur_subtests; unsigned int testsc, subtestsc; }; static struct rat_tests inst; void rat_init(const char * name, const char * desc) { memset(&inst, 0, sizeof(inst)); printf("---[ %s ]---\n", name); printf("Description: %s\n", desc); printf("\n"); } int rat_fin(void) { printf("\n"); printf("Summery:\n"); printf("%u of %u tests ok, %u tests failed.\n", inst.all.ok, inst.testsc, inst.all.fail); return inst.all.fail; } void rat_test(const char * title, int res) { printf("Test %-32s: %s\n", title, res ? "ok" : "failed"); inst.testsc++; if ( res ) { inst.all.ok++; } else { inst.all.fail++; } } void rat_test_zero(const char * title, int res) { rat_test(title, res == 0); } void rat_test_with_subtests(const char * title) { memset(&(inst.cur_subtests), 0, sizeof(inst.cur_subtests)); printf("Test %-32s: ", title); fflush(stdout); } void rat_subtests_fin(void) { printf(" %u ok, %u failed.\n", inst.cur_subtests.ok, inst.cur_subtests.fail); inst.subtests.ok += inst.cur_subtests.ok; inst.subtests.fail += inst.cur_subtests.fail; inst.testsc++; if ( inst.cur_subtests.fail ) { inst.all.fail++; } else { inst.all.ok++; } } void rat_subtest(int res) { inst.subtestsc++; if ( res ) { printf("."); inst.cur_subtests.ok++; } else { printf("e"); inst.cur_subtests.fail++; } fflush(stdout); } void rat_subtest_crit(int res) { inst.subtestsc++; if ( res ) { printf("."); inst.cur_subtests.ok++; } else { printf("E"); inst.cur_subtests.fail++; } fflush(stdout); } //ll roaraudio-1.0beta11/tests/rat.h0000644000175000017500000000303212264733723014567 0ustar phiphi//rat.h: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014 * * This file is part of rat a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * libroar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * NOTE for everyone want's to change something and send patches: * read README and HACKING! There a addition information on * the license of this document you need to read before you send * any patches. * */ #ifndef _RAT_H_ #define _RAT_H_ #include void rat_init(const char * name, const char * desc); int rat_fin(void); void rat_test(const char * title, int res); void rat_test_zero(const char * title, int res); void rat_test_with_output(const char * title, int res); void rat_test_with_subtests(const char * title); void rat_subtests_fin(void); void rat_subtest(int res); void rat_subtest_crit(int res); #endif //ll roaraudio-1.0beta11/tests/test-buffer_set_len.c0000644000175000017500000000112412024053056017717 0ustar phiphi#include "rat.h" #include int main (void) { struct roar_buffer * buf; rat_init("roar_buffer_set_len", "testing roar_buffer_set_len()"); rat_test("Creating buffer (size: 3)", roar_buffer_new(&buf, 3) == 0); rat_test("Setting buffer size to 1", roar_buffer_set_len(buf, 1) == 0); rat_test("Setting buffer size to 2", roar_buffer_set_len(buf, 2) == 0); rat_test("Setting buffer size to 3", roar_buffer_set_len(buf, 3) == 0); rat_test("Setting buffer size to 4", roar_buffer_set_len(buf, 4) == 0); rat_test("Freeing buffer", roar_buffer_free(buf) == 0); return rat_fin(); } roaraudio-1.0beta11/tests/test-rat.c0000644000175000017500000000077511456350360015544 0ustar phiphi#include "rat.h" int main (void) { int ret; rat_init("RAT", "testing RAT itself before any other tests, stage 0"); rat_test("Dummy test with const, ok", 1); rat_test("Dummy test with const, fail", 0); rat_test_with_subtests("Subtests"); rat_subtest(1); rat_subtest(0); rat_subtest_crit(1); rat_subtest_crit(0); rat_subtests_fin(); ret = rat_fin(); rat_init("RAT", "testing RAT itself before any other tests, stage 1"); rat_test("Return value of stage 0", ret == 2); return rat_fin(); } roaraudio-1.0beta11/tests/test-roard.sh0000755000175000017500000000051511376746734016267 0ustar phiphi#!/bin/sh TEST_NAME='roard test' TEST_DESC='Do tests on RoarAudio'\''s Sound Daemon' . ./common.sh c=roard FORMAT="%-42s : " printf "$FORMAT" 'Testing for general runnability' if $EXEC_HELPER $BIN_PATH$c --no-listen -o null < /dev/null > /dev/null 2> /dev/null then _ok echo ok else _failed echo failed fi disp_sum ret #ll roaraudio-1.0beta11/tests/test-runnable.sh0000755000175000017500000000054211650577244016757 0ustar phiphi#!/bin/sh TEST_NAME='Runnable test' TEST_DESC='Test clients for runnability' . ./common.sh CLIENTS="$1" for c in $CLIENTS; do printf "%-16s : " "$c" $EXEC_HELPER $BIN_PATH$c --server +invalid < /dev/null > /dev/null 2> /dev/null R=$? if [ "$R" -le 64 ] then _ok echo ok else _failed echo "FAILED! ret=$R" fi done disp_sum ret #ll roaraudio-1.0beta11/tools/0000755000175000017500000000000012267553202013623 5ustar phiphiroaraudio-1.0beta11/tools/configure-players0000755000175000017500000000062411040443421017176 0ustar phiphi#!/bin/sh GLOBAL=false HAVE_LIBAO=false PLAYERS='libao mplayer xmms gxine wine' BASEDIR=. player_libao () { : } player_mplayer () { : } player_xmms () { : } player_gxine () { : } player_wine () { if regedit wine.reg then echo -n 'OK' else echo -n 'Error' fi } cd $BASEDIR || exit 1 for player in $PLAYERS do echo -n "configuring $player... " player_$player 2> /dev/null echo done #ll roaraudio-1.0beta11/tools/create-matrix0000755000175000017500000000063311027324401016306 0ustar phiphi#!/usr/bin/perl use strict; use warnings; my $i; my $j; my $line; my $row = 'A'; my $size = int($ARGV[0]); die unless $size > 0; $line = ''; $j = 'a'; for ($i = 0; $i < $size; $i++) { $line .= sprintf('%4s ', $j++); } print $line, "\n"; for ($i = 0; $i < $size; $i++) { $line = ''; for ($j = ($size - 1); $j >= 0; $j--) { $line .= sprintf('%4i ', $i**$j); } print $line, ' ', $row++, "\n"; } #ll roaraudio-1.0beta11/tools/create-meta-types0000755000175000017500000000024511023050720017065 0ustar phiphi#!/usr/bin/perl use strict; my $offset = int(shift(@ARGV)); foreach (@ARGV) { printf("#define ROAR_META_TYPE_%-12s %i\n", uc($_), $offset); $offset++; } #ll roaraudio-1.0beta11/tools/help2man0000755000175000017500000000216411321777052015263 0ustar phiphi#!/usr/bin/perl use strict; #use Data::Dumper; my $progname; my $usage = <>; my @cat; my $cur = ['FIXME', []]; my ($opts, $desc); $usage =~ s/\r?\n//; $usage =~ s/^Usage:\s*//; ($progname) = $usage =~ /^(\S+)\s/; while (<>) { s/\r?\n//; next if $_ eq ''; if ( /^(.+):$/ ) { push(@cat, $cur); $cur = [$1, []]; } else { ($opts, $desc) = /\s+(.+?)\s+-\s+(.+)$/; push(@{$cur->[1]}, [$opts, $desc]); } } push(@cat, $cur); shift(@cat); #print Dumper($usage, $progname, \@cat); print ".\\\" $progname.1:\n\n"; print ".TH \"$progname\" \"1\" \"FIXME(DATE)\" \"RoarAudio\" \"System User's Manual: $progname\"\n\n"; print ".SH NAME\n\n"; print "$progname \\- FIXME(PROGNAME)\n\n"; print ".SH SYNOPSIS\n\n"; print $usage, "\n\n"; print ".SH DESCRIPTION\n\n"; print "FIXME(DESCRIPTION)\n\n"; foreach my $c (@cat) { print ".SH \"\U$c->[0]\"\n\n"; foreach my $o (@{$c->[1]}) { print ".TP\n"; print "\\fB$o->[0]\\fR\n"; print $o->[1], "\n\n"; } } print <<'DATA'; .SH "SEE ALSO" \fBroartips\fR(7), \fBlibroar\fR(7), \fBRoarAudio\fR(7). .SH "HISTORY" For history information see \fBRoarAudio\fR(7). .\" ll DATA #ll roaraudio-1.0beta11/tools/send-roaraudio0000755000175000017500000000364712213163404016467 0ustar phiphi#!/bin/sh REMOTEHOST='' REMOTEDIR='.' CONFIGURE=true BUILD=true TEST=true PORT='' REV='HEAD' PACKAGE='roaraudio' SSH_OPTS='' while [ "$1" != '' ] do case "$1" in '-h'|'--help') echo "Usage: $0 [OPTIONS] host..." echo cat < /dev/null | grep ^/ | head -n 1`' echo "cd $PACKAGE" $CONFIGURE && echo './configure || exit 1' $BUILD && echo '$MAKE || exit 2' $TEST && echo '$MAKE test || exit 3' echo 'exit 0' echo '#ll' } > $LOCALDIR/setup chmod +rx $LOCALDIR/setup tar -czf - $LOCALDIR | ssh $SSH_OPTS "cd $REMOTEDIR && rm -rf $LOCALDIR/$PACKAGE && gunzip | tar -xvf - && cd $LOCALDIR && ./setup" rm -rf $LOCALDIR #ll roaraudio-1.0beta11/tools/wine.reg0000644000175000017500000000020311040443421015244 0ustar phiphiREGEDIT4 [HKEY_CURRENT_USER\Software\Wine\Drivers] "Audio"="esd" [HKEY_USERS\S-1-5-4\Software\Wine\Drivers] "Audio"="esd"