pax_global_header 0000666 0000000 0000000 00000000064 12650750046 0014517 g ustar 00root root 0000000 0000000 52 comment=5567ea1735b5024ef615df04b23f21e4a38a74ee
mediasettings-v0.1.1-5567ea1735b5024ef615df04b23f21e4a38a74ee/ 0000775 0000000 0000000 00000000000 12650750046 0022113 5 ustar 00root root 0000000 0000000 mediasettings-v0.1.1-5567ea1735b5024ef615df04b23f21e4a38a74ee/LICENSE.txt 0000664 0000000 0000000 00000001333 12650750046 0023736 0 ustar 00root root 0000000 0000000 audiosettings - get/set audio settings within Pd
Copyright © 2010-2012 IOhannes m zmoelnig (zmoelnig AT iem DOT at)
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 .
mediasettings-v0.1.1-5567ea1735b5024ef615df04b23f21e4a38a74ee/Makefile 0000664 0000000 0000000 00000002070 12650750046 0023552 0 ustar 00root root 0000000 0000000 #!/usr/bin/make -f
# Makefile for pure data externals in lib creb.
# Needs Makefile.pdlibbuilder to work (https://github.com/pure-data/pd-lib-builder)
lib.name = mediasettings
# special file that does not provide a class
lib.setup.sources =
# all other C and C++ files in subdirs are source files per class
# (alternatively, enumerate them by hand)
class.sources = audiosettings.c midisettings.c
datafiles = \
audiosettings-help.pd midisettings-help.pd \
LICENSE.txt \
README.txt \
mediasettings-meta.pd
cflags = -DVERSION='"$(lib.version)"'
################################################################################
### pdlibbuilder ###############################################################
################################################################################
# This Makefile is based on the Makefile from pd-lib-builder written by
# Katja Vetter. You can get it from:
# https://github.com/pure-data/pd-lib-builder
PDLIBBUILDER_DIR=pd-lib-builder/
include $(firstword $(wildcard $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder Makefile.pdlibbuilder))
mediasettings-v0.1.1-5567ea1735b5024ef615df04b23f21e4a38a74ee/Makefile.pdlibbuilder 0000664 0000000 0000000 00000113541 12650750046 0026220 0 ustar 00root root 0000000 0000000 # Makefile.pdlibbuilder version 0.0.1, dated 2015-10-31
#
# Helper makefile for Pure Data external libraries.
# Written by Katja Vetter March-June 2015 for the public domain. No warranties.
# Inspired by Hans Christoph Steiner's Makefile Template and Stephan Beal's
# ShakeNMake.
#
# GNU make version >= 3.81 required.
#
#
#=== characteristics ===========================================================
#
#
# - defines build settings based on autodetected OS and architecture
# - defines rules to build Pd class- or lib executables from C or C++ sources
# - defines rules for libdir installation
# - defines convenience targets for developer and user
# - evaluates implicit dependencies for non-clean builds
#
#
#=== basic usage ===============================================================
#
#
# In your Makefile, define your Pd lib name and class files, and include
# Makefile.pdlibbuilder at the end of the Makefile. Like so:
#
# ________________________________________________________________________
#
# # Makefile for mylib
#
# lib.name = mylib
#
# class.sources = myclass1.c myclass2.c
#
# datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt
#
# include Makefile.pdlibbuilder
# ________________________________________________________________________
#
#
# For files in class.sources it is assumed that class basename == source file
# basename. The default target builds all classes as individual executables
# with Pd's default extension for the platform. For anything more than the
# most basic usage, continue reading.
#
#
#=== list of Makefile.pdlibbuilder API variables ===============================
#
#
# Variables available for definition in your library Makefile:
#
# - lib.name
# - lib.setup.sources
# - class.sources
# - common.sources
# - shared.sources
# - .class.sources
# - .class.ldflags
# - .class.ldlibs
# - cflags
# - ldflags
# - ldlibs
# - datafiles
# - datadirs
# - makefiles
# - makefiledirs
# - externalsdir
#
# Variables avaialable for (re)definition via command arguments:
#
# - pdbinpath (Windows only)
# - pdincludepath
# - DESTDIR
# - prefix
# - libdir
# - pkglibdir
# - CFLAGS
# - CC
# - CXX
# - INSTALL
# - INSTALL_PROGRAM
# - INSTALL_DATA
# - INSTALL_DIR
#
# Variables available for your makefile or as command argument:
#
# - objectsdir
# - make-lib-executable
# - suppress-wunused
#
#
#=== descriptions of Makefile.pdlibbuilder API variables =======================
#
#
# lib.name:
# Name of the library directory as it will be installed / distributed. Also the
# name of the lib executable in the case where all classes are linked into
# a single binary.
#
# lib.setup.sources:
# Source file(s) (C or C++) which must be compiled only when linking all classes
# into a single lib binary.
#
# class.sources:
# All sources files (C or C++) for which the condition holds that
# class name == source file basename.
#
# .class.sources:
# Source file(s) (C or C++) specific to class . Use this for
# multiple-source classes or when class name != source file basename.
#
# common.sources:
# Source file(s) which must be statically linked to each class in the library.
#
# shared.sources:
# Source file(s) (C or C++) to build a shared dynamic link lib, to be linked
# with all class executables.
#
# cflags, ldflags, ldlibs:
# Define cflags (preprocessor&compiler), ldflags (linker) and ldlibs (dynamic
# link libs) for the whole library. These flags are added to platform-specific
# flags defined by Makefile.pdlibbuilder.
#
# .class.ldflags and .class.ldlibs:
# Define ldflags resp. ldlibs specific to class . These flags are
# added to platform-specific flags defined by Makefile.pdlibbuilder, and flags
# defined in your Makefile for the whole library. Note: cflags can not be
# defined per class in the current implementation.
#
# datafiles and datadirs:
# All extra files you want to include in binary distributions of the
# library: abstractions and help patches, example patches, meta patch, readme
# and license texts, manuals, sound files, etcetera. Use 'datafiles' for all
# files that should go into your lib rootdir and 'datadirs' for complete
# directories you want to copy from source to distribution.
#
# externalsdir:
# Relative path to directory 'externals' in the context of pd-extended SVN, or
# any other centralized build layout for multiple libraries. Default value
# is '..', meaning the direct parent. The value is used in search paths for
# pd core components (header files, and executable in the case of Windows).
#
# makefiles and makefiledirs:
# Extra makefiles or directories with makefiles that should be made in sub-make
# processes.
#
# pdbinpath:
# For Windows only. Directory where pd.dll can be found for linking.
#
# pdincludepath:
# Directory where Pd API m_pd.h can be found, and other Pd header files.
#
# DESTDIR, prefix, libdir:
# Components of the path for installation as conventionally used on Linux.
#
# pkglibdir:
# Base path for installation of Pd library directories. Default is specified
# per OS, see section about paths below.
#
# objectsdir:
# Alias of pkglibdir. Can be defined in your makefile to enable project-
# dependent relative install locations.
#
# CFLAGS:
# Compiler (notably optimization) flags which are defined by
# Makefile.pdlibbuilder, but may be overriden via command argument.
#
# CC and CXX:
# C and C++ compiler programs as defined in your build environment.
#
# INSTALL, INSTALL_PROGRAM, INSTALL_DATA, INSTALL_DIR:
# Definitions of install program, may be overriden via command argument.
#
# make-lib-executable:
# When this variable is defined 'yes' in your makefile or as command argument,
# Makefile.pdlibbuilder will try to build all classes into a single library
# executable (but it will force exit if lib.setup.sources is undefined).
# If your makefile defines 'make-lib-executable=yes' as the library default,
# this can still be overriden with 'make-lib-executable=no' as command argument
# to build individual class executables (the Makefile.pdlibbuilder default.)
#
# suppress-wunused:
# When this variable is defined ('yes' or any other value), -Wunused-variable,
# -Wunused-parameter, -Wunused-value and -Wunused-function are suppressed,
# but the other warnings from -Wall are retained.
#
#
#=== paths =====================================================================
#
#
# Source files in directories other than current working directory must be
# prefixed with their relative path. Do not rely on VPATH or vpath.
# Object (.o) files are built in the directory of their source files.
# Executables are built in current working directory.
#
# Variable 'pdincludepath' stores the location where m_pd.h was found.
# Locations where Makefile.pdlibbuilder tries to find it, in order of priority:
#
# any OS: $(externalsdir)../pd/src/
#
# Linux: /usr/include/pdextended/
# /usr/include/pd/
#
# OSX: /Applications/Pd-extended.app/Contents/Resources/include/pdextended/
# /Applications/Pd.app/Contents/Resources/src/
#
# Windows: %PROGRAMFILES%/pd/include/pdextended/
# %PROGRAMFILES%/pd/src/
#
# The path for installation of all library components is constructed as:
#
# installpath := $(DESTDIR)$(objectsdir)/$(lib.name)
#
# Default for 'objectsdir' is defined per platform and follows this convention:
# https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files
#
# Linux: /usr/local/lib/pd-externals
# OSX: ~/Library/Pd
# Windows: %APPDATA%/Pd
#
# The rationale for not installing to ~/pd-externals by default on Linux
# is that some people share the home dir between 32 and 64 bit installations.
#
#
#=== targets ===================================================================
#
#
# all: build classes (default) or library blob (if make-lib-executable=true)
# alldebug: build all with -g option turned on for debug symbols
# : force clean build of an individual class
# .pre: make preprocessor output file in current working directory
# .lst: make asm/source output file in current working directory
#
# install: install executables and data files
# clean: remove build products from source tree
#
# help: print help text
# vars: print makefile variables
# allvars: print all variables
# depend: print generated prerequisites
# coffee: dummy target
#
#
#=== Pd-extended libdir concept ================================================
#
#
# For libdir layout as conceived by Hans-Christoph Steiner, see:
#
# https://puredata.info/docs/developer/Libdir
#
# Files README.txt, LICENSE.txt and -meta.pd are part of the libdir
# convention. Help patches for each class and abstraction are supposed to be
# available. Makefile.pdlibbuilder does not force the presence of these files
# however. It does not automatically include such files in libdir installations.
# Data files you want to include in distributions must be defined explicitly in
# your Makefile.
#
#
#=== Makefile.pdlibbuilder syntax conventions ==================================
#
#
# Makefile.pdlibbuilder variable names are lower case. Default make variables,
# environment variables, and standard user variables (CC, CXX, CFLAGS, DESTDIR)
# are upper case. Use target 'allvars' to print all variables and their values.
#
# 'Fields' in data variables are separated by dots, like in 'foo.class.sources'.
# Words in variables expressing a function or command are separated by dashes,
# like in 'make-lib-executable'.
#
#
#=== useful make options =======================================================
#
#
# Use 'make -d ' to print debug details of the make process.
# Use 'make -p ' to print make's database.
#
#
#=== TODO ======================================================================
#
#
# - decide whether to use -static-libgcc or shared dll in MinGW
# - cygwin support
# - android support
# - Windows 64 bit support
# - figure out how to handle '$' in filenames
# - add makefile template targets dpkg-source dist libdir distclean tags?
#
#
#=== end of documentation sections =============================================
#
#
################################################################################
################################################################################
################################################################################
# GNU make version 3.81 (2006) or higher is required because of the following:
# - function 'info'
# - variable '.DEFAULT_GOAL'
# force exit when make version is < 3.81
ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))), 3.81)
$(error GNU make version 3.81 or higher is required)
endif
# Relative path to externals root dir in multi-lib source tree like
# pd-extended SVN. Default is parent of current working directory. May be
# defined differently in including makefile. This variable is used to probe for
# paths.
externalsdir ?= ..
# variable you can use to check if Makefile.pdlibbuilder is already included
Makefile.pdlibbuilder = true
################################################################################
### variables: library name and version ########################################
################################################################################
# strip possibles spaces from lib.name, they mess up calculated file names
lib.name := $(strip $(lib.name))
# if meta file exists, check library version
metafile := $(wildcard $(lib.name)-meta.pd)
ifdef metafile
lib.version := $(shell sed -n \
's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' \
$(metafile))
endif
################################################################################
### variables: files ###########################################################
################################################################################
#=== sources ===================================================================
# (re)define .class.sources using file names in class.sources
define add-class-source
$(notdir $(basename $v)).class.sources += $v
endef
$(foreach v, $(class.sources), $(eval $(add-class-source)))
# derive class names from .class.sources variables
sourcevariables := $(filter %.class.sources, $(.VARIABLES))
classes := $(basename $(basename $(sourcevariables)))
# accumulate all source files specified in makefile
classes.sources := $(sort $(foreach v, $(sourcevariables), $($v)))
all.sources := $(classes.sources) $(lib.setup.sources) \
$(shared.sources) $(common.sources)
#=== object files ==============================================================
# construct object filenames from all C and C++ source file names
classes.objects := $(addsuffix .o, $(basename $(classes.sources)))
common.objects := $(addsuffix .o, $(basename $(common.sources)))
shared.objects := $(addsuffix .o, $(basename $(shared.sources)))
lib.setup.objects := $(addsuffix .o, $(basename $(lib.setup.sources)))
all.objects = $(classes.objects) $(common.objects) $(shared.objects) \
$(lib.setup.objects)
#=== executables ===============================================================
# use recursive variables here because executable extension is not yet known
# construct class executable names from class names
classes.executables = $(addsuffix .$(extension), $(classes))
# construct shared lib executable name if shared sources are defined
ifdef shared.sources
shared.lib = lib$(lib.name).$(shared.extension)
else
shared.lib =
endif
################################################################################
### variables per platform #####################################################
################################################################################
#=== flags per architecture ====================================================
# Set architecture-dependent cflags, mainly for Linux. For Mac and Windows,
# arch.c.flags are overriden below.
machine := $(shell uname -m)
# Raspberry Pi 1st generation
ifeq ($(machine), armv6l)
arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard
endif
# Beagle, Udoo, RPi2 etc.
ifeq ($(machine), armv7l)
arch.c.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard
endif
# Intel 32 bit, build with SSE and SSE2 instructions
ifeq ($(findstring $(machine), i386 i686), $(machine))
arch.c.flags = -march=pentium4 -mfpmath=sse -msse -msse2
endif
# Intel/AMD 64 bit, build with SSE, SSE2 and SSE3 instructions
ifeq ($(findstring $(machine), ia64 x86_64), $(machine))
arch.c.flags = -march=core2 -mfpmath=sse -msse -msse2 -msse3
endif
#=== operating system ==========================================================
# The following systems are defined: Linux, Darwin, Windows. GNU and
# GNU/kFreeBSD are treated as Linux to get the same options.
uname := $(shell uname)
ifeq ($(findstring $(uname), Linux GNU GNU/kFreeBSD), $(uname))
system = Linux
endif
ifeq ($(uname), Darwin)
system = Darwin
endif
ifeq ($(findstring MINGW, $(uname)), MINGW)
system = Windows
endif
# TODO: Cygwin, Android
#=== flags and paths for Linux =================================================
ifeq ($(system), Linux)
prefix = /usr/local
libdir := $(prefix)/lib
pkglibdir = $(libdir)/pd-externals
pdincludepath := $(firstword $(dir $(wildcard \
$(externalsdir)/../pd/src/m_pd.h \
/usr/include/pdextended/m_pd.h \
/usr/include/pd/m_pd.h)))
extension = pd_linux
cpp.flags := -DUNIX
c.flags := -fpic
c.ldflags := -rdynamic -shared -fpic -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
c.ldlibs := -lc -lm
cxx.flags := -fpic -fcheck-new
cxx.ldflags := -rdynamic -shared -fpic -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
cxx.ldlibs := -lc -lm -lstdc++
shared.extension = so
shared.ldflags := -rdynamic -fpic -shared -Wl,-soname,$(shared.lib)
stripflags = --strip-unneeded -R .note -R .comment
endif
#=== flags and paths for Darwin ================================================
# On OSX we try to build fat binaries by default. It is assumed that OSX i386
# can build for ppc and OSX x86_64 can't. TODO: try to refine this condition.
# LLVM-clang doesn't support -fcheck-new, therefore this flag is omitted for
# OSX x86_64.
ifeq ($(system), Darwin)
pkglibdir = $(HOME)/Library/Pd
pdincludepath := $(firstword $(dir $(wildcard \
$(externalsdir)/../pd/src/m_pd.h \
/Applications/Pd-extended.app/Contents/Resources/include/pdextended/m_pd.h \
/Applications/Pd.app/Contents/Resources/src/m_pd.h)))
extension = pd_darwin
cpp.flags := -DUNIX -DMACOSX -I /sw/include
c.flags :=
c.ldflags := -undefined suppress -flat_namespace -bundle
c.ldlibs := -lc
cxx.ldflags := -undefined suppress -flat_namespace -bundle
cxx.ldlibs := -lc
shared.extension = dylib
shared.ldflags = -dynamiclib -undefined dynamic_lookup \
-install_name @loader_path/$(shared.lib) \
-compatibility_version 1 -current_version 1.0
stripflags = -x
ifeq ($(machine), i386)
cxx.flags := -fcheck-new
arch.c.flags := -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
arch.ld.flags := -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
endif
ifeq ($(machine), x86_64)
arch.c.flags := -arch i386 -arch x86_64 -mmacosx-version-min=10.5
arch.ld.flags := -arch i386 -arch x86_64 -mmacosx-version-min=10.5
endif
endif
#=== flags and paths for Windows ===============================================
# Standard paths on Windows contain spaces, and GNU make functions treat such
# paths as lists, with unintended effects. Therefore we must use shell function
# ls instead of make's wildcard, and probe for each standard path individually.
# Using double quotes around paths with spaces is obligatory. Since some path
# variables are assembled or re-expanded later, great care must be taken to put
# quotes at appropriate points throughout the makefile. Thanks, Bill.
# paths for 32-bit executables on 64-bit Windows aren't yet defined here (TODO)
ifeq ($(system), Windows)
pkglibdir := $(APPDATA)/Pd
pdbinpath := $(wildcard $(externalsdir)/../pd/bin/)
pdincludepath := $(wildcard $(externalsdir)/../pd/src/)
ifndef pdbinpath
pdbinpath := $(shell ls -d "$(PROGRAMFILES)/pd/bin/")
endif
ifndef pdincludepath
pdincludepath := $(shell ls -d "$(PROGRAMFILES)/pd/include/pdextended/")
endif
ifndef pdincludepath
pdincludepath := $(shell ls -d "$(PROGRAMFILES)/pd/src/")
endif
endif
# On Windows we build 32 bit by default to match Pd(-extended) binary
# distributions. This may change in the future.
# TODO: decide whether -mms-bitfields should be specified.
ifeq ($(system), Windows)
extension = dll
CC = gcc
CXX = g++
arch.c.flags := -march=pentium4 -msse -msse2 -mfpmath=sse
cpp.flags := -DMSW -DNT
c.flags :=
c.ldflags := -static-libgcc -shared \
-Wl,--enable-auto-import "$(pdbinpath)pd.dll"
c.ldlibs :=
cxx.flags := -fcheck-new
cxx.ldflags := -static-libstdc++ -shared \
-Wl,--enable-auto-import "$(pdbinpath)pd.dll"
cxx.ldlibs :=
shared.extension = dll
shared.ldflags := -static-libgcc -shared "$(pdbinpath)pd.dll"
stripflags = --strip-unneeded -R .note -R .comment
endif
#=== paths =====================================================================
# Default pkglibdir is specified above per operating system. It is aliased as
# 'objectsdir' to retain compatibility with pd-extended template. Assignment
# operator '?=' is used to enable a project-relative path definition in the
# including makefile.
objectsdir ?= $(pkglibdir)
# base path where all components of the lib will be installed by default
installpath := $(DESTDIR)$(objectsdir)/$(lib.name)
# check if pdincludepath contains spaces (as is often the case on Windows)
# if so, store the path so we can later do checks with it
pdincludepathwithspaces := $(if $(word 2, $(pdincludepath)), $(pdincludepath))
#=== accumulated build flags ===================================================
# From GNU make docs: 'Users expect to be able to specify CFLAGS freely
# themselves.' So we use CFLAGS to define options which are not strictly
# required for compilation: optimizations, architecture specifications, and
# warnings. CFLAGS can be safely overriden using a make command argument.
# Variables cflags, ldflags and ldlibs may be defined in including makefile.
optimization.flags = -O3 -ffast-math -funroll-loops -fomit-frame-pointer
warn.flags = -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing
# suppress -Wunused-variable & Co if you don't want to clutter a build log
ifdef suppress-wunused
warn.flags += $(addprefix -Wno-unused-, function parameter value variable)
endif
CFLAGS = $(warn.flags) $(optimization.flags) $(arch.c.flags)
# preprocessor flags
cpp.flags += -DPD -I "$(pdincludepath)" $(CPPFLAGS)
# architecture specifications for linker are overridable by LDFLAGS
LDFLAGS := $(arch.ld.flags)
# now add the same ld flags to shared dynamic lib
shared.ldflags := $(shared.ldflags) $(LDFLAGS)
# accumulated flags for C compiler / linker
c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS)
c.ldflags := $(c.ldflags) $(ldflags) $(LDFLAGS)
c.ldlibs := $(c.ldlibs) $(ldlibs)
# accumulated flags for C++ compiler / linker
cxx.flags := $(cpp.flags) $(cxx.flags) $(cflags) $(CFLAGS)
cxx.ldflags := $(cxx.ldflags) $(ldflags) $(LDFLAGS)
cxx.ldlibs := $(cxx.ldlibs) $(ldlibs)
################################################################################
### variables: tools ###########################################################
################################################################################
# aliases so we can later define 'compile-$1' and set 'c' or 'cxx' as argument
compile-c := $(CC)
compile-cxx := $(CXX)
################################################################################
### checks #####################################################################
################################################################################
# At this point most variables are defined. Now do some checks and info's
# before rules begin.
# 'forward declaration' of default target, needed to do checks
all:
# To avoid unpredictable results, make sure the default target is not redefined
# by including makefile.
ifneq ($(.DEFAULT_GOAL), all)
$(error Default target must be 'all'.)
endif
# find out which target(s) will be made
ifdef MAKECMDGOALS
goals := $(MAKECMDGOALS)
else
goals := all
endif
# check if m_pd.h is found and print info about it
$(if $(shell ls "$(pdincludepath)m_pd.h"), \
$(info ++++ info: using Pd API $(pdincludepath)m_pd.h), \
$(warning Where is your m_pd.h? Do 'make help' for info.))
# print target info
$(info ++++ info: making target $(goals) $(if $(lib.name),in lib $(lib.name)))
# when installing, print installpath info
$(if $(filter install install-lib, $(goals)), $(info ++++ info: \
installpath is '$(installpath)'))
#=== define executables ========================================================
# By default we build class executables, and optionally a shared dynamic link
# lib. When make-lib-executable=yes we build all classes into a single lib
# executable, on the condition that variable lib.setup.sources is defined.
ifeq ($(make-lib-executable),yes)
$(if $(lib.setup.sources), ,\
$(error Can not build library blob because lib.setup.sources is undefined))
executables := $(lib.name).$(extension)
else
executables := $(classes.executables) $(shared.lib)
endif
################################################################################
### rules: special targets #####################################################
################################################################################
# Disable built-in rules. If some target can't be built with the specified
# rules, it should not be built at all.
MAKEFLAGS += --no-builtin-rules
.PRECIOUS:
.SUFFIXES:
.PHONY: all build-classes build-lib $(classes) $(makefiledirs) $(makefiles)\
install install-executables install-datafiles install-datadirs \
force clean vars allvars depend help
################################################################################
### rules: build targets #######################################################
################################################################################
# target all builds class executables plus optional shared lib
# or alternatively a single lib executable when make-lib-executable=true
all: $(executables)
$(info ++++ info: $(if $(executables),executables in $(lib.name) completed))
# build all with -g option turned on for debug symbols
alldebug: c.flags += -g
alldebug: cxx.flags += -g
alldebug: all
#=== class executable ==========================================================
# recipe for linking objects in class executable
# argument $1 = compiler type (c or cxx)
# argument $2 = class basename
define link-class
$(compile-$1) \
$($1.ldflags) $($2.class.ldflags) \
-o $2.$(extension) \
$(addsuffix .o, $(basename $($2.class.sources))) \
$(addsuffix .o, $(basename $(common.sources))) \
$($1.ldlibs) $($2.class.ldlibs) $(shared.lib)
endef
# general rule for linking object files in class executable
%.$(extension): $(shared.lib)
$(info ++++ info: linking objects in $@ for lib $(lib.name))
$(if $(filter %.cc %.cpp, $($*.class.sources)), \
$(call link-class,cxx,$*), \
$(call link-class,c,$*))
#=== library blob ==============================================================
# build all classes into single executable
build-lib: $(lib.name).$(extension)
$(info ++++ info: library blob $(lib.name).$(extension) completed)
# recipe for linking objects in lib executable
# argument $1 = compiler type (c or cxx)
define link-lib
$(compile-$1) \
$($1.ldflags) $(lib.ldflags) \
-o $(lib.name).$(extension) $(all.objects) \
$($1.ldlibs) $(lib.ldlibs)
endef
# rule for linking objects in lib executable
# declared conditionally to avoid name clashes
ifeq ($(make-lib-executable),yes)
$(lib.name).$(extension): $(all.objects)
$(if $(filter %.cc %.cpp, $(all.sources)), \
$(call link-lib,cxx), \
$(call link-lib,c))
endif
#=== shared dynamic lib ========================================================
# recipe for linking objects in shared executable
# argument $1 = compiler type (c or cxx)
define link-shared
$(compile-$1) \
$(shared.ldflags) \
-o lib$(lib.name).$(shared.extension) $(shared.objects) \
$($1.ldlibs) $(shared.ldlibs)
endef
# rule for linking objects in shared executable
# build recipe is in macro 'link-shared'
lib$(lib.name).$(shared.extension): $(shared.objects)
$(info ++++ info: linking objects in shared lib $@)
$(if $(filter %.cc %.cpp, $(shared.sources)), \
$(call link-shared,cxx), \
$(call link-shared,c))
#=== object files ==============================================================
# recipe to make .o file from source
# argument $1 is compiler type (c or cxx)
define make-object-file
$(info ++++ info: making $@ in lib $(lib.name))
$(compile-$1) \
$($1.flags) \
-o $@ -c $<
endef
# Three rules to create .o files. These are double colon 'terminal' rules,
# meaning they are the last in a rules chain.
%.o:: %.c
$(call make-object-file,c)
%.o:: %.cc
$(call make-object-file,cxx)
%.o:: %.cpp
$(call make-object-file,cxx)
#=== explicit prerequisites for class executables ==============================
# For class executables, prerequisite rules are declared in run time. Target
# 'depend' prints these rules for debugging purposes.
# declare explicit prerequisites rule like 'class: class.extension'
# argument $v is class basename
define declare-class-target
$v: $v.$(extension)
endef
# declare explicit prerequisites rule like 'class.extension: object1.o object2.o'
# argument $v is class basename
define declare-class-executable-target
$v.$(extension): $(addsuffix .o, $(basename $($v.class.sources))) \
$(addsuffix .o, $(basename $(common.sources)))
endef
# evaluate explicit prerequisite rules for all classes
$(foreach v, $(classes), $(eval $(declare-class-target)))
$(foreach v, $(classes), $(eval $(declare-class-executable-target)))
#=== implicit prerequisites for class executables ==============================
# Evaluating implicit prerequisites (header files) with help from the
# preprocessor is 'expensive' so this is done conditionally and selectively.
# Note that it is also possible to trigger a build via install targets, in
# which case implicit prerequisites are not checked.
# When the Pd include path contains spaces it will mess up the implicit
# prerequisites rules so we do not evaluate them in that case.
ifndef pdincludepathwithspaces
must-build-everything := $(filter all default lib, $(goals))
must-build-class := $(filter $(classes), $(goals))
must-build-sources := $(foreach v, $(must-build-class), $($v.class.sources))
endif
# declare implicit prerequisites rule like 'object.o: header1.h header2.h ...'
# argument $1 is input source file(s)
define declare-object-target
$(filter %.o: %.h, $(shell $(CPP) $(c.flags) -MM $1)) $(MAKEFILE_LIST)
endef
# evaluate implicit prerequisite rules when rebuilding everything
ifdef must-build-everything
$(if $(wildcard $(all.objects)), \
$(info ++++ info: evaluating implicit prerequisites in lib $(lib.name).....) \
$(foreach v, $(all.sources), $(eval $(call declare-object-target, $v))))
endif
# evaluate implicit prerequisite rules when selectively building classes
ifdef must-build-class
$(foreach v, $(must-build-sources), \
$(eval $(call declare-object-target, $v)))
$(foreach v, $(shared.sources), \
$(eval $(call declare-object-target, $v)))
endif
################################################################################
### rules: preprocessor and assembly files #####################################
################################################################################
# Preprocessor and assembly output files for bug tracing etc. They are not part
# of the build processes for executables. By default these files are created in
# the current working directory. Dependency tracking is not performed, the build
# is forced instead to make sure it's up to date.
force:
#=== preprocessor file =========================================================
# make preprocessor output file with extension .pre
# argument $1 = compiler type (c or cxx)
define make-preprocessor-file
$(info ++++ info: making preprocessor output file $(notdir $*.pre) \
in current working directory)
$(compile-$1) -E $< $(c.flags) $($1.flags) -o $(notdir $*.pre)
endef
%.pre:: %.c force
$(call make-preprocessor-file,c)
%.pre:: %.cc force
$(call make-preprocessor-file,cxx)
%.pre:: %.cpp force
$(call make-preprocessor-file,cxx)
#=== assembly file =============================================================
# make C / assembly interleaved output file with extension .lst
# argument $1 = compiler type (c or cxx)
define make-assembly-file
$(info ++++ info: making assembly output file $(notdir $*.lst) \
in current working directory)
$(compile-$1) \
-c -Wa,-a,-ad -fverbose-asm \
$($1.flags) \
$< > $(notdir $*.lst)
endef
%.lst:: %.c force
$(call make-assembly-file,c)
%.lst:: %.cc force
$(call make-assembly-file,cxx)
%.lst:: %.cpp force
$(call make-assembly-file,cxx)
################################################################################
### rules: installation targets ################################################
################################################################################
# Install targets depend on successful exit status of target all because nothing
# must be installed in case of a build error.
# -p = preserve time stamps
# -m = set permission mode (as in chmod)
# -d = create all components of specified directories
INSTALL = install
INSTALL_PROGRAM := $(INSTALL) -p -m 644
INSTALL_DATA := $(INSTALL) -p -m 644
INSTALL_DIR := $(INSTALL) -m 755 -d
# strip spaces from file names
executables := $(strip $(executables))
datafiles := $(strip $(datafiles))
datadirs := $(strip $(datadirs))
# Do not make any install sub-target with empty variable definition because the
# install program would exit with an error.
install: $(if $(executables), install-executables)
install: $(if $(datafiles), install-datafiles)
install: $(if $(datadirs), install-datadirs)
install-executables: all
$(INSTALL_DIR) -v "$(installpath)"
$(INSTALL_PROGRAM) $(executables) "$(installpath)"
$(info ++++ info: executables of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
install-datafiles: all
$(INSTALL_DIR) -v "$(installpath)"
$(INSTALL_DATA) $(datafiles) "$(installpath)"
$(info ++++ info: data files of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
install-datadirs: all
$(foreach v, $(datadirs), $(INSTALL_DIR) "$(installpath)/$v";)
$(foreach v, $(datadirs), \
$(INSTALL_DATA) $(wildcard $v/*) "$(installpath)/$v";)
$(info ++++ info: data directories of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
################################################################################
### rules: distribution targets ################################################
################################################################################
# TODO
# These targets are implemented in Makefile Template, but I have to figure out
# how to do it under the not-so-strict conditions of Makefile.pdlibbuilder.
# make source package
dist:
@echo "target dist not yet implemented"
# make Debian source package
dpkg-source:
@echo "target dpkg-source not yet implemented"
$(ORIGDIR):
$(DISTDIR):
################################################################################
### rules: clean targets #######################################################
################################################################################
# delete build products from build tree
clean:
rm -f $(all.objects)
rm -f $(classes.executables) $(lib.name).$(extension) $(shared.lib)
rm -f *.pre *.lst
# remove distribution directories and tarballs from build tree
distclean: clean
@echo "target distclean not yet implemented"
################################################################################
### rules: submake targets #####################################################
################################################################################
# Iterate over sub-makefiles or makefiles in other directories.
# When 'continue-make=yes' is set, sub-makes will report 'true' to the parent
# process regardless of their real exit status. This prevents the parent make
# from being aborted by a sub-make error. Useful when you want to quickly find
# out which sub-makes from a large set will succeed.
ifeq ($(continue-make),yes)
continue = || true
endif
# These targets will trigger sub-make processes for entries in 'makefiledirs'
# and 'makefiles'.
all alldebug install clean distclean dist dkpg-source: \
$(makefiledirs) $(makefiles)
# this expands to identical rules for each entry in 'makefiledirs'
$(makefiledirs):
$(MAKE) --directory=$@ $(MAKECMDGOALS) $(continue)
# this expands to identical rules for each entry in 'makefiles'
$(makefiles):
$(MAKE) --directory=$(dir $@) --makefile=$(notdir $@) $(MAKECMDGOALS) $(continue)
################################################################################
### rules: convenience targets #################################################
################################################################################
#=== show variables ============================================================
# Several 'function' macro's cause errors when expanded within a rule or without
# proper arguments. Variables which are set with the define directive are only
# shown by name for that reason.
functions = \
add-class-source \
declare-class-target \
declare-class-executable-target \
declare-object-target \
link-class \
link-lib \
link-shared \
make-object-file \
make-preprocessor-file \
make-assembly-file
# show variables from makefiles
vars:
$(info ++++ info: showing makefile variables:)
$(foreach v,\
$(sort $(filter-out $(functions) functions, $(.VARIABLES))),\
$(if $(filter file, $(origin $v)),\
$(info variable $v = $($v))))
$(foreach v, $(functions), $(info 'function' name: $v))
@echo
# show all variables
allvars:
$(info ++++ info: showing default, automatic and makefile variables:)
$(foreach v, \
$(sort $(filter-out $(functions) functions, $(.VARIABLES))), \
$(info variable ($(origin $v)) $v = $($v)))
$(foreach v, $(functions), $(info 'function' name: $v))
@echo
#=== show dependencies =========================================================
# show generated prerequisites rules
depend:
$(info ++++ info: generated prerequisite rules)
$(foreach v, $(classes), $(info $(declare-class-target)))
$(foreach v, $(classes), $(info $(declare-class-executable-target)))
$(foreach v, $(all.sources), $(info $(call declare-object-target, $v)))
@echo
#=== show help text ============================================================
# brief info about targets and paths
mpdh := $(shell ls "$(pdincludepath)m_pd.h")
mpdh := $(if $(mpdh), $(mpdh), m_pd.h not found. Is Pd(-extended) installed?)
help:
@echo
@echo " Main targets:"
@echo " all: build executables (default target)"
@echo " install: install all components of the library"
@echo " vars: print makefile variables for troubleshooting"
@echo " allvars: print all variables for troubleshooting"
@echo " help: print this help text"
@echo
@echo " Pd API m_pd.h:"
@echo " $(shell ls "$(pdincludepath)m_pd.h")"
@echo " You may specify your preferred include path as argument to"
@echo " the make command, like 'pdincludepath=path/to/pd/src'."
@echo
@echo " Path for installation of your libdir(s):"
@echo " $(objectsdir)"
@echo " Alternatively you may specify your path for installation as argument"
@echo " to the make command, like 'objectsdir=path/to/pd-externals'."
@echo " For detailed info read the doc sections in Makefile.pdlibbuilder."
@echo
#=== dummy target ==============================================================
coffee:
@echo "Makefile.pdlibbuilder: Can not make coffee. Sorry."
################################################################################
### end of rules sections ######################################################
################################################################################
# for syntax highlighting in vim and github
# vim: set filetype=make:
mediasettings-v0.1.1-5567ea1735b5024ef615df04b23f21e4a38a74ee/README.txt 0000664 0000000 0000000 00000000303 12650750046 0023605 0 ustar 00root root 0000000 0000000
mediasettings - get/set audio and MIDI settings within Pd
NOTE: this library has been developed for the IntegraLive
project http://integralive.org
IOhannes m zmoelnig (zmoelnig AT iem DOT at)
mediasettings-v0.1.1-5567ea1735b5024ef615df04b23f21e4a38a74ee/audiosettings-help.pd 0000664 0000000 0000000 00000002120 12650750046 0026243 0 ustar 00root root 0000000 0000000 #N canvas 172 173 473 417 10;
#X obj 48 261 audiosettings;
#X text 28 20 audiosettings - query and manipulate audio-settings;
#X msg 98 58 listdrivers;
#X msg 100 87 listdevices;
#X msg 105 117 listparams;
#X text 179 56 get available audio drivers;
#X text 181 86 get available devices for current driver;
#X text 183 119 get available parameters for current driver/device
;
#X obj 48 283 print info;
#N canvas 6 50 809 300 set 0;
#X msg 123 54 driver ALSA;
#X obj 61 259 outlet;
#X text 207 55 set driver to "ALSA" (if possible);
#X msg 130 119 params @samplerate 48000;
#X text 288 118 set samplerate to 48kHz;
#X text 432 165 choose (input-device #1) AND (output-device #2) AND
(samplerate=48kHz);
#X msg 135 168 params @input 0 2 @output 0 2 @samplerate 48000;
#X connect 0 0 1 0;
#X connect 3 0 1 0;
#X connect 6 0 1 0;
#X restore 114 181 pd set;
#X msg 140 227 getdriver;
#X msg 175 266 bang;
#X msg 239 230 params @samplerate 48000;
#X connect 0 0 8 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 9 0 0 0;
#X connect 10 0 0 0;
#X connect 11 0 0 0;
#X connect 12 0 0 0;
mediasettings-v0.1.1-5567ea1735b5024ef615df04b23f21e4a38a74ee/audiosettings.c 0000664 0000000 0000000 00000045006 12650750046 0025146 0 ustar 00root root 0000000 0000000 /******************************************************
*
* audiosettings - get/set audio preferences from within Pd-patches
* Copyright (C) 2010-2012 IOhannes m zmölnig
*
* forum::für::umläute
*
* institute of electronic music and acoustics (iem)
* university of music and dramatic arts, graz (kug)
*
*
******************************************************
*
* license: GNU General Public License v.3 or later
*
******************************************************/
#include "mediasettings.h"
#if (!defined AUDIOSETTINGS_VERSION) && (defined VERSION)
# define AUDIOSETTINGS_VERSION VERSION
#endif
#define MAXAUDIOINDEV 4
#define MAXAUDIOOUTDEV 4
static void as_get_audio_params(
int *pnaudioindev, int *paudioindev, int *pchindev,
int *pnaudiooutdev, int *paudiooutdev, int *pchoutdev,
int *prate, int *padvance, int *pcallback, int *pblocksize) {
#if (defined PD_MINOR_VERSION) && (PD_MINOR_VERSION >= 43)
sys_get_audio_params(pnaudioindev , paudioindev , pchindev,
pnaudiooutdev, paudiooutdev, pchoutdev,
prate, padvance, pcallback, pblocksize);
#else
if(pblocksize)
*pblocksize=-1;
sys_get_audio_params(pnaudioindev , paudioindev , pchindev,
pnaudiooutdev, paudiooutdev, pchoutdev,
prate, padvance, pcallback);
#endif
}
static t_class *audiosettings_class;
t_symbol*s_pdsym=NULL;
typedef struct _as_drivers {
t_symbol*name;
int id;
struct _as_drivers *next;
} t_as_drivers;
typedef struct _as_params {
int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
int rate, advance, callback;
int blocksize;
} t_as_params;
t_as_drivers*as_finddriver(t_as_drivers*drivers, const t_symbol*name) {
while(drivers) {
if(name==drivers->name)return drivers;
drivers=drivers->next;
}
return NULL;
}
t_as_drivers*as_finddriverid(t_as_drivers*drivers, const int id) {
while(drivers) {
if(id==drivers->id)return drivers;
drivers=drivers->next;
}
return NULL;
}
t_as_drivers*as_adddriver(t_as_drivers*drivers, t_symbol*name, int id, int overwrite) {
t_as_drivers*driver=as_finddriver(drivers, name);
if(driver) {
if(overwrite) {
driver->name=name;
driver->id =id;
}
return drivers;
}
driver=(t_as_drivers*)getbytes(sizeof(t_as_drivers));
driver->name=name;
driver->id=id;
driver->next=drivers;
return driver;
}
t_as_drivers*as_driverparse(t_as_drivers*drivers, const char*buf) {
int start=-1;
int stop =-1;
unsigned int index=0;
int depth=0;
const char*s;
char substring[MAXPDSTRING];
for(index=0, s=buf; 0!=*s; s++, index++) {
if('{'==*s) {
start=index;
depth++;
}
if('}'==*s) {
depth--;
stop=index;
if(start>=0 && start=MAXPDSTRING)length=MAXPDSTRING-1;
snprintf(substring, length, "%s", buf+start+1);
if(common_parsedriver(substring, length,
drivername, MAXPDSTRING,
&driverid)) {
drivers=as_adddriver(drivers, gensym(drivername), driverid, 0);
} else {
if((start+1)!=(stop))
post("unparseable: '%s' (%d-%d)", substring, start, stop);
}
}
start=-1;
stop=-1;
}
}
return drivers;
}
static t_as_drivers*DRIVERS=NULL;
static t_symbol*as_getdrivername(const int id) {
t_as_drivers*driver=as_finddriverid(DRIVERS, id);
if(driver) {
return driver->name;
} else {
return gensym("");
}
}
static int as_getdriverid(const t_symbol*id) {
t_as_drivers*driver=as_finddriver(DRIVERS, id);
if(driver) {
return driver->id;
}
return -1; /* unknown */
}
static void as_params_print(t_as_params*parms) {
int i=0;
post("\n=================================<");
post("indevs: %d", parms->naudioindev);
for(i=0; iaudioindev[i], parms->chindev[i]);
}
post("outdevs: %d", parms->naudiooutdev);
for(i=0; iaudiooutdev[i], parms->choutdev[i]);
}
post("rate=%d", parms->rate);
post("advance=%d", parms->advance);
post("callback=%d", parms->callback);
post(">=================================\n");
}
static void as_params_get(t_as_params*parms) {
int i=0;
memset(parms, 0, sizeof(t_as_params));
parms->callback=-1;
as_get_audio_params( &parms->naudioindev, parms->audioindev, parms->chindev,
&parms->naudiooutdev, parms->audiooutdev, parms->choutdev,
&parms->rate, &parms->advance,
&parms->callback, &parms->blocksize);
for(i=parms->naudioindev; iaudioindev[i]=0;
parms->chindev[i]=0;
}
for(i=parms->naudiooutdev; iaudiooutdev[i]=0;
parms->choutdev[i]=0;
}
// as_params_print(parms);
}
typedef struct _audiosettings
{
t_object x_obj;
t_outlet*x_info;
t_as_params x_params;
} t_audiosettings;
static void audiosettings_listparams(t_audiosettings *x);
static void audiosettings_listdevices(t_audiosettings *x)
{
int i;
char indevlist[MAXNDEV][DEVDESCSIZE], outdevlist[MAXNDEV][DEVDESCSIZE];
int indevs = 0, outdevs = 0, canmulti = 0, cancallback = 0;
t_atom atoms[3];
sys_get_audio_devs((char*)indevlist, &indevs,
(char*)outdevlist, &outdevs,
&canmulti, &cancallback,
MAXNDEV, DEVDESCSIZE);
SETSYMBOL (atoms+0, gensym("driver"));
SETSYMBOL (atoms+1, as_getdrivername(sys_audioapi));
outlet_anything(x->x_info, gensym("device"), 2, atoms);
SETSYMBOL (atoms+0, gensym("multi"));
SETFLOAT (atoms+1, (t_float)canmulti);
outlet_anything(x->x_info, gensym("device"), 2, atoms);
SETSYMBOL (atoms+0, gensym("callback"));
SETFLOAT (atoms+1, (t_float)cancallback);
outlet_anything(x->x_info, gensym("device"), 2, atoms);
SETSYMBOL(atoms+0, gensym("in"));
SETSYMBOL(atoms+1, gensym("devices"));
SETFLOAT (atoms+2, (t_float)indevs);
outlet_anything(x->x_info, gensym("device"), 3, atoms);
for(i=0; ix_info, gensym("device"), 3, atoms);
}
SETSYMBOL(atoms+0, gensym("out"));
SETSYMBOL(atoms+1, gensym("devices"));
SETFLOAT (atoms+2, (t_float)outdevs);
outlet_anything(x->x_info, gensym("device"), 3, atoms);
for(i=0; ix_info, gensym("device"), 3, atoms);
}
}
/* this is the actual settings used
*
*/
static void audiosettings_listparams(t_audiosettings *x) {
int i;
t_atom atoms[4];
t_as_params params;
as_params_get(¶ms);
SETSYMBOL (atoms+0, gensym("rate"));
SETFLOAT (atoms+1, (t_float)params.rate);
outlet_anything(x->x_info, gensym("params"), 2, atoms);
SETSYMBOL (atoms+0, gensym("advance"));
SETFLOAT (atoms+1, (t_float)params.advance);
outlet_anything(x->x_info, gensym("params"), 2, atoms);
SETSYMBOL (atoms+0, gensym("callback"));
SETFLOAT (atoms+1, (t_float)params.callback);
outlet_anything(x->x_info, gensym("params"), 2, atoms);
SETSYMBOL(atoms+0, gensym("in"));
SETSYMBOL(atoms+1, gensym("devices"));
SETFLOAT (atoms+2, (t_float)params.naudioindev);
outlet_anything(x->x_info, gensym("params"), 3, atoms);
for(i=0; ix_info, gensym("params"), 3, atoms);
}
SETSYMBOL(atoms+0, gensym("out"));
SETSYMBOL(atoms+1, gensym("devices"));
SETFLOAT (atoms+2, (t_float)params.naudiooutdev);
outlet_anything(x->x_info, gensym("params"), 3, atoms);
for(i=0; ix_info, gensym("params"), 3, atoms);
}
}
static void audiosettings_params_init(t_audiosettings*x) {
as_params_get(&x->x_params);
}
static void audiosettings_params_apply(t_audiosettings*x) {
/*
"pd audio-dialog ..."
#00: indev[0]
#01: indev[1]
#02: indev[2]
#03: indev[3]
#04: inchan[0]
#05: inchan[1]
#06: inchan[2]
#07: inchan[3]
#08: outdev[0]
#09: outdev[1]
#10: outdev[2]
#11: outdev[3]
#12: outchan[0]
#13: outchan[1]
#14: outchan[2]
#15: outchan[3]
#16: rate
#17: advance
#18: callback
*/
t_atom argv [2*MAXAUDIOINDEV+2*MAXAUDIOOUTDEV+3];
int argc=2*MAXAUDIOINDEV+2*MAXAUDIOOUTDEV+3;
int i=0;
// as_params_print(&x->x_params);
for(i=0; ix_params.audioindev[i]));
SETFLOAT(argv+i+1*MAXAUDIOINDEV, (t_float)(x->x_params.chindev [i]));
}
for(i=0; ix_params.audiooutdev[i]));
SETFLOAT(argv+i+2*MAXAUDIOINDEV+1*MAXAUDIOOUTDEV,(t_float)(x->x_params.choutdev [i]));
}
SETFLOAT(argv+2*MAXAUDIOINDEV+2*MAXAUDIOOUTDEV+0,(t_float)(x->x_params.rate));
SETFLOAT(argv+2*MAXAUDIOINDEV+2*MAXAUDIOOUTDEV+1,(t_float)(x->x_params.advance));
SETFLOAT(argv+2*MAXAUDIOINDEV+2*MAXAUDIOOUTDEV+2,(t_float)(x->x_params.callback));
if (s_pdsym->s_thing) typedmess(s_pdsym->s_thing,
gensym("audio-dialog"),
argc,
argv);
}
/* find the beginning of the next parameter in the list */
typedef enum {
PARAM_RATE,
PARAM_ADVANCE,
PARAM_CALLBACK,
PARAM_INPUT,
PARAM_OUTPUT,
PARAM_INVALID
} t_paramtype;
static t_paramtype audiosettings_setparams_id(t_symbol*s) {
if(gensym("@rate")==s) {
return PARAM_RATE;
} else if(gensym("@samplerate")==s) {
return PARAM_RATE;
} else if(gensym("@advance")==s) {
return PARAM_ADVANCE;
} else if(gensym("@buffersize")==s) {
return PARAM_ADVANCE;
} else if(gensym("@callback")==s) {
return PARAM_CALLBACK;
} else if(gensym("@input")==s) {
return PARAM_INPUT;
} else if(gensym("@output")==s) {
return PARAM_OUTPUT;
}
return PARAM_INVALID;
}
/* find the beginning of the next parameter in the list */
static int audiosettings_setparams_next(int argc, t_atom*argv) {
int i=0;
for(i=0; is_name[0])
return i;
}
}
return i;
}
/* ... */
static int audiosettings_setparams_rate(t_audiosettings*x, int argc, t_atom*argv) {
if(argc<=0)return 1;
t_int rate=atom_getint(argv);
if(rate>0)
x->x_params.rate=rate;
return 1;
}
/* ... */
static int audiosettings_setparams_advance(t_audiosettings*x, int argc, t_atom*argv) {
if(argc<=0)return 1;
t_int advance=atom_getint(argv);
if(advance>0)
x->x_params.advance=advance;
return 1;
}
/* ... */
static int audiosettings_setparams_callback(t_audiosettings*x, int argc, t_atom*argv) {
if(argc<=0)return 1;
t_int callback=atom_getint(argv);
x->x_params.callback=callback;
return 1;
}
/* [ ]* ... */
static int audiosettings_setparams_input(t_audiosettings*x, int argc, t_atom*argv) {
int length=audiosettings_setparams_next(argc, argv);
int i;
int numpairs=length/2;
if(length%2)return length;
if(numpairs>MAXAUDIOINDEV)
numpairs=MAXAUDIOINDEV;
for(i=0; ix_params.audioindev[i]=dev;
x->x_params.chindev[i]=ch;
}
return length;
}
static int audiosettings_setparams_output(t_audiosettings*x, int argc, t_atom*argv) {
int length=audiosettings_setparams_next(argc, argv);
int i;
int numpairs=length/2;
if(length%2)return length;
if(numpairs>MAXAUDIOOUTDEV)
numpairs=MAXAUDIOOUTDEV;
for(i=0; ix_params.audiooutdev[i]=dev;
x->x_params.choutdev[i]=ch;
}
return length;
}
static void audiosettings_setparams(t_audiosettings *x, t_symbol*s, int argc, t_atom*argv) {
/*
PLAN:
several messages that accumulate to a certain settings, and then "apply" them
*/
int apply=1;
int advance=0;
t_paramtype param=PARAM_INVALID;
audiosettings_params_init (x); /* re-initialize to what we got */
advance=audiosettings_setparams_next(argc, argv);
while((argc-=advance)>0) {
argv+=advance;
s=atom_getsymbol(argv);
param=audiosettings_setparams_id(s);
argv++;
argc--;
switch(param) {
case PARAM_RATE:
advance=audiosettings_setparams_rate(x, argc, argv);
break;
case PARAM_ADVANCE:
advance=audiosettings_setparams_advance(x, argc, argv);
break;
case PARAM_CALLBACK:
advance=audiosettings_setparams_callback(x, argc, argv);
break;
case PARAM_INPUT:
advance=audiosettings_setparams_input(x, argc, argv);
break;
case PARAM_OUTPUT:
advance=audiosettings_setparams_output(x, argc, argv);
break;
default:
pd_error(x, "unknown parameter"); postatom(1, argv);endpost();
break;
}
argc-=advance;
argv+=advance;
advance=audiosettings_setparams_next(argc, argv);
}
if(apply) {
audiosettings_params_apply(x);
}
}
static void audiosettings_testdevices(t_audiosettings *x);
/*
*/
static void audiosettings_listdrivers(t_audiosettings *x)
{
t_as_drivers*driver=NULL;
t_atom ap[2];
for(driver=DRIVERS; driver; driver=driver->next) {
SETSYMBOL(ap+0, driver->name);
SETFLOAT (ap+1, (t_float)(driver->id));
outlet_anything(x->x_info, gensym("driver"), 2, ap);
}
}
static void audiosettings_setdriver(t_audiosettings *x, t_symbol*s, int argc, t_atom*argv) {
int id=-1;
s=gensym(""); /* just re-use the argument, which is not needed anyhow */
switch(argc) {
case 0:
audiosettings_listdrivers(x);
return;
case 1:
if(A_FLOAT==argv->a_type) {
s=as_getdrivername(atom_getint(argv));
break;
} else if (A_SYMBOL==argv->a_type) {
s=atom_getsymbol(argv);
break;
}
}
id=as_getdriverid(s);
if(id<0) {
pd_error(x, "invalid driver '%s'", s->s_name);
return;
}
verbose(1, "setting driver '%s' (=%d)", s->s_name, id);
#ifdef HAVE_SYS_CLOSE_AUDIO
sys_close_audio();
sys_set_audio_api(id);
sys_reopen_audio();
#else
if (s_pdsym->s_thing) {
t_atom ap[1];
SETFLOAT(ap, id);
typedmess(s_pdsym->s_thing,
gensym("audio-setapi"),
1,
ap);
}
#endif
}
static void audiosettings_bang(t_audiosettings *x) {
audiosettings_listdrivers(x);
audiosettings_listdevices(x);
audiosettings_listparams(x);
}
static void audiosettings_free(t_audiosettings *x){
}
static void *audiosettings_new(void)
{
t_audiosettings *x = (t_audiosettings *)pd_new(audiosettings_class);
x->x_info=outlet_new(&x->x_obj, 0);
char buf[MAXPDSTRING];
sys_get_audio_apis(buf);
DRIVERS=as_driverparse(DRIVERS, buf);
audiosettings_params_init (x);
return (x);
}
void audiosettings_setup(void)
{
s_pdsym=gensym("pd");
mediasettings_boilerplate("[audiosettings] audio settings manager",
#ifdef AUDIOSETTINGS_VERSION
AUDIOSETTINGS_VERSION
#else
0
#endif
);
#if (defined PD_MINOR_VERSION) && (PD_MINOR_VERSION < 43)
if(1) {
int major, minor, bugfix;
sys_getversion(&major, &minor, &bugfix);
if(0==major && minor>=43) {
error("[audiosettings] have been compiled against an old version of Pd");
error(" that is incompatible with the one you are using!");
error(" recompile [audiosettings]");
}
return;
}
#endif
audiosettings_class = class_new(gensym("audiosettings"), (t_newmethod)audiosettings_new, (t_method)audiosettings_free,
sizeof(t_audiosettings), 0, 0);
class_addbang(audiosettings_class, (t_method)audiosettings_bang);
class_addmethod(audiosettings_class, (t_method)audiosettings_listdrivers, gensym("listdrivers"), A_NULL);
class_addmethod(audiosettings_class, (t_method)audiosettings_listdevices, gensym("listdevices"), A_NULL);
class_addmethod(audiosettings_class, (t_method)audiosettings_listparams, gensym("listparams"), A_NULL);
class_addmethod(audiosettings_class, (t_method)audiosettings_setdriver, gensym("driver"), A_GIMME, A_NULL);
class_addmethod(audiosettings_class, (t_method)audiosettings_setparams, gensym("params"), A_GIMME, A_NULL);
class_addmethod(audiosettings_class, (t_method)audiosettings_testdevices, gensym("testdevices"), A_NULL);
}
static void audiosettings_testdevices(t_audiosettings *x)
{
int i;
char indevlist[MAXNDEV][DEVDESCSIZE], outdevlist[MAXNDEV][DEVDESCSIZE];
int indevs = 0, outdevs = 0, canmulti = 0, cancallback = 0;
if(0) {
pd_error(x, "this should never happen");
}
sys_get_audio_devs((char*)indevlist, &indevs, (char*)outdevlist, &outdevs, &canmulti,
&cancallback, MAXNDEV, DEVDESCSIZE);
post("%d indevs", indevs);
for(i=0; i