From 64930746f2920dd7bdfc6488920e21bc4decabbc Mon Sep 17 00:00:00 2001 From: joq Date: Thu, 25 Mar 2004 19:31:51 +0000 Subject: [PATCH] [0.96.0] merge MacOSX EXP tree into HEAD git-svn-id: svn+ssh://jackaudio.org/trunk/jack@673 0c269be4-1314-0410-8aa9-9f06e86f4224 --- .cvsignore | 32 +- Makefile.am | 13 +- TODO | 9 + autogen.sh | 18 +- config/.cvsignore | 10 + config/Makefile.am | 14 + config/acinclude.m4 | 41 + config/configure.host | 159 +++ config/cpu/alpha/atomicity.h | 76 + config/cpu/alpha/cycles.h | 35 + config/cpu/cris/atomicity.h | 78 + config/cpu/generic/atomicity.h | 80 ++ macosx/ipc.h => config/cpu/generic/cycles.h | 36 +- config/cpu/hppa/atomicity.h | 90 ++ config/cpu/i386/atomicity.h | 76 + config/cpu/i386/cycles.h | 24 + config/cpu/i486/atomicity.h | 54 + {jack => config/cpu/i486}/cycles.h | 74 - config/cpu/ia64/atomicity.h | 51 + config/cpu/ia64/cycles.h | 36 + config/cpu/ia64/ia64intrin.h | 130 ++ config/cpu/m68k/atomicity.h | 139 ++ config/cpu/mips/atomicity.h | 83 ++ config/cpu/powerpc/atomicity.h | 78 + config/cpu/powerpc/cycles.h | 55 + config/cpu/s390/atomicity.h | 60 + config/cpu/sparc/atomicity.h | 131 ++ config/os/aix/atomicity.h | 59 + config/os/generic/ipc.h | 28 + config/os/generic/os_defines.h | 30 + config/os/generic/poll.h | 28 + config/os/generic/time.h | 42 + config/os/gnu-linux/time.h | 97 ++ config/os/irix/atomicity.h | 50 + config/os/macosx/README | 183 +++ .../fakepoll.c => config/os/macosx/fakepoll.h | 1 - {macosx => config/os/macosx}/getopt.h | 11 +- macosx/ipc.c => config/os/macosx/ipc.h | 90 +- .../os/macosx/jack.xcode}/project.pbxproj | 1249 +++++++---------- {macosx => config/os/macosx}/mach_port.h | 0 config/os/macosx/os_defines.h | 39 + config/os/macosx/pThreadUtilities.h | 203 +++ config/os/macosx/poll.h | 29 + .../config.h => config/os/macosx/portaudio.h | 17 +- {jack => config/os/macosx}/time.h | 37 +- config/sysdeps/.cvsignore | 3 + config/sysdeps/Makefile.am | 23 + configure.in | 65 +- doc/Makefile.am | 4 +- doc/mainpage.dox | 8 + doc/porting.dox | 119 ++ doc/reference.doxygen.in | 3 +- drivers/alsa/Makefile.am | 3 +- drivers/alsa/alsa_driver.c | 10 +- drivers/alsa/alsa_driver.h | 2 +- drivers/alsa/memops.c | 2 +- drivers/dummy/dummy_driver.c | 5 +- drivers/iec61883/iec61883_driver.c | 3 +- drivers/oss/oss_driver.c | 2 +- drivers/oss/oss_driver.h | 1 - drivers/portaudio/portaudio_driver.c | 434 ++++-- drivers/portaudio/portaudio_driver.h | 15 +- example-clients/Makefile.am | 33 +- example-clients/capture_client.c | 17 +- example-clients/impulse_grabber.c | 3 +- example-clients/inprocess.c | 17 +- example-clients/lsp.c | 3 +- example-clients/metro.c | 6 +- jack.pc.in | 2 +- jack/Makefile.am | 11 +- jack/atomicity.h | 39 + jack/engine.h | 2 +- jack/internal.h | 30 +- jack/jack.h | 15 +- jack/memops.h | 97 ++ jack/types.h | 8 - jack/version.h.in | 3 +- jackd/Makefile.am | 2 +- jackd/engine.c | 70 +- jackd/jackd.c | 13 +- libjack/ChangeLog | 6 + libjack/Makefile.am | 2 +- libjack/client.c | 237 ++-- libjack/driver.c | 12 +- libjack/local.h | 3 +- libjack/pool.c | 10 +- libjack/ringbuffer.c | 7 + libjack/shm.c | 5 +- libjack/timestamps.c | 2 +- libjack/transclient.c | 40 +- macosx/fakepoll.h | 53 - macosx/pThreadUtilities.c | 150 -- macosx/pThreadUtilities.h | 50 - macosx/readme.txt | 133 -- 94 files changed, 3872 insertions(+), 1786 deletions(-) create mode 100644 config/.cvsignore create mode 100644 config/Makefile.am create mode 100644 config/acinclude.m4 create mode 100644 config/configure.host create mode 100644 config/cpu/alpha/atomicity.h create mode 100644 config/cpu/alpha/cycles.h create mode 100644 config/cpu/cris/atomicity.h create mode 100644 config/cpu/generic/atomicity.h rename macosx/ipc.h => config/cpu/generic/cycles.h (58%) create mode 100644 config/cpu/hppa/atomicity.h create mode 100644 config/cpu/i386/atomicity.h create mode 100644 config/cpu/i386/cycles.h create mode 100644 config/cpu/i486/atomicity.h rename {jack => config/cpu/i486}/cycles.h (57%) create mode 100644 config/cpu/ia64/atomicity.h create mode 100644 config/cpu/ia64/cycles.h create mode 100644 config/cpu/ia64/ia64intrin.h create mode 100644 config/cpu/m68k/atomicity.h create mode 100644 config/cpu/mips/atomicity.h create mode 100644 config/cpu/powerpc/atomicity.h create mode 100644 config/cpu/powerpc/cycles.h create mode 100644 config/cpu/s390/atomicity.h create mode 100644 config/cpu/sparc/atomicity.h create mode 100644 config/os/aix/atomicity.h create mode 100644 config/os/generic/ipc.h create mode 100644 config/os/generic/os_defines.h create mode 100644 config/os/generic/poll.h create mode 100644 config/os/generic/time.h create mode 100644 config/os/gnu-linux/time.h create mode 100644 config/os/irix/atomicity.h create mode 100644 config/os/macosx/README rename macosx/fakepoll.c => config/os/macosx/fakepoll.h (99%) mode change 100755 => 100644 rename {macosx => config/os/macosx}/getopt.h (77%) mode change 100755 => 100644 rename macosx/ipc.c => config/os/macosx/ipc.h (65%) rename {macosx/jack.pbproj => config/os/macosx/jack.xcode}/project.pbxproj (58%) mode change 100755 => 100644 rename {macosx => config/os/macosx}/mach_port.h (100%) create mode 100644 config/os/macosx/os_defines.h create mode 100644 config/os/macosx/pThreadUtilities.h create mode 100644 config/os/macosx/poll.h rename macosx/config.h => config/os/macosx/portaudio.h (80%) mode change 100755 => 100644 rename {jack => config/os/macosx}/time.h (59%) create mode 100644 config/sysdeps/.cvsignore create mode 100644 config/sysdeps/Makefile.am create mode 100644 doc/porting.dox create mode 100644 jack/atomicity.h create mode 100644 jack/memops.h delete mode 100755 macosx/fakepoll.h delete mode 100644 macosx/pThreadUtilities.c delete mode 100644 macosx/pThreadUtilities.h delete mode 100755 macosx/readme.txt diff --git a/.cvsignore b/.cvsignore index 5dba9a3a..767422b2 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,25 +1,19 @@ +*.desc +*.pc +*.tar.gz +*diff +*diffs +.deps +Makefile +Makefile.in +aclocal.m4 autom4te.cache +config.cache config.h config.h.in -stamp-h1 config.log -aclocal.m4 config.status -config.cache -libtool -*.pc -.deps -Makefile -Makefile.in -jack.spec configure -*.tar.gz -*.desc -*diff -*diffs -compile -depcomp -install-sh -missing -mkinstalldirs -doxygen-build.stamp +jack.spec +libtool +stamp-h1 diff --git a/Makefile.am b/Makefile.am index 75b1e459..8797b295 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,6 @@ -MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config.h.in \ +MAINTAINERCLEANFILES = Makefile.in configure config.h.in \ stamp-h.in config.log config.cache \ - config.guess mkinstalldirs config.status \ - missing install-sh config.sub ltconfig \ - ltmain.sh + config.status if HAVE_DOXYGEN DOC_DIR = doc @@ -16,14 +14,13 @@ dist-check-doxygen: @false endif -SUBDIRS = jack libjack jackd drivers example-clients $(DOC_DIR) - -DIST_SUBDIRS = jack libjack jackd drivers example-clients doc +SUBDIRS = config jack libjack jackd drivers example-clients $(DOC_DIR) +DIST_SUBDIRS = config jack libjack jackd drivers example-clients doc pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = jack.pc -EXTRA_DIST = depcomp COPYING COPYING.GPL COPYING.LGPL +EXTRA_DIST = COPYING COPYING.GPL COPYING.LGPL AUTOMAKE_OPTIONS = foreign diff --git a/TODO b/TODO index 16092c95..93c50bd4 100644 --- a/TODO +++ b/TODO @@ -20,6 +20,15 @@ send a change request to Kai Vehmanen (mailto:k_at_eca.cx). ----------------------------------------------------------------------- +TODO for merging Mac OS X support + +- + -- fix cpu/generic/atomicity.h:36:#include +- clean up other header files + -- , fakepoll.h, etc. + -- , in shm.c + -- need config/os/generic/time.h implementation + TODO before-1.0 - add explanation of protocol versioning to README.developers (kaiv) diff --git a/autogen.sh b/autogen.sh index 1afe37e8..c1cf7ed6 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,11 +1,25 @@ #!/bin/sh -libtoolize --force 2>&1 | sed '/^You should/d' || { +if which libtoolize >/dev/null +then + LIBTOOLIZE=libtoolize +else + if which glibtoolize >/dev/null + then + # on the Mac it's called glibtoolize for some reason + LIBTOOLIZE=glibtoolize + else + echo "libtoolize not found" + exit 1 + fi +fi + +$LIBTOOLIZE --force 2>&1 | sed '/^You should/d' || { echo "libtool failed, exiting..." exit 1 } -aclocal $ACLOCAL_FLAGS || { +aclocal $ACLOCAL_FLAGS -I config || { echo "aclocal \$ACLOCAL_FLAGS where \$ACLOCAL_FLAGS= failed, exiting..." exit 1 } diff --git a/config/.cvsignore b/config/.cvsignore new file mode 100644 index 00000000..c0b20bc2 --- /dev/null +++ b/config/.cvsignore @@ -0,0 +1,10 @@ +Makefile +Makefile.in +compile +config.guess +config.sub +depcomp +install-sh +ltmain.sh +missing +mkinstalldirs diff --git a/config/Makefile.am b/config/Makefile.am new file mode 100644 index 00000000..64347d12 --- /dev/null +++ b/config/Makefile.am @@ -0,0 +1,14 @@ +# Currently, we don't actually build anything in the `cpu' and `os' +# subdirectories. If we ever do, they will need Makefiles. For now, +# this is sufficient. Unfortunately, their CVS subdirectories also +# get distributed as a side-effect. + +EXTRA_DIST = configure.host depcomp cpu os +MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.sub \ + install-sh ltmain.sh missing mkinstalldirs + +# Link all relevant headers into the `sysdeps' directory. The order +# of these loops determines header file precedence. + +SUBDIRS = sysdeps +DIST_SUBDIRS = sysdeps diff --git a/config/acinclude.m4 b/config/acinclude.m4 new file mode 100644 index 00000000..6a69887c --- /dev/null +++ b/config/acinclude.m4 @@ -0,0 +1,41 @@ +dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR) +dnl example +dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) +dnl will set SYSCONFDIR to /usr/local/etc + +dnl written by thomas vander stichele + +AC_DEFUN(AS_AC_EXPAND, +[ + EXP_VAR=[$1] + FROM_VAR=[$2] + + dnl first expand prefix and exec_prefix if necessary + prefix_save=$prefix + if test "x$prefix" = "xNONE"; then + prefix=/usr/local + fi + exec_prefix_save=$exec_prefix + if test "x$exec_prefix" = "xNONE"; then + if test "x$prefix_save" = "xNONE"; then + exec_prefix=/usr/local + else + exec_prefix=$prefix + fi + fi + + full_var="$FROM_VAR" + dnl loop until it doesn't change anymore + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + dnl clean up + full_var=$new_full_var + [$1]=$full_var + prefix=$prefix_save + exec_prefix=$exec_prefix_save +]) + diff --git a/config/configure.host b/config/configure.host new file mode 100644 index 00000000..c2dc8881 --- /dev/null +++ b/config/configure.host @@ -0,0 +1,159 @@ +######################################################################## +# +# configure.host -- JACK Audio Connection Kit version. +# +# This script and the system-dependent header directories it uses were +# adapted for JACK from gcc/libstdc++-v3/configure.host. +# +# We've tried to keep it as close to the original as possible, while +# removing a bunch of os-specific files that didn't seem relevant. +# The primary goal has been to avoid changing the cpu-dependent +# atomicity.h headers. +# +# If you need to make changes, the relevant GCC documentation may +# prove helpful, , especially +# the +# discussion of . +# +######################################################################## + +# This shell script handles all host based configuration for libstdc++. +# It sets various shell variables based on the the host and the +# configuration options. You can modify this shell script without needing +# to rerun autoconf/aclocal/etc. This file is "sourced" not executed. +# +# You should read docs/html/17_intro/porting.* to make sense of this file. +# +# +# It uses the following shell variables as set by config.guess: +# host The configuration host (full CPU-vendor-OS triplet) +# host_cpu The configuration host CPU +# host_os The configuration host OS +# +# +# It sets the following shell variables: +# +# cpu_include_dir CPU-specific directory, defaults to cpu/generic +# if cpu/host_cpu doesn't exist. This is +# used to set atomicity_include_dir. +# +# os_include_dir OS-specific directory, defaults to os/generic. +# +# atomicity_include_dir location of atomicity.h, +# defaults to cpu_include_dir +# +# It possibly modifies the following variables: +# +# OS_LDFLAGS extra flags to pass when linking the library, of +# the form '-Wl,blah' +# (defaults to empty in acinclude.m4) +# +# If the defaults will not work for your platform, you need only change the +# variables that won't work, i.e., you do not need to explicitly set a +# working variable to its default. Most hosts only need to change the two +# *_include_dir variables. + + +# DEFAULTS +# Try to guess a default cpu_include_dir based on the name of the CPU. We +# cannot do this for os_include_dir; there are too many portable operating +# systems out there. :-) + +# HOST-SPECIFIC OVERRIDES +# Set any CPU-dependent bits. +# Here we override defaults and catch more general cases due to naming +# conventions (e.g., chip_name* to catch all variants). + +# THIS TABLE IS SORTED. KEEP IT THAT WAY. +case "${host_cpu}" in + alpha*) + try_cpu=alpha + ;; + i[3567]86 | x86_64) + try_cpu=i486 + ;; + hppa*) + try_cpu=hppa + ;; + mips*) + # NB: cpu/mips/atomicity.h needs MIPS II or above. + # Of course, there is no sane way to test for this, no ABI macro, + # and no consistent host_cpu name differentiation. Therefore, only + # use it where it is known to be safe, ie it runs linux (see below). + try_cpu=generic + ;; + m680[246]0) + try_cpu=m68k + ;; + powerpc* | rs6000) + try_cpu=powerpc + ;; + s390x) + try_cpu=s390 + ;; + sparc* | ultrasparc) + try_cpu=sparc + ;; + *) + if test -d $srcdir/config/cpu/${host_cpu}; then + try_cpu=${host_cpu} + else + try_cpu=generic + fi + ;; +esac + +# Now look for the file(s) usually tied to a CPU model, and make +# default choices for those if they haven't been explicitly set +# already. +cpu_include_dir="cpu/${try_cpu}" +atomicity_include_dir=$cpu_include_dir + + +# Set any OS-dependent bits. +# Set the os_include_dir. +# If atomic ops and/or numeric limits are OS-specific rather than +# CPU-specifc, set those here too. +# THIS TABLE IS SORTED. KEEP IT THAT WAY. +case "${host_os}" in + aix4.[3456789]* | aix[56789]*) + # We set os_include_dir to os/aix only on AIX 4.3 and newer, but + # os/aix/atomicity.h works on earlier versions of AIX 4.*, so we + # explicitly duplicate the directory for 4.[<3]. + os_include_dir="os/aix" + atomicity_include_dir="os/aix" + OS_LDFLAGS="-Wl,-G" + ;; + aix4.*) + os_include_dir="os/generic" + atomicity_include_dir="os/aix" + ;; + aix*) + os_include_dir="os/generic" + atomicity_include_dir="cpu/generic" + ;; + gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu) + os_include_dir="os/gnu-linux" + ;; + irix*) + os_include_dir="os/irix" + atomicity_include_dir=$os_include_dir + ;; + darwin*) + os_include_dir="os/macosx" + OS_LDFLAGS="-framework CoreAudio" + TRY_POSIX_SHM=yes # POSIX shm works better on darwin + ;; + *) + os_include_dir="os/generic" + ;; +esac + + +# Set any OS-dependent and CPU-dependent bits. +# THIS TABLE IS SORTED. KEEP IT THAT WAY. +case "${host}" in + mips*-*-linux*) + atomicity_include_dir="cpu/mips" + ;; +esac diff --git a/config/cpu/alpha/atomicity.h b/config/cpu/alpha/atomicity.h new file mode 100644 index 00000000..cb071cda --- /dev/null +++ b/config/cpu/alpha/atomicity.h @@ -0,0 +1,76 @@ +// Low-level functions for atomic operations: Alpha version -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +/* @@@ With gas we can play nice .subsection games to get the + non-predicted branch pointing forward. But Digital assemblers + don't understand those directives. This isn't a terribly + important issue, so just ignore it. */ + +typedef int _Atomic_word; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + register int __result, __tmp; + + __asm__ __volatile__ ( + "\n$Lxadd_%=:\n\t" + "ldl_l %0,%3\n\t" + "addl %0,%4,%1\n\t" + "stl_c %1,%2\n\t" + "beq %1,$Lxadd_%=\n\t" + "mb" + : "=&r"(__result), "=&r"(__tmp), "=m"(*__mem) + : "m" (*__mem), "r"(__val)); + + return __result; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + register _Atomic_word __result; + + __asm__ __volatile__ ( + "\n$Ladd_%=:\n\t" + "ldl_l %0,%2\n\t" + "addl %0,%3,%0\n\t" + "stl_c %0,%1\n\t" + "beq %0,$Ladd_%=\n\t" + "mb" + : "=&r"(__result), "=m"(*__mem) + : "m" (*__mem), "r"(__val)); +} + +#endif /* atomicity.h */ diff --git a/config/cpu/alpha/cycles.h b/config/cpu/alpha/cycles.h new file mode 100644 index 00000000..e746849e --- /dev/null +++ b/config/cpu/alpha/cycles.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2001 Paul Davis + Code derived from various headers from the Linux kernel + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __jack_cycles_h__ +#define __jack_cycles_h__ + +/* alpha */ + +typedef unsigned int cycles_t; +static inline cycles_t get_cycles (void) +{ + cycles_t ret; + __asm__ __volatile__ ("rpcc %0" : "=r"(ret)); + return ret; +} + +#endif /* __jack_cycles_h__ */ diff --git a/config/cpu/cris/atomicity.h b/config/cpu/cris/atomicity.h new file mode 100644 index 00000000..fecb9dc1 --- /dev/null +++ b/config/cpu/cris/atomicity.h @@ -0,0 +1,78 @@ +// Low-level functions for atomic operations: CRIS version -*- C++ -*- + +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +// This entity must not cross a page boundary. +typedef int _Atomic_word __attribute__ ((__aligned__ (4))); + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(_Atomic_word* __mem, int __val) +{ + int __tmp; + _Atomic_word __result; + +#if (__CRIS_arch_version >= 10) + __asm__ __volatile__ (" clearf \n" + "0: \n" + " move.d %4,%2 \n" + " move.d [%3],%0 \n" + " add.d %0,%2 \n" + " ax \n" + " move.d %2,[%3] \n" + " bwf 0b \n" + " clearf \n" + : "=&r" (__result), "=m" (*__mem), "=&r" (__tmp) + : "r" (__mem), "g" (__val), "m" (*__mem)); +#else + __asm__ __volatile__ (" move $ccr,$r9 \n" + " di \n" + " move.d %4,%2 \n" + " move.d [%3],%0 \n" + " add.d %0,%2 \n" + " move.d %2,[%3] \n" + " move $r9,$ccr \n" + : "=&r" (__result), "=m" (*__mem), "=&r" (__tmp) + : "r" (__mem), "g" (__val), "m" (*__mem) + : "r9"); +#endif + + return __result; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(_Atomic_word* __mem, int __val) +{ + __exchange_and_add(__mem, __val); +} + +#endif /* atomicity.h */ diff --git a/config/cpu/generic/atomicity.h b/config/cpu/generic/atomicity.h new file mode 100644 index 00000000..ab7fad81 --- /dev/null +++ b/config/cpu/generic/atomicity.h @@ -0,0 +1,80 @@ +// Low-level functions for atomic operations: Generic version -*- C++ -*- + +// Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#warning No native atomic operations are provided for this platform. +#warning They will be faked using a mutex, degrading performance. + +#include + +#define _GLIBCXX_NEED_GENERIC_MUTEX + +typedef int _Atomic_word; + +namespace __gnu_cxx +{ + extern __gthread_mutex_t _Atomic_add_mutex; + +#ifndef __GTHREAD_MUTEX_INIT + extern __gthread_once_t _Atomic_add_mutex_once; + extern void __gthread_atomic_add_mutex_once(); +#endif +} + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ +#ifndef __GTHREAD_MUTEX_INIT + __gthread_once(&__gnu_cxx::_Atomic_add_mutex_once, + __gnu_cxx::__gthread_atomic_add_mutex_once); +#endif + + _Atomic_word __result; + + __gthread_mutex_lock(&__gnu_cxx::_Atomic_add_mutex); + + __result = *__mem; + *__mem += __val; + + __gthread_mutex_unlock(&__gnu_cxx::_Atomic_add_mutex); + return __result; +} + + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + (void) __exchange_and_add(__mem, __val); +} + +#endif /* atomicity.h */ diff --git a/macosx/ipc.h b/config/cpu/generic/cycles.h similarity index 58% rename from macosx/ipc.h rename to config/cpu/generic/cycles.h index 486e51d1..13eb2041 100644 --- a/macosx/ipc.h +++ b/config/cpu/generic/cycles.h @@ -1,6 +1,7 @@ /* - Copyright © Grame 2003 - + Copyright (C) 2001 Paul Davis + Code derived from various headers from the Linux kernel + 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 @@ -14,24 +15,27 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France - grame@rd.grame.fr + + $Id$ */ -#ifndef __ipc__ -#define __ipc__ +#ifndef __jack_cycles_h__ +#define __jack_cycles_h__ + +/* generic solution */ -#include -#include -#include +#warning You are compiling JACK on a platform for which jack/cycles.h needs work +#include -int jack_client_resume(jack_client_internal_t *client); -int jack_client_suspend(jack_client_t * client); +typedef long cycles_t; +extern cycles_t cacheflush_time; -void allocate_mach_serverport(jack_engine_t * engine, jack_client_internal_t *client); -int allocate_mach_clientport(jack_client_t * client, int portnum); +static inline cycles_t get_cycles(void) +{ + struct timeval tv; + gettimeofday (&tv, NULL); -typedef int socklen_t; + return tv.tv_usec; +} -#endif \ No newline at end of file +#endif /* __jack_cycles_h__ */ diff --git a/config/cpu/hppa/atomicity.h b/config/cpu/hppa/atomicity.h new file mode 100644 index 00000000..b0741424 --- /dev/null +++ b/config/cpu/hppa/atomicity.h @@ -0,0 +1,90 @@ +/* Low-level functions for atomic operations. PA-RISC version. -*- C++ -*- + Copyright 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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. + + The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +typedef int _Atomic_word; + +template +struct __Atomicity_lock +{ + static volatile int _S_atomicity_lock; +}; + +template +volatile int +__Atomicity_lock<__inst>::_S_atomicity_lock __attribute__ ((aligned (16))) = 1; + +/* Because of the lack of weak support when using the hpux + som linker, we explicitly instantiate the atomicity lock + in src/misc-inst.cc when _GLIBCXX_INST_ATOMICITY_LOCK + is defined. */ +#ifndef _GLIBCXX_INST_ATOMICITY_LOCK +template volatile int __Atomicity_lock<0>::_S_atomicity_lock; +#endif + +static inline int +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word result; + int tmp; + volatile int& lock = __Atomicity_lock<0>::_S_atomicity_lock; + + __asm__ __volatile__ ("ldcw 0(%1),%0\n\t" + "cmpib,<>,n 0,%0,.+20\n\t" + "ldw 0(%1),%0\n\t" + "cmpib,= 0,%0,.-4\n\t" + "nop\n\t" + "b,n .-20" + : "=&r" (tmp) + : "r" (&lock)); + + result = *__mem; + *__mem = result + __val; + /* Reset lock with PA 2.0 "ordered" store. */ + __asm__ __volatile__ ("stw,ma %1,0(%0)" + : : "r" (&lock), "r" (tmp) : "memory"); + return result; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(_Atomic_word* __mem, int __val) +{ + int tmp; + volatile int& lock = __Atomicity_lock<0>::_S_atomicity_lock; + + __asm__ __volatile__ ("ldcw 0(%1),%0\n\t" + "cmpib,<>,n 0,%0,.+20\n\t" + "ldw 0(%1),%0\n\t" + "cmpib,= 0,%0,.-4\n\t" + "nop\n\t" + "b,n .-20" + : "=&r" (tmp) + : "r" (&lock)); + + *__mem += __val; + /* Reset lock with PA 2.0 "ordered" store. */ + __asm__ __volatile__ ("stw,ma %1,0(%0)" + : : "r" (&lock), "r" (tmp) : "memory"); +} + +#endif diff --git a/config/cpu/i386/atomicity.h b/config/cpu/i386/atomicity.h new file mode 100644 index 00000000..7a949c30 --- /dev/null +++ b/config/cpu/i386/atomicity.h @@ -0,0 +1,76 @@ +// Low-level functions for atomic operations: x86, x >= 3 version -*- C++ -*- + +// Copyright (C) 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +typedef int _Atomic_word; + +template + struct __Atomicity_lock + { + static volatile _Atomic_word _S_atomicity_lock; + }; + +template +volatile _Atomic_word __Atomicity_lock<__inst>::_S_atomicity_lock = 0; + +template volatile _Atomic_word __Atomicity_lock<0>::_S_atomicity_lock; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + register _Atomic_word __result, __tmp = 1; + + /* obtain the atomic exchange/add spin lock */ + do { + __asm__ __volatile__ ("xchg{l} {%0,%1|%1,%0}" + : "=m" (__Atomicity_lock<0>::_S_atomicity_lock), + "+r" (__tmp) + : "m" (__Atomicity_lock<0>::_S_atomicity_lock)); + } while (__tmp); + + __result = *__mem; + *__mem += __val; + + /* release spin lock */ + __Atomicity_lock<0>::_S_atomicity_lock = 0; + + return __result; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + __exchange_and_add(__mem, __val); +} + +#endif /* atomicity.h */ diff --git a/config/cpu/i386/cycles.h b/config/cpu/i386/cycles.h new file mode 100644 index 00000000..b75a4568 --- /dev/null +++ b/config/cpu/i386/cycles.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2001 Paul Davis + Code derived from various headers from the Linux kernel + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +/* the i486 version of this header is compatible */ + +#include diff --git a/config/cpu/i486/atomicity.h b/config/cpu/i486/atomicity.h new file mode 100644 index 00000000..014cf629 --- /dev/null +++ b/config/cpu/i486/atomicity.h @@ -0,0 +1,54 @@ +// Low-level functions for atomic operations: x86, x >= 4 version -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +typedef int _Atomic_word; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + register _Atomic_word __result; + __asm__ __volatile__ ("lock; xaddl %0,%1" + : "=r" (__result), "=m" (*__mem) + : "0" (__val), "m" (*__mem)); + return __result; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + __asm__ __volatile__ ("lock; addl %1,%0" + : "=m" (*__mem) : "ir" (__val), "m" (*__mem)); +} + +#endif /* atomicity.h */ diff --git a/jack/cycles.h b/config/cpu/i486/cycles.h similarity index 57% rename from jack/cycles.h rename to config/cpu/i486/cycles.h index 062df7a9..855dfb45 100644 --- a/jack/cycles.h +++ b/config/cpu/i486/cycles.h @@ -22,8 +22,6 @@ #ifndef __jack_cycles_h__ #define __jack_cycles_h__ -#if defined(__i386__) || defined(__x86_64__) - /* * Standard way to access the cycle counter on i586+ CPUs. * Currently only used on SMP. @@ -53,76 +51,4 @@ static inline cycles_t get_cycles (void) return ret; } -#elif defined(__powerpc__) - -#define CPU_FTR_601 0x00000100 - -typedef unsigned long cycles_t; - -/* - * For the "cycle" counter we use the timebase lower half. - * Currently only used on SMP. - */ - -extern cycles_t cacheflush_time; - -static inline cycles_t get_cycles(void) -{ - cycles_t ret = 0; - - __asm__ __volatile__( - "98: mftb %0\n" - "99:\n" - ".section __ftr_fixup,\"a\"\n" - " .long %1\n" - " .long 0\n" - " .long 98b\n" - " .long 99b\n" - ".previous" - : "=r" (ret) : "i" (CPU_FTR_601)); - return ret; -} - -#elif defined(__ia64__) -/* ia64 */ - -typedef unsigned long cycles_t; -static inline cycles_t -get_cycles (void) -{ - cycles_t ret; - __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret)); - return ret; -} - -#elif defined(__alpha__) -/* alpha */ - -typedef unsigned int cycles_t; -static inline cycles_t get_cycles (void) -{ - cycles_t ret; - __asm__ __volatile__ ("rpcc %0" : "=r"(ret)); - return ret; -} - -#else -/* generic solution */ - -#warning You are compiling JACK on a platform for which jack/cycles.h needs work -#include - -typedef long cycles_t; -extern cycles_t cacheflush_time; - -static inline cycles_t get_cycles(void) -{ - struct timeval tv; - gettimeofday (&tv, NULL); - - return tv.tv_usec; -} - -#endif - #endif /* __jack_cycles_h__ */ diff --git a/config/cpu/ia64/atomicity.h b/config/cpu/ia64/atomicity.h new file mode 100644 index 00000000..d326a13c --- /dev/null +++ b/config/cpu/ia64/atomicity.h @@ -0,0 +1,51 @@ +// Low-level functions for atomic operations: IA64 version -*- C++ -*- + +// Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#include + +typedef int _Atomic_word; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + return __sync_fetch_and_add(__mem, __val); +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + __sync_fetch_and_add(__mem, __val); +} + +#endif /* atomicity.h */ diff --git a/config/cpu/ia64/cycles.h b/config/cpu/ia64/cycles.h new file mode 100644 index 00000000..52373639 --- /dev/null +++ b/config/cpu/ia64/cycles.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2001 Paul Davis + Code derived from various headers from the Linux kernel + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __jack_cycles_h__ +#define __jack_cycles_h__ + +/* ia64 */ + +typedef unsigned long cycles_t; +static inline cycles_t +get_cycles (void) +{ + cycles_t ret; + __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret)); + return ret; +} + +#endif /* __jack_cycles_h__ */ diff --git a/config/cpu/ia64/ia64intrin.h b/config/cpu/ia64/ia64intrin.h new file mode 100644 index 00000000..262dc20e --- /dev/null +++ b/config/cpu/ia64/ia64intrin.h @@ -0,0 +1,130 @@ +#ifndef _IA64INTRIN_H_INCLUDED +#define _IA64INTRIN_H_INCLUDED + +/* Actually, everything is a compiler builtin, but just so + there's no confusion... */ +#ifdef __cplusplus +extern "C" { +#endif + +extern void __sync_synchronize (void); + +extern int __sync_val_compare_and_swap_si (int *, int, int); +extern long __sync_val_compare_and_swap_di (long *, long, long); +#define __sync_val_compare_and_swap(PTR, OLD, NEW) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) \ + __sync_val_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \ + : (__typeof__(*(PTR))) \ + __sync_val_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW))) + +extern int __sync_bool_compare_and_swap_si (int *, int, int); +extern int __sync_bool_compare_and_swap_di (long *, long, long); +#define __sync_bool_compare_and_swap(PTR, OLD, NEW) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? __sync_bool_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \ + : __sync_bool_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW))) + +extern void __sync_lock_release_si (int *); +extern void __sync_lock_release_di (long *); +#define __sync_lock_release(PTR) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? __sync_lock_release_si((int *)(PTR)) \ + : __sync_lock_release_di((long *)(PTR))) + +extern int __sync_lock_test_and_set_si (int *, int); +extern long __sync_lock_test_and_set_di (long *, long); +#define __sync_lock_test_and_set(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_lock_test_and_set_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_lock_test_and_set_di((long *)(PTR),(long)(VAL))) + +extern int __sync_fetch_and_add_si (int *, int); +extern long __sync_fetch_and_add_di (long *, long); +#define __sync_fetch_and_add(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_fetch_and_add_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_fetch_and_add_di((long *)(PTR),(long)(VAL))) + +extern int __sync_fetch_and_sub_si (int *, int); +extern long __sync_fetch_and_sub_di (long *, long); +#define __sync_fetch_and_sub(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_fetch_and_sub_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_fetch_and_sub_di((long *)(PTR),(long)(VAL))) + +extern int __sync_fetch_and_and_si (int *, int); +extern long __sync_fetch_and_and_di (long *, long); +#define __sync_fetch_and_and(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_fetch_and_and_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_fetch_and_and_di((long *)(PTR),(long)(VAL))) + +extern int __sync_fetch_and_or_si (int *, int); +extern long __sync_fetch_and_or_di (long *, long); +#define __sync_fetch_and_or(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_fetch_and_or_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_fetch_and_or_di((long *)(PTR),(long)(VAL))) + +extern int __sync_fetch_and_xor_si (int *, int); +extern long __sync_fetch_and_xor_di (long *, long); +#define __sync_fetch_and_xor(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_fetch_and_xor_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_fetch_and_xor_di((long *)(PTR),(long)(VAL))) + +extern int __sync_fetch_and_nand_si (int *, int); +extern long __sync_fetch_and_nand_di (long *, long); +#define __sync_fetch_and_nand(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_fetch_and_nand_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_fetch_and_nand_di((long *)(PTR),(long)(VAL))) + +extern int __sync_add_and_fetch_si (int *, int); +extern long __sync_add_and_fetch_di (long *, long); +#define __sync_add_and_fetch(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_add_and_fetch_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_add_and_fetch_di((long *)(PTR),(long)(VAL))) + +extern int __sync_sub_and_fetch_si (int *, int); +extern long __sync_sub_and_fetch_di (long *, long); +#define __sync_sub_and_fetch(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_sub_and_fetch_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_sub_and_fetch_di((long *)(PTR),(long)(VAL))) + +extern int __sync_and_and_fetch_si (int *, int); +extern long __sync_and_and_fetch_di (long *, long); +#define __sync_and_and_fetch(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_and_and_fetch_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_and_and_fetch_di((long *)(PTR),(long)(VAL))) + +extern int __sync_or_and_fetch_si (int *, int); +extern long __sync_or_and_fetch_di (long *, long); +#define __sync_or_and_fetch(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_or_and_fetch_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_or_and_fetch_di((long *)(PTR),(long)(VAL))) + +extern int __sync_xor_and_fetch_si (int *, int); +extern long __sync_xor_and_fetch_di (long *, long); +#define __sync_xor_and_fetch(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_xor_and_fetch_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_xor_and_fetch_di((long *)(PTR),(long)(VAL))) + +extern int __sync_nand_and_fetch_si (int *, int); +extern long __sync_nand_and_fetch_di (long *, long); +#define __sync_nand_and_fetch(PTR,VAL) \ + ((sizeof (*(PTR)) == sizeof(int)) \ + ? (__typeof__(*(PTR))) __sync_nand_and_fetch_si((int *)(PTR),(int)(VAL)) \ + : (__typeof__(*(PTR))) __sync_nand_and_fetch_di((long *)(PTR),(long)(VAL))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/config/cpu/m68k/atomicity.h b/config/cpu/m68k/atomicity.h new file mode 100644 index 00000000..eb801dec --- /dev/null +++ b/config/cpu/m68k/atomicity.h @@ -0,0 +1,139 @@ +// Low-level functions for atomic operations: m68k version -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +typedef int _Atomic_word; + +#if ( defined(__mc68020__) || defined(__mc68030__) \ + || defined(__mc68040__) || defined(__mc68060__) ) \ + && !defined(__mcpu32__) +// These variants support compare-and-swap. + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + register _Atomic_word __result = *__mem; + register _Atomic_word __temp; + __asm__ __volatile__ ("1: move%.l %0,%1\n\t" + "add%.l %3,%1\n\t" + "cas%.l %0,%1,%2\n\t" + "jne 1b" + : "=d" (__result), "=&d" (__temp), "=m" (*__mem) + : "d" (__val), "0" (__result), "m" (*__mem)); + return __result; +} + +#elif defined(__rtems__) + /* + * TAS/JBNE is unsafe on systems with strict priority-based scheduling. + * Disable interrupts, which we can do only from supervisor mode. + */ +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __result; + short __level, __tmpsr; + __asm__ __volatile__ ("move%.w %%sr,%0\n\tor%.l %0,%1\n\tmove%.w %1,%%sr" + : "=d"(__level), "=d"(__tmpsr) : "1"(0x700)); + + __result = *__mem; + *__mem = __result + __val; + + __asm__ __volatile__ ("move%.w %0,%%sr" : : "d"(__level)); + + return __result; +} + +#else + +template + struct __Atomicity_lock + { + static volatile unsigned char _S_atomicity_lock; + }; + +template +volatile unsigned char __Atomicity_lock<__inst>::_S_atomicity_lock = 0; + +template volatile unsigned char __Atomicity_lock<0>::_S_atomicity_lock; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __result; + +// bset with no immediate addressing (not SMP-safe) +#if defined(__mcf5200__) || defined(__mcf5300__) + __asm__ __volatile__("1: bset.b #7,%0@\n\tjbne 1b" + : /* no outputs */ + : "a"(&__Atomicity_lock<0>::_S_atomicity_lock) + : "cc", "memory"); + +// CPU32 and MCF5400 support test-and-set (SMP-safe). +#elif defined(__mcpu32__) || defined(__mcf5400__) + __asm__ __volatile__("1: tas %0\n\tjbne 1b" + : "+m"(__Atomicity_lock<0>::_S_atomicity_lock) + : /* none */ + : "cc"); + +// Use bset with immediate addressing for 68000/68010 (not SMP-safe) +// NOTE: TAS is available on the 68000, but unsupported by some Amiga +// memory controllers. +#else + __asm__ __volatile__("1: bset.b #7,%0\n\tjbne 1b" + : "+m"(__Atomicity_lock<0>::_S_atomicity_lock) + : /* none */ + : "cc"); +#endif + + __result = *__mem; + *__mem = __result + __val; + + __Atomicity_lock<0>::_S_atomicity_lock = 0; + + return __result; +} + +#endif /* TAS / BSET */ + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + // Careful: using add.l with a memory destination is not + // architecturally guaranteed to be atomic. + (void) __exchange_and_add(__mem, __val); +} + +#endif /* !_GLIBCXX_ATOMICITY_H */ diff --git a/config/cpu/mips/atomicity.h b/config/cpu/mips/atomicity.h new file mode 100644 index 00000000..3d0c7a10 --- /dev/null +++ b/config/cpu/mips/atomicity.h @@ -0,0 +1,83 @@ +// Low-level functions for atomic operations. + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +typedef int _Atomic_word; + +static inline int +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + int __result, __tmp; + + __asm__ __volatile__ + ("/* Inline exchange & add */\n\t" + "1:\n\t" + ".set push\n\t" +#if _MIPS_SIM == _ABIO32 + ".set mips2\n\t" +#endif + "ll %0,%3\n\t" + "addu %1,%4,%0\n\t" + "sc %1,%2\n\t" + ".set pop\n\t" + "beqz %1,1b\n\t" + "/* End exchange & add */" + : "=&r"(__result), "=&r"(__tmp), "=m"(*__mem) + : "m" (*__mem), "r"(__val)); + + return __result; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + int __result; + + __asm__ __volatile__ + ("/* Inline atomic add */\n\t" + "1:\n\t" + ".set push\n\t" +#if _MIPS_SIM == _ABIO32 + ".set mips2\n\t" +#endif + "ll %0,%2\n\t" + "addu %0,%3,%0\n\t" + "sc %0,%1\n\t" + ".set pop\n\t" + "beqz %0,1b\n\t" + "/* End atomic add */" + : "=&r"(__result), "=m"(*__mem) + : "m" (*__mem), "r"(__val)); +} + +#endif /* atomicity.h */ diff --git a/config/cpu/powerpc/atomicity.h b/config/cpu/powerpc/atomicity.h new file mode 100644 index 00000000..3b44b7da --- /dev/null +++ b/config/cpu/powerpc/atomicity.h @@ -0,0 +1,78 @@ +// Low-level functions for atomic operations: PowerPC version -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#ifdef __PPC405__ +#define _STWCX "sync \n\tstwcx. " +#else +#define _STWCX "stwcx. " +#endif + +typedef int _Atomic_word; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __tmp, __res; + __asm__ __volatile__ ( + "/* Inline exchange & add */\n" + "0:\t" + "lwarx %0,0,%3 \n\t" + "add%I4 %1,%0,%4 \n\t" + _STWCX " %1,0,%3 \n\t" + "bne- 0b \n\t" + "/* End exchange & add */" + : "=&b"(__res), "=&r"(__tmp), "=m" (*__mem) + : "r" (__mem), "Ir"(__val), "m" (*__mem) + : "cr0"); + return __res; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __tmp; + __asm__ __volatile__ ( + "/* Inline atomic add */\n" + "0:\t" + "lwarx %0,0,%2 \n\t" + "add%I3 %0,%0,%3 \n\t" + _STWCX " %0,0,%2 \n\t" + "bne- 0b \n\t" + "/* End atomic add */" + : "=&b"(__tmp), "=m" (*__mem) + : "r" (__mem), "Ir"(__val), "m" (*__mem) + : "cr0"); +} + +#endif /* atomicity.h */ diff --git a/config/cpu/powerpc/cycles.h b/config/cpu/powerpc/cycles.h new file mode 100644 index 00000000..84486d49 --- /dev/null +++ b/config/cpu/powerpc/cycles.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2001 Paul Davis + Code derived from various headers from the Linux kernel + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __jack_cycles_h__ +#define __jack_cycles_h__ + +/* PowerPC */ + +#define CPU_FTR_601 0x00000100 + +typedef unsigned long cycles_t; + +/* + * For the "cycle" counter we use the timebase lower half. + * Currently only used on SMP. + */ + +extern cycles_t cacheflush_time; + +static inline cycles_t get_cycles(void) +{ + cycles_t ret = 0; + + __asm__ __volatile__( + "98: mftb %0\n" + "99:\n" + ".section __ftr_fixup,\"a\"\n" + " .long %1\n" + " .long 0\n" + " .long 98b\n" + " .long 99b\n" + ".previous" + : "=r" (ret) : "i" (CPU_FTR_601)); + return ret; +} + +#endif /* __jack_cycles_h__ */ diff --git a/config/cpu/s390/atomicity.h b/config/cpu/s390/atomicity.h new file mode 100644 index 00000000..8647c763 --- /dev/null +++ b/config/cpu/s390/atomicity.h @@ -0,0 +1,60 @@ +// Low-level functions for atomic operations: S/390 version -*- C++ -*- + +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +typedef int _Atomic_word; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + register _Atomic_word __old_val, __new_val; + + __asm__ __volatile__ (" l %0,0(%3)\n" + "0: lr %1,%0\n" + " ar %1,%4\n" + " cs %0,%1,0(%3)\n" + " jl 0b" + : "=&d" (__old_val), "=&d" (__new_val), "=m" (*__mem) + : "a" (__mem), "d" (__val), "m" (*__mem) : "cc"); + return __old_val; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + __exchange_and_add(__mem, __val); +} + +#endif /* atomicity.h */ + + diff --git a/config/cpu/sparc/atomicity.h b/config/cpu/sparc/atomicity.h new file mode 100644 index 00000000..2db079c9 --- /dev/null +++ b/config/cpu/sparc/atomicity.h @@ -0,0 +1,131 @@ +// Low-level functions for atomic operations: Sparc version -*- C++ -*- + +// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#ifdef __arch64__ + +typedef long _Atomic_word; + +static inline _Atomic_word +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __tmp1, __tmp2; + _Atomic_word __val_extended = __val; + + __asm__ __volatile__("1: ldx [%3], %0\n\t" + " add %0, %4, %1\n\t" + " casx [%3], %0, %1\n\t" + " sub %0, %1, %0\n\t" + " brnz,pn %0, 1b\n\t" + " nop" + : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem) + : "r" (__mem), "r" (__val_extended), "m" (*__mem)); + return __tmp2; +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __tmp1, __tmp2; + _Atomic_word __val_extended = __val; + + __asm__ __volatile__("1: ldx [%3], %0\n\t" + " add %0, %4, %1\n\t" + " casx [%3], %0, %1\n\t" + " sub %0, %1, %0\n\t" + " brnz,pn %0, 1b\n\t" + " nop" + : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__mem) + : "r" (__mem), "r" (__val_extended), "m" (*__mem)); +} + +#else /* __arch32__ */ + +typedef int _Atomic_word; + +template + struct __Atomicity_lock + { + static unsigned char _S_atomicity_lock; + }; + +template +unsigned char __Atomicity_lock<__inst>::_S_atomicity_lock = 0; + +template unsigned char __Atomicity_lock<0>::_S_atomicity_lock; + +static int +__attribute__ ((__unused__)) +__exchange_and_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __result, __tmp; + + __asm__ __volatile__("1: ldstub [%1], %0\n\t" + " cmp %0, 0\n\t" + " bne 1b\n\t" + " nop" + : "=&r" (__tmp) + : "r" (&__Atomicity_lock<0>::_S_atomicity_lock) + : "memory"); + __result = *__mem; + *__mem += __val; + __asm__ __volatile__("stb %%g0, [%0]" + : /* no outputs */ + : "r" (&__Atomicity_lock<0>::_S_atomicity_lock) + : "memory"); + return __result; +} + +static void +__attribute__ ((__unused__)) +__atomic_add(volatile _Atomic_word* __mem, int __val) +{ + _Atomic_word __tmp; + + __asm__ __volatile__("1: ldstub [%1], %0\n\t" + " cmp %0, 0\n\t" + " bne 1b\n\t" + " nop" + : "=&r" (__tmp) + : "r" (&__Atomicity_lock<0>::_S_atomicity_lock) + : "memory"); + *__mem += __val; + __asm__ __volatile__("stb %%g0, [%0]" + : /* no outputs */ + : "r" (&__Atomicity_lock<0>::_S_atomicity_lock) + : "memory"); +} + +#endif /* __arch32__ */ + +#endif /* atomicity.h */ diff --git a/config/os/aix/atomicity.h b/config/os/aix/atomicity.h new file mode 100644 index 00000000..af4fa5a8 --- /dev/null +++ b/config/os/aix/atomicity.h @@ -0,0 +1,59 @@ +// Low-level functions for atomic operations: AIX version -*- C++ -*- + +// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BITS_ATOMICITY_H +#define _BITS_ATOMICITY_H 1 + +/* We cannot use the cpu/powerpc/bits/atomicity.h inline assembly + definitions for these operations since they depend on operations + that are not available on the original POWER architecture. AIX + still runs on the POWER architecture, so it would be incorrect to + assume the existence of these instructions. */ + +/* This should match the type pointed to by atomic_p in + . */ +typedef int _Atomic_word; + +#include + +static inline int +__attribute__ ((__unused__)) +__exchange_and_add (atomic_p __mem, int __val) +{ + return fetch_and_add (__mem, __val); +} + +static inline void +__attribute__ ((__unused__)) +__atomic_add (atomic_p __mem, int __val) +{ + (void) fetch_and_add (__mem, __val); +} + +#endif /* atomicity.h */ diff --git a/config/os/generic/ipc.h b/config/os/generic/ipc.h new file mode 100644 index 00000000..bc128c08 --- /dev/null +++ b/config/os/generic/ipc.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2004 Jack O'Quin + + Generic version, overridden by OS-specific defines when needed. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ + +#ifndef _jack_sys_ipc +#define _jack_sys_ipc 1 + +#include + +#endif /* _jack_sys_ipc */ diff --git a/config/os/generic/os_defines.h b/config/os/generic/os_defines.h new file mode 100644 index 00000000..456137a3 --- /dev/null +++ b/config/os/generic/os_defines.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2004 Jack O'Quin + + Generic version, overridden by OS-specific defines when available. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ + +#ifndef _jack_os_defines +#define _jack_os_defines 1 + +#define JACK_THREAD_STACK_TOUCH 1048576 +#define PORTAUDIO_H +#define GETOPT_H + +#endif /* _jack_os_defines */ diff --git a/config/os/generic/poll.h b/config/os/generic/poll.h new file mode 100644 index 00000000..38371348 --- /dev/null +++ b/config/os/generic/poll.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2004 Jack O'Quin + + Generic version, overridden by OS-specific defines when needed. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ + +#ifndef _jack_sys_poll +#define _jack_sys_poll 1 + +#include + +#endif /* _jack_sys_poll */ diff --git a/config/os/generic/time.h b/config/os/generic/time.h new file mode 100644 index 00000000..5a7ea49f --- /dev/null +++ b/config/os/generic/time.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2004 Jack O'Quin + + Generic version, overridden by OS-specific defines when available. + In this case, that is necessary, because the generic version + hasn't been written, yet. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ +#ifndef __jack_time_h__ +#define __jack_time_h__ + +#include + +#error No generic available. + +/* This is a kludge. We need one global instantiation of this + * variable in each address space. So, libjack/client.c declares the + * actual storage. Other source files will see it as an extern. */ +#define JACK_TIME_GLOBAL_DECL jack_time_t __jack_cpu_mhz +extern JACK_TIME_GLOBAL_DECL; + +/* Need implementations. jack_init_time() should only be called ONCE + * per process. */ +static inline jack_time_t jack_get_microseconds (void); +static inline void jack_init_time (void); + +#endif /* __jack_time_h__ */ diff --git a/config/os/gnu-linux/time.h b/config/os/gnu-linux/time.h new file mode 100644 index 00000000..033d4a61 --- /dev/null +++ b/config/os/gnu-linux/time.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2001-2003 Paul Davis + + This is the GNU/Linux version. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ +#ifndef __jack_time_h__ +#define __jack_time_h__ + +#include +#include +#include + +/* This is a kludge. We need one global instantiation of this + * variable in each address space. So, libjack/client.c declares the + * actual storage. Other source files will see it as an extern. */ +#define JACK_TIME_GLOBAL_DECL jack_time_t __jack_cpu_mhz +extern JACK_TIME_GLOBAL_DECL; + +static inline jack_time_t +jack_get_microseconds (void) { + return get_cycles() / __jack_cpu_mhz; +} + +/* + * This is another kludge. It looks CPU-dependent, but actually it + * reflects the lack of standards for the Linux kernel formatting of + * /proc/cpuinfo. + */ +static inline jack_time_t +jack_get_mhz (void) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + if (f == 0) + { + perror("can't open /proc/cpuinfo\n"); + exit(1); + } + + for ( ; ; ) + { + jack_time_t mhz; + int ret; + char buf[1000]; + + if (fgets(buf, sizeof(buf), f) == NULL) { + jack_error ("FATAL: cannot locate cpu MHz in " + "/proc/cpuinfo\n"); + exit(1); + } + +#if defined(__powerpc__) + ret = sscanf(buf, "clock\t: %" SCNu64 "MHz", &mhz); +#elif defined( __i386__ ) || defined (__hppa__) || defined (__ia64__) || \ + defined(__x86_64__) + ret = sscanf(buf, "cpu MHz : %" SCNu64, &mhz); +#elif defined( __sparc__ ) + ret = sscanf(buf, "Cpu0Bogo : %" SCNu64, &mhz); +#elif defined( __mc68000__ ) + ret = sscanf(buf, "Clocking: %" SCNu64, &mhz); +#elif defined( __s390__ ) + ret = sscanf(buf, "bogomips per cpu: %" SCNu64, &mhz); +#else /* MIPS, ARM, alpha */ + ret = sscanf(buf, "BogoMIPS : %" SCNu64, &mhz); +#endif + + if (ret == 1) + { + fclose(f); + return (jack_time_t)mhz; + } + } +} + +/* This should only be called ONCE per process. */ +static inline void +jack_init_time () +{ + __jack_cpu_mhz = jack_get_mhz (); +} + +#endif /* __jack_time_h__ */ diff --git a/config/os/irix/atomicity.h b/config/os/irix/atomicity.h new file mode 100644 index 00000000..c7f5c83f --- /dev/null +++ b/config/os/irix/atomicity.h @@ -0,0 +1,50 @@ +// Low-level functions for atomic operations: IRIX version -*- C++ -*- + +// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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, 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _BITS_ATOMICITY_H +#define _BITS_ATOMICITY_H 1 + +#include + +typedef long _Atomic_word; + +static inline _Atomic_word +__exchange_and_add (_Atomic_word* __mem, int __val) +{ + return (_Atomic_word) test_then_add ((unsigned long*) __mem, __val); +} + + +static inline void +__atomic_add (_Atomic_word* __mem, int __val) +{ + __exchange_and_add (__mem, __val); +} + +#endif /* atomicity.h */ diff --git a/config/os/macosx/README b/config/os/macosx/README new file mode 100644 index 00000000..33f5692e --- /dev/null +++ b/config/os/macosx/README @@ -0,0 +1,183 @@ + +Darwin/MacOSX port for Jack : architecture changes in the implementation +======================================================================== + +Build Dependencies +================== + +Apple Developer Tools + gcc 2.95.x or 3.x, the standard OSX 10.3 gcc-3.3 compiler works fine + MacOSX10.3 SDK package + +GNU tools + autoconf >= 2.57 + automake >= 1.6.3 + +optional tools + libtool >= 1.5 (to build from CVS) + pkg-config >= 0.15.0 (to build from CVS) + doxygen (to build documentation) + libsndfile >= 1.0.0 (for some example-clients) + GNU readline (for some example-clients) + +All non-Apple tools are available from `fink' or `darwinports'. + +Since fink is not well-integrated with OS X, you must define a bunch +of environment variables... + + export ACLOCAL_FLAGS="-I /sw/share/aclocal" + export CFLAGS="-I/sw/include" + export CPPFLAGS=$CFLAGS + export LDFLAGS="-L/sw/lib" + export PKG_CONFIG_PATH="/sw/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/opt/local/lib/pkgconfig" + + +Shared memory +============= + +The system V shared memory is not very reliable on Darwin/MacOSX, so +POSIX shared memory API is the preferred default. To override, use... + + ./configure --disable-posix-shm + + +Jack server audio cycle +======================== + +On Linux, the jack server audio cycle (jack_run_cycle function) is +called in a real-time SCHED_FIFO thread. On Darwin/MacOSX, the +jack_run_cycle is directly called inside the CoreAudio audio callback. + + +External client activation +=========================== + +Jack Linux implementation use system fifo/pipe to trigger the clients +real-time callback from the server : the first client of an external +subgraph is triggered, does it's job and wakes up the next one in the +list, and so on until the last client that wakes up the Jack +server. This avoid uneeded context switches between the server and +clients and thus is more efficient. + +This Linux implementation works also on Darwin/MacOSX but is not very +efficient : audio gliches occur quite frequently. + +A more efficient system for external client activation has been +developed. It use low-level mach messages system to implement fast IPC +between the Jack server and the running clients. The Darwin/MacOSX has +a very efficient Remote Procedure Call (RPC) implementation that can +be used: the Jack server activate each external client in turn in a +loop. + +On the client side, each client uses an additionnal thread only used +for the real-time process callback, that will be triggered by the Jack +server using this fast RPC mechanism. + + +Real-time threads +================== + +The Darwin/MacOSX system use a special class of scheduling for +real-time threads. + +Since the server audio cycle is called directly from the CoreAudio +callback, there is nothing special to do on the server side. On the +client side, the thread used to call the "process" callback from the +server is made real-time, using the mach thread API. + + +Compilation and installation +============================= + +- In the jack/jack folder, you'll have to produce the version.h +manually from the version.h.in file ): Edit the version.h.in, replace +the JACK_PROTOCOL_VERSION value with the one found in configure.in and +save as a new version.h file. You should get something like "#define +jack_protocol_version 6" in the file. + +Several packages need to be installed before compiling Jack : + +- Fink dlcompat (fink.sourceforge.net) : this package define the +dlopen, dlsym... API used in Jack to load drivers and internal +clients. The package has to be installed before compiling Jack. + +- fakepoll is a implementation of the poll function using select. The +Fink version of poll does not work correctly, thus the public domain +"fakepoll" code has been used instead. It is directly included in the +Jack Darwin/MacOSX port. + +- PortAudio (www.portaudio.com) : PortAudio is a free, cross platform, +open-source, audio I/O library. The Jack CoreAudio driver actually is +implemented using PortAudio. The PortAudio source code for MacOSX has +to be installed and compiled to produce a framework called +"PortAudio.framework" that will be used in the Jack link phase. + + +Several targets are available in the Project Builder project : + +- jackd : build the Jack server ("jackd" executable) +- jack framework : build the "Jack.framework" library. +- driver : build the PortAudio driver as a "jack_portaudio.so" shared library. +- jack_metro : build the "jack_metro" executable. +- jack_lsp : build the "jack_lsp" executable. +- jack_connect : build the "jack_connect" executable. +- jack_disconnect : build the "jack_disconnect" executable. + +Server, driver and library installation : +----------------------------------------- + +First copy the Jack.framework in /Library/Framework. Then as root : + + # cp jack_portaudio /usr/local/lib + # cp jackd /usr/local/bin + +Launching Jack server : +----------------------- + +By default buffer size is 128 frames and sample rate is 44100. + + $ jackd -v -R -d coreaudio + +To setup a 32 frames buffer and a 4800 Hz sample rate : + + $ jackd -v -R -d coreaudio -p 32 -r 48000 + +Performances +============= + +The Darwin/MacOSX implementation is quite efficient: on a G4/867 Mhz, +the Jack server can run with a 32 frames buffer size without noticable +problems. + + +Known problems or unimplemented features +========================================= + +- thread cancellation : the pthread API pthread_cancel is not +completely available on Darwin/MacOSX. Thread cannot be cancelled in +the general case: they must use explicit cancelation points like +"pthread_testcancel" (see the "jack_client_thread" function) + +- xruns detection and report: not implemented. + + +Possible improvements +====================== + +- The audio driver is built on top of PortAudio. It may be more +efficient to directly use the CoreAudio API in order to avoid +additional buffer copy and interleaving/disinterleaving operations. + +- The project uses Project Builder. It would be helpful to work on +the autoconf and automake tools as the Linux version. In this case, +the macosx/config.h file would have to be removed and generated by +configure, and jack/version.h will be generated automatically from +jack/version.h.in + +- Better separation of Linux and Darwin/MacOSX only code. + +The Jack port for Darwin/MacOSX version has be done by: + +Grame Research Laboratory +9, rue du Garet 69001 Lyon - France +Mail : letz@grame.fr diff --git a/macosx/fakepoll.c b/config/os/macosx/fakepoll.h old mode 100755 new mode 100644 similarity index 99% rename from macosx/fakepoll.c rename to config/os/macosx/fakepoll.h index 2d099598..e3f43453 --- a/macosx/fakepoll.c +++ b/config/os/macosx/fakepoll.h @@ -17,7 +17,6 @@ #define _FAKE_POLL_H #include -#define FD_SETSIZE OPEN_MAX #include #include #include diff --git a/macosx/getopt.h b/config/os/macosx/getopt.h old mode 100755 new mode 100644 similarity index 77% rename from macosx/getopt.h rename to config/os/macosx/getopt.h index d3ca89d3..7275c597 --- a/macosx/getopt.h +++ b/config/os/macosx/getopt.h @@ -19,13 +19,4 @@ grame@rd.grame.fr */ -/* Replacement for getopt_long */ - -#include -#define getopt_long(a,b,c,d,e) getopt(a,b,c) -struct option { - const char *name; - enum { required_argument, no_argument } arg; - void *unused; - char val; -}; \ No newline at end of file +#include "/Developer/SDKs/MacOSX10.3.0.sdk/usr/include/getopt.h" diff --git a/macosx/ipc.c b/config/os/macosx/ipc.h similarity index 65% rename from macosx/ipc.c rename to config/os/macosx/ipc.h index 02b1e3f0..621196ea 100644 --- a/macosx/ipc.c +++ b/config/os/macosx/ipc.h @@ -19,27 +19,57 @@ grame@rd.grame.fr */ -#include "ipc.h" +#ifndef __ipc__ +#define __ipc__ + +#include +#include +#include +#include +#include /* JOQ: fix me */ + +/* + Copyright © Grame 2003 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France + grame@rd.grame.fr +*/ /* - RPC without time out can put the jack server in a blocked state (waiting for the client answer) when a client is killed. - The mach_msg function does not return any error in this case. Using time out solve the problem but does not seems really - satisfactory. + RPC without time out can put the jack server in a blocked state + (waiting for the client answer) when a client is killed. The + mach_msg function does not return any error in this case. Using + time out solve the problem but does not seems really satisfactory. */ #define WAIT 25 /* in millisecond */ - -int +static inline int jack_client_resume(jack_client_internal_t *client) { mach_msg_header_t *head = &client->message.header; int err; if (!client->running) { - err = mach_msg (head, MACH_RCV_MSG, 0, sizeof(client->message), client->serverport, 0, MACH_PORT_NULL); + err = mach_msg (head, MACH_RCV_MSG, 0, sizeof(client->message), + client->serverport, 0, MACH_PORT_NULL); if (err) { - jack_error("jack_client_resume: priming receive error: %s\n", mach_error_string(err)); + jack_error("jack_client_resume: priming receive error: %s\n", + mach_error_string(err)); return -1; } client->running = TRUE; @@ -49,28 +79,34 @@ jack_client_resume(jack_client_internal_t *client) head->msgh_local_port = MACH_PORT_NULL; head->msgh_size = sizeof(mach_msg_header_t); - err = mach_msg(head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_SEND_TIMEOUT|MACH_RCV_TIMEOUT, - sizeof(*head), sizeof(client->message), client->serverport, WAIT, MACH_PORT_NULL); + err = mach_msg(head, (MACH_SEND_MSG|MACH_RCV_MSG| + MACH_SEND_TIMEOUT|MACH_RCV_TIMEOUT), + sizeof(*head), sizeof(client->message), + client->serverport, WAIT, MACH_PORT_NULL); if (err) { /* switch(err) { case MACH_SEND_TIMED_OUT: - jack_error("MACH_SEND_TIMED_OUT %s\n", client->control->name); + jack_error("MACH_SEND_TIMED_OUT %s\n", + client->control->name); break; case MACH_RCV_TIMED_OUT: - jack_error("MACH_RCV_TIMED_OUT %s\n", client->control->name); + jack_error("MACH_RCV_TIMED_OUT %s\n", + client->control->name); break; case MACH_SEND_INVALID_DEST: - jack_error("MACH_SEND_INVALID_DEST %s\n", client->control->name); + jack_error("MACH_SEND_INVALID_DEST %s\n", + client->control->name); break; } */ - jack_error("jack_client_resume: send error for %s\n", mach_error_string(err)); + jack_error("jack_client_resume: send error for %s\n", + mach_error_string(err)); return err; } } @@ -78,39 +114,44 @@ jack_client_resume(jack_client_internal_t *client) return 0; } -int +static inline int jack_client_suspend(jack_client_t * client) { int err = 0; mach_msg_header_t * head = &client->message.header; - head->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,MACH_MSG_TYPE_MAKE_SEND_ONCE); + head->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, + MACH_MSG_TYPE_MAKE_SEND_ONCE); head->msgh_remote_port = client->serverport; head->msgh_local_port = client->replyport; head->msgh_size = sizeof(mach_msg_header_t); err = mach_msg(head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_SEND_TIMEOUT, - sizeof(mach_msg_header_t), sizeof(client->message), client->replyport, WAIT, MACH_PORT_NULL); + sizeof(mach_msg_header_t), sizeof(client->message), + client->replyport, WAIT, MACH_PORT_NULL); if (err) { - jack_error("jack_client_suspend: RPC error: %s\n", mach_error_string(err)); + jack_error("jack_client_suspend: RPC error: %s\n", + mach_error_string(err)); return -1; } return 0; } -void +static inline void allocate_mach_serverport(jack_engine_t * engine, jack_client_internal_t *client) { char buf[256]; snprintf(buf, 256, "JackMachPort_%d", engine->portnum); - if (mach_port_allocate(engine->servertask, MACH_PORT_RIGHT_RECEIVE, &client->serverport)){ + if (mach_port_allocate(engine->servertask, MACH_PORT_RIGHT_RECEIVE, + &client->serverport)){ jack_error("allocate_mach_serverport: can't allocate mach port"); } - if (mach_port_insert_right(engine->servertask, client->serverport, client->serverport, MACH_MSG_TYPE_MAKE_SEND)){ + if (mach_port_insert_right(engine->servertask, client->serverport, + client->serverport, MACH_MSG_TYPE_MAKE_SEND)){ jack_error("allocate_mach_serverport: error inserting mach rights"); } @@ -122,7 +163,7 @@ allocate_mach_serverport(jack_engine_t * engine, jack_client_internal_t *client) engine->portnum++; } -int +static inline int allocate_mach_clientport(jack_client_t * client, int portnum) { char buf[256]; @@ -133,7 +174,8 @@ allocate_mach_clientport(jack_client_t * client, int portnum) return -1; } - if (mach_port_allocate(client->clienttask, MACH_PORT_RIGHT_RECEIVE, &client->replyport)){ + if (mach_port_allocate(client->clienttask, MACH_PORT_RIGHT_RECEIVE, + &client->replyport)){ jack_error("allocate_mach_clientport: can't allocate mach port"); return -1; } @@ -141,4 +183,4 @@ allocate_mach_clientport(jack_client_t * client, int portnum) return 0; } - +#endif /* __ipc__ */ diff --git a/macosx/jack.pbproj/project.pbxproj b/config/os/macosx/jack.xcode/project.pbxproj old mode 100755 new mode 100644 similarity index 58% rename from macosx/jack.pbproj/project.pbxproj rename to config/os/macosx/jack.xcode/project.pbxproj index 41444daf..a76e7d05 --- a/macosx/jack.pbproj/project.pbxproj +++ b/config/os/macosx/jack.xcode/project.pbxproj @@ -3,14 +3,19 @@ archiveVersion = 1; classes = { }; - objectVersion = 38; + objectVersion = 39; objects = { 014CEA520018CE5811CA2923 = { buildRules = ( ); buildSettings = { COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; OPTIMIZATION_CFLAGS = "-O0"; + ZERO_LINK = YES; }; isa = PBXBuildStyle; name = Development; @@ -20,6 +25,8 @@ ); buildSettings = { COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + ZERO_LINK = NO; }; isa = PBXBuildStyle; name = Deployment; @@ -35,9 +42,12 @@ //033 //034 034768E8FF38A79811DB9C8B = { + explicitFileType = "compiled.mach-o.executable"; + fallbackIsa = PBXFileReference; isa = PBXExecutableFileReference; path = jackd; refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; }; //030 //031 @@ -50,6 +60,8 @@ //083 //084 08FB7793FE84155DC02AAC07 = { + buildSettings = { + }; buildStyles = ( 014CEA520018CE5811CA2923, 014CEA530018CE5811CA2923, @@ -66,7 +78,6 @@ 4BF8712F040BDE8200053105, 4BA1CB000470D38800053105, 4BA1E4570442D99D00053105, - 4BB3FC31048B7EF000053105, ); }; 08FB7794FE84155DC02AAC07 = { @@ -82,19 +93,22 @@ isa = PBXGroup; name = jackd; refType = 4; + sourceTree = ""; }; 08FB7795FE84155DC02AAC07 = { children = ( - 4B6BFD45042B4E4D00053105, - 4B813E0D0406ACEE00053105, - 4B813E110406AD4900053105, - 4B813E120406AD4900053105, - 4BB407B0044DB8EF00053105, - 4BB3416604D5115900053105, + 4B117C6305DD0C8000B5DA5A, + 4B117C6605DD0C8700B5DA5A, + 4B117C6905DD0C8D00B5DA5A, + 4B117C6C05DD0C9400B5DA5A, + 4B117C6F05DD0C9900B5DA5A, + 4B117C7205DD0C9D00B5DA5A, + 4B117C7505DD0CA000B5DA5A, ); isa = PBXGroup; name = Client; refType = 4; + sourceTree = ""; }; 08FB779FFE84155DC02AAC07 = { buildPhases = ( @@ -106,11 +120,10 @@ ); buildSettings = { FRAMEWORK_SEARCH_PATHS = ""; - HEADER_SEARCH_PATHS = "../ /sw/include"; + HEADER_SEARCH_PATHS = "../../../ ../../"; INSTALL_PATH = "$(HOME)/bin"; - LIBRARY_SEARCH_PATHS = /sw/lib; + LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-O3"; - OTHER_CFLAGS = "-Ddlsym=dlsym_auto_underscore"; OTHER_LDFLAGS = "-framework CoreAudio -ldl "; OTHER_REZFLAGS = ""; PRODUCT_NAME = jackd; @@ -121,7 +134,7 @@ dependencies = ( ); isa = PBXToolTarget; - name = jackd; + name = Jackd; productInstallPath = "$(HOME)/bin"; productName = jackd; productReference = 034768E8FF38A79811DB9C8B; @@ -129,30 +142,17 @@ 08FB77A0FE84155DC02AAC07 = { buildActionMask = 2147483647; files = ( - 4BA7173304090368004F4E3A, - 4BA7173404090369004F4E3A, - 4BA7173504090369004F4E3A, - 4BA717370409036A004F4E3A, - 4BA717380409036B004F4E3A, - 4BA717390409036C004F4E3A, - 4BA7173A0409036C004F4E3A, - 4BA7173B0409036D004F4E3A, - 4BA7173C0409036D004F4E3A, - 4BA7173D0409036E004F4E3A, - 4BA7173E0409036F004F4E3A, - 4BA7173F0409036F004F4E3A, - 4BA7174004090370004F4E3A, - 4BA7174104090370004F4E3A, - 4BA7174204090371004F4E3A, - 4BA7174304090372004F4E3A, - 4B6BFD3E042B26F800053105, - 4B6BFD42042B274900053105, 4B16FF920467B5A000053105, 4BB9E095046FADED00053105, 4B5B51EE047D353A00053105, 4BAA76A7047E0D5200053105, - 4BA74631048BC86900053105, 4B783E1B049F824D00053105, + 4B117C7B05DD0CC000B5DA5A, + 4B4DCBA205DD234100DC3452, + 4B4DCBA505DD234800DC3452, + 4B4DCBA805DD235B00DC3452, + 4BA39A1F05DD2C63008919E8, + 4BA39A2305DD2CA5008919E8, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -160,17 +160,16 @@ 08FB77A1FE84155DC02AAC07 = { buildActionMask = 2147483647; files = ( - 4B63C61404092FC90030C2C8, - 4BD69BCE040A860400053105, - 4BD69BCF040A860800053105, - 4B032A1E040AA1B000053105, - 4B032A26040AA3D200053105, - 4B6CBA45041F50C600053105, - 4BE14029041FB98500053105, - 4B6BFD46042B4E4D00053105, - 4BB407B2044DB8EF00053105, - 4B5B51ED047D353A00053105, - 4BB3416204D5113A00053105, + 4B117C5905DD0C3600B5DA5A, + 4B117C5B05DD0C4100B5DA5A, + 4B117C5E05DD0C5B00B5DA5A, + 4B117C6405DD0C8000B5DA5A, + 4B117C6705DD0C8700B5DA5A, + 4B117C6A05DD0C8D00B5DA5A, + 4B117C6D05DD0C9400B5DA5A, + 4B117C7005DD0C9900B5DA5A, + 4B117C7305DD0C9D00B5DA5A, + 4B117C7605DD0CA000B5DA5A, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -208,11 +207,11 @@ 4BA1E4580442D99D00053105, 4BA1CADF0470D14500053105, 4BA1CB010470D38800053105, - 4BB3FC32048B7EF000053105, ); isa = PBXGroup; name = Products; refType = 4; + sourceTree = ""; }; //1A0 //1A1 @@ -224,289 +223,521 @@ //4B2 //4B3 //4B4 - 4B032A1E040AA1B000053105 = { - fileRef = 4B813E0D0406ACEE00053105; + 4B099343041FB67A00053105 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = fakepoll.h; + refType = 4; + sourceTree = ""; + }; + 4B117C5805DD0C3600B5DA5A = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = jackd.c; + path = ../../../jackd/jackd.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B117C5905DD0C3600B5DA5A = { + fileRef = 4B117C5805DD0C3600B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B032A26040AA3D200053105 = { - fileRef = 4B813E110406AD4900053105; + 4B117C5A05DD0C4100B5DA5A = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = engine.c; + path = ../../../jackd/engine.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B117C5B05DD0C4100B5DA5A = { + fileRef = 4B117C5A05DD0C4100B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B032A29040AA91C00053105 = { - fileRef = 4B813E0F0406AD3100053105; + 4B117C5C05DD0C4100B5DA5A = { + fileRef = 4B117C5A05DD0C4100B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B032A2B040AA94B00053105 = { - fileRef = 4B813E0D0406ACEE00053105; + 4B117C5D05DD0C5B00B5DA5A = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = transengine.c; + path = ../../../jackd/transengine.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B117C5E05DD0C5B00B5DA5A = { + fileRef = 4B117C5D05DD0C5B00B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B032A2C040AA95400053105 = { - fileRef = 4B813E110406AD4900053105; + 4B117C5F05DD0C5B00B5DA5A = { + fileRef = 4B117C5D05DD0C5B00B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B032A3E040AB68E00053105 = { + 4B117C6305DD0C8000B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - name = simple_client.c; - path = "../example-clients/simple_client.c"; + lastKnownFileType = sourcecode.c.c; + name = port.c; + path = ../../../libjack/port.c; refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B117C6405DD0C8000B5DA5A = { + fileRef = 4B117C6305DD0C8000B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B117C6505DD0C8000B5DA5A = { + fileRef = 4B117C6305DD0C8000B5DA5A; + isa = PBXBuildFile; + settings = { + }; }; - 4B099342041FB67A00053105 = { + 4B117C6605DD0C8700B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - path = fakepoll.c; - refType = 4; + lastKnownFileType = sourcecode.c.c; + name = pool.c; + path = ../../../libjack/pool.c; + refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B099343041FB67A00053105 = { + 4B117C6705DD0C8700B5DA5A = { + fileRef = 4B117C6605DD0C8700B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B117C6805DD0C8700B5DA5A = { + fileRef = 4B117C6605DD0C8700B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B117C6905DD0C8D00B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - path = fakepoll.h; - refType = 4; + lastKnownFileType = sourcecode.c.c; + name = driver.c; + path = ../../../libjack/driver.c; + refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B099348041FB67A00053105 = { - fileRef = 4B099342041FB67A00053105; + 4B117C6A05DD0C8D00B5DA5A = { + fileRef = 4B117C6905DD0C8D00B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B16FF900467B5A000053105 = { + 4B117C6B05DD0C8D00B5DA5A = { + fileRef = 4B117C6905DD0C8D00B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B117C6C05DD0C9400B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - path = pThreadUtilities.h; + lastKnownFileType = sourcecode.c.c; + name = ringbuffer.c; + path = ../../../libjack/ringbuffer.c; refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B16FF920467B5A000053105 = { - fileRef = 4B16FF900467B5A000053105; + 4B117C6D05DD0C9400B5DA5A = { + fileRef = 4B117C6C05DD0C9400B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B117C6E05DD0C9400B5DA5A = { + fileRef = 4B117C6C05DD0C9400B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B5B51E9047D353A00053105 = { + 4B117C6F05DD0C9900B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - path = ipc.c; + lastKnownFileType = sourcecode.c.c; + name = transclient.c; + path = ../../../libjack/transclient.c; refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B5B51EA047D353A00053105 = { + 4B117C7005DD0C9900B5DA5A = { + fileRef = 4B117C6F05DD0C9900B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B117C7105DD0C9900B5DA5A = { + fileRef = 4B117C6F05DD0C9900B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B117C7205DD0C9D00B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - path = ipc.h; + lastKnownFileType = sourcecode.c.c; + name = shm.c; + path = ../../../libjack/shm.c; refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B5B51EB047D353A00053105 = { - fileRef = 4B5B51E9047D353A00053105; + 4B117C7305DD0C9D00B5DA5A = { + fileRef = 4B117C7205DD0C9D00B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B5B51EC047D353A00053105 = { - fileRef = 4B5B51EA047D353A00053105; + 4B117C7405DD0C9D00B5DA5A = { + fileRef = 4B117C7205DD0C9D00B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B5B51ED047D353A00053105 = { - fileRef = 4B5B51E9047D353A00053105; + 4B117C7505DD0CA000B5DA5A = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = client.c; + path = ../../../libjack/client.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B117C7605DD0CA000B5DA5A = { + fileRef = 4B117C7505DD0CA000B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B5B51EE047D353A00053105 = { - fileRef = 4B5B51EA047D353A00053105; + 4B117C7705DD0CA000B5DA5A = { + fileRef = 4B117C7505DD0CA000B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B5B51EF047D353A00053105 = { - fileRef = 4B5B51E9047D353A00053105; + 4B117C7A05DD0CC000B5DA5A = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = config.h; + path = ../../../config.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B117C7B05DD0CC000B5DA5A = { + fileRef = 4B117C7A05DD0CC000B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B5B51F0047D353A00053105 = { - fileRef = 4B5B51EA047D353A00053105; + 4B117C7C05DD0CC000B5DA5A = { + fileRef = 4B117C7A05DD0CC000B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B5EA35F0406AB6E00053105 = { + 4B117C7F05DD0D7700B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - name = engine.c; - path = ../jackd/engine.c; + lastKnownFileType = sourcecode.c.c; + name = portaudio_driver.c; + path = ../../../drivers/portaudio/portaudio_driver.c; refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B117C8005DD0D7700B5DA5A = { + fileRef = 4B117C7F05DD0D7700B5DA5A; + isa = PBXBuildFile; + settings = { + }; }; - 4B5EA37B0406AB6E00053105 = { + 4B117C8105DD0D7D00B5DA5A = { fileEncoding = 30; isa = PBXFileReference; - name = jackd.c; - path = ../jackd/jackd.c; + lastKnownFileType = sourcecode.c.h; + name = portaudio_driver.h; + path = ../../../drivers/portaudio/portaudio_driver.h; refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B63C61404092FC90030C2C8 = { - fileRef = 4B5EA35F0406AB6E00053105; + 4B117C8205DD0D7D00B5DA5A = { + fileRef = 4B117C8105DD0D7D00B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B6AF278041F4DBC00053105 = { - children = ( - 4B032A3E040AB68E00053105, - 4BCA2605040B8BC900053105, - 4BF87132040BDEAE00053105, - 4BA1E44F0442D89100053105, - 4BB3FC36048B7F7C00053105, - 4BB3FC37048B7F7C00053105, - 4BB3FC34048B7F0000053105, - ); - isa = PBXGroup; - name = Samples; - refType = 4; + 4B117C8305DD0DA700B5DA5A = { + fileRef = 4B117C6905DD0C8D00B5DA5A; + isa = PBXBuildFile; + settings = { + }; }; - 4B6BFD3D042B26F800053105 = { + 4B16FF900467B5A000053105 = { fileEncoding = 30; isa = PBXFileReference; - name = local.h; - path = ../libjack/local.h; + lastKnownFileType = sourcecode.c.h; + path = pThreadUtilities.h; refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B16FF920467B5A000053105 = { + fileRef = 4B16FF900467B5A000053105; + isa = PBXBuildFile; + settings = { + }; + }; + 4B4DCB9405DD229F00DC3452 = { + fileRef = 4B117C6305DD0C8000B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B4DCB9505DD22AF00DC3452 = { + fileRef = 4B117C6605DD0C8700B5DA5A; + isa = PBXBuildFile; + settings = { + }; + }; + 4B4DCB9705DD22BB00DC3452 = { + fileRef = 4B117C7505DD0CA000B5DA5A; + isa = PBXBuildFile; + settings = { + }; }; - 4B6BFD3E042B26F800053105 = { - fileRef = 4B6BFD3D042B26F800053105; + 4B4DCB9805DD22C300DC3452 = { + fileRef = 4B117C7205DD0C9D00B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B6BFD40042B26F800053105 = { - fileRef = 4B6BFD3D042B26F800053105; + 4B4DCB9905DD22C900DC3452 = { + fileRef = 4B117C6F05DD0C9900B5DA5A; isa = PBXBuildFile; settings = { }; }; - 4B6BFD41042B274900053105 = { + 4B4DCBA105DD234100DC3452 = { fileEncoding = 30; isa = PBXFileReference; - name = time.h; - path = ../jack/time.h; + lastKnownFileType = sourcecode.c.h; + name = ringbuffer.h; + path = ../../../jack/ringbuffer.h; refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B6BFD42042B274900053105 = { - fileRef = 4B6BFD41042B274900053105; + 4B4DCBA205DD234100DC3452 = { + fileRef = 4B4DCBA105DD234100DC3452; isa = PBXBuildFile; settings = { }; }; - 4B6BFD44042B274900053105 = { - fileRef = 4B6BFD41042B274900053105; + 4B4DCBA305DD234100DC3452 = { + fileRef = 4B4DCBA105DD234100DC3452; isa = PBXBuildFile; settings = { + ATTRIBUTES = ( + Public, + ); }; }; - 4B6BFD45042B4E4D00053105 = { + 4B4DCBA405DD234800DC3452 = { fileEncoding = 30; isa = PBXFileReference; - name = port.c; - path = ../libjack/port.c; + lastKnownFileType = sourcecode.c.h; + name = transport.h; + path = ../../../jack/transport.h; refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B6BFD46042B4E4D00053105 = { - fileRef = 4B6BFD45042B4E4D00053105; + 4B4DCBA505DD234800DC3452 = { + fileRef = 4B4DCBA405DD234800DC3452; isa = PBXBuildFile; settings = { }; }; - 4B6BFD48042B4F0800053105 = { - fileRef = 4B6BFD45042B4E4D00053105; + 4B4DCBA605DD234800DC3452 = { + fileRef = 4B4DCBA405DD234800DC3452; isa = PBXBuildFile; settings = { + ATTRIBUTES = ( + Public, + ); }; }; - 4B6CBA33041F4DDF00053105 = { - children = ( - 4BA74630048BC86900053105, - 4B6CBA3F041F4F4D00053105, - 4B16FF900467B5A000053105, - 4B099342041FB67A00053105, - 4B099343041FB67A00053105, - 4B5B51E9047D353A00053105, - 4B5B51EA047D353A00053105, - 4BB9E091046FADED00053105, - 4BAA76A6047E0D5200053105, - ); - isa = PBXGroup; - name = Porting_code; - refType = 4; - }; - 4B6CBA3F041F4F4D00053105 = { + 4B4DCBA705DD235B00DC3452 = { fileEncoding = 30; isa = PBXFileReference; - path = pThreadUtilities.c; - refType = 4; + lastKnownFileType = sourcecode.c.h; + name = types.h; + path = ../../../jack/types.h; + refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B6CBA45041F50C600053105 = { - fileRef = 4B6CBA3F041F4F4D00053105; + 4B4DCBA805DD235B00DC3452 = { + fileRef = 4B4DCBA705DD235B00DC3452; isa = PBXBuildFile; settings = { }; }; - 4B6CBA67041F79CE00053105 = { - fileRef = 4B6CBA3F041F4F4D00053105; + 4B4DCBA905DD235B00DC3452 = { + fileRef = 4B4DCBA705DD235B00DC3452; isa = PBXBuildFile; settings = { + ATTRIBUTES = ( + Public, + ); }; }; - 4B783E1B049F824D00053105 = { - fileRef = 4B099343041FB67A00053105; + 4B4DCBAE05DD23DE00DC3452 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = metro.c; + path = "../../../example-clients/metro.c"; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B4DCBAF05DD23DE00DC3452 = { + fileRef = 4B4DCBAE05DD23DE00DC3452; isa = PBXBuildFile; settings = { }; }; - 4B813E0D0406ACEE00053105 = { + 4B4DCBB205DD243A00DC3452 = { fileEncoding = 30; isa = PBXFileReference; - name = client.c; - path = ../libjack/client.c; - refType = 4; + lastKnownFileType = sourcecode.c.c; + name = connect.c; + path = "../../../example-clients/connect.c"; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B4DCBB305DD243A00DC3452 = { + fileRef = 4B4DCBB205DD243A00DC3452; + isa = PBXBuildFile; + settings = { + }; }; - 4B813E0F0406AD3100053105 = { + 4B4DCBB605DD248300DC3452 = { + fileRef = 4B4DCBB205DD243A00DC3452; + isa = PBXBuildFile; + settings = { + }; + }; + 4B4DCBB905DD249E00DC3452 = { fileEncoding = 30; isa = PBXFileReference; - name = driver.c; - path = ../libjack/driver.c; - refType = 4; + lastKnownFileType = sourcecode.c.c; + name = lsp.c; + path = "../../../example-clients/lsp.c"; + refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B813E110406AD4900053105 = { + 4B4DCBBA05DD249E00DC3452 = { + fileRef = 4B4DCBB905DD249E00DC3452; + isa = PBXBuildFile; + settings = { + }; + }; + 4B4DCBBD05DD24CD00DC3452 = { fileEncoding = 30; isa = PBXFileReference; - name = pool.c; - path = ../libjack/pool.c; - refType = 4; + lastKnownFileType = sourcecode.c.c; + name = capture_client.c; + path = "../../../example-clients/capture_client.c"; + refType = 2; + sourceTree = SOURCE_ROOT; }; - 4B813E120406AD4900053105 = { + 4B5B51EA047D353A00053105 = { fileEncoding = 30; isa = PBXFileReference; - name = timestamps.c; - path = ../libjack/timestamps.c; + lastKnownFileType = sourcecode.c.h; + path = ipc.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 4B5B51EC047D353A00053105 = { + fileRef = 4B5B51EA047D353A00053105; + isa = PBXBuildFile; + settings = { + }; + }; + 4B5B51EE047D353A00053105 = { + fileRef = 4B5B51EA047D353A00053105; + isa = PBXBuildFile; + settings = { + }; + }; + 4B5B51F0047D353A00053105 = { + fileRef = 4B5B51EA047D353A00053105; + isa = PBXBuildFile; + settings = { + }; + }; + 4B6AF278041F4DBC00053105 = { + children = ( + 4B4DCBAE05DD23DE00DC3452, + 4B4DCBB205DD243A00DC3452, + 4B4DCBB905DD249E00DC3452, + 4B4DCBBD05DD24CD00DC3452, + ); + isa = PBXGroup; + name = Samples; + refType = 4; + sourceTree = ""; + }; + 4B6CBA33041F4DDF00053105 = { + children = ( + 4B117C7A05DD0CC000B5DA5A, + 4B16FF900467B5A000053105, + 4B099343041FB67A00053105, + 4B5B51EA047D353A00053105, + 4BB9E091046FADED00053105, + 4BAA76A6047E0D5200053105, + ); + isa = PBXGroup; + name = Porting_code; refType = 4; + sourceTree = ""; + }; + 4B783E1B049F824D00053105 = { + fileRef = 4B099343041FB67A00053105; + isa = PBXBuildFile; + settings = { + }; }; 4BA1CAD90470D14500053105 = { buildActionMask = 2147483647; files = ( 4BA1CAE60470D1FB00053105, 4BA1CAEA0470D1FD00053105, - 4BA1CAEC0470D24100053105, - 4BA1CAEE0470D24500053105, - 4BA1CAEF0470D26000053105, 4B5B51F0047D353A00053105, + 4B117C7C05DD0CC000B5DA5A, + 4B4DCBA305DD234100DC3452, + 4B4DCBA605DD234800DC3452, + 4B4DCBA905DD235B00DC3452, + 4BA39A2005DD2C63008919E8, + 4BA39A2405DD2CA5008919E8, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -521,15 +752,15 @@ 4BA1CADB0470D14500053105 = { buildActionMask = 2147483647; files = ( - 4BA1CAE00470D16200053105, - 4BA1CAE10470D16300053105, - 4BA1CAE20470D16300053105, - 4BA1CAE30470D16400053105, - 4BA1CAE40470D16400053105, - 4BA1CAE50470D1FA00053105, - 4BA1CAE70470D1FB00053105, - 4B5B51EF047D353A00053105, - 4BB3416704D5115900053105, + 4B117C5C05DD0C4100B5DA5A, + 4B117C5F05DD0C5B00B5DA5A, + 4B117C6505DD0C8000B5DA5A, + 4B117C6805DD0C8700B5DA5A, + 4B117C6B05DD0C8D00B5DA5A, + 4B117C6E05DD0C9400B5DA5A, + 4B117C7105DD0C9900B5DA5A, + 4B117C7405DD0C9D00B5DA5A, + 4B117C7705DD0CA000B5DA5A, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -560,8 +791,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; - HEADER_SEARCH_PATHS = ". /sw/include ../"; - LIBRARY_SEARCH_PATHS = /sw/lib; + HEADER_SEARCH_PATHS = "../../ ../../../"; + LIBRARY_SEARCH_PATHS = ""; OPTIMIZATION_CFLAGS = "-O3"; OTHER_CFLAGS = "-DOLD_TRANSPORT"; OTHER_LDFLAGS = "-framework CoreAudio "; @@ -611,45 +842,12 @@ "; }; 4BA1CADF0470D14500053105 = { + explicitFileType = wrapper.framework; + fallbackIsa = PBXFileReference; isa = PBXFrameworkReference; path = Jack.framework; refType = 3; - }; - 4BA1CAE00470D16200053105 = { - fileRef = 4B6BFD45042B4E4D00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA1CAE10470D16300053105 = { - fileRef = 4B813E0D0406ACEE00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA1CAE20470D16300053105 = { - fileRef = 4B813E110406AD4900053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA1CAE30470D16400053105 = { - fileRef = 4B813E120406AD4900053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA1CAE40470D16400053105 = { - fileRef = 4BB407B0044DB8EF00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA1CAE50470D1FA00053105 = { - fileRef = 4B6CBA3F041F4F4D00053105; - isa = PBXBuildFile; - settings = { - }; + sourceTree = BUILT_PRODUCTS_DIR; }; 4BA1CAE60470D1FB00053105 = { fileRef = 4B16FF900467B5A000053105; @@ -657,45 +855,12 @@ settings = { }; }; - 4BA1CAE70470D1FB00053105 = { - fileRef = 4B099342041FB67A00053105; + 4BA1CAEA0470D1FD00053105 = { + fileRef = 4BB9E091046FADED00053105; isa = PBXBuildFile; settings = { }; }; - 4BA1CAEA0470D1FD00053105 = { - fileRef = 4BB9E091046FADED00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA1CAEC0470D24100053105 = { - fileRef = 4BA7167B0408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - ATTRIBUTES = ( - Public, - ); - }; - }; - 4BA1CAEE0470D24500053105 = { - fileRef = 4BA716850408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - ATTRIBUTES = ( - Public, - ); - }; - }; - 4BA1CAEF0470D26000053105 = { - fileRef = 4BA716840408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - ATTRIBUTES = ( - Public, - ); - }; - }; 4BA1CAFC0470D38800053105 = { buildActionMask = 2147483647; files = ( @@ -706,7 +871,7 @@ 4BA1CAFD0470D38800053105 = { buildActionMask = 2147483647; files = ( - 4BA1CB040470D3B100053105, + 4B4DCBB605DD248300DC3452, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -750,22 +915,12 @@ productReference = 4BA1CB010470D38800053105; }; 4BA1CB010470D38800053105 = { + explicitFileType = "compiled.mach-o.executable"; + fallbackIsa = PBXFileReference; isa = PBXExecutableFileReference; path = jack_disconnect; refType = 3; - }; - 4BA1CB040470D3B100053105 = { - fileRef = 4BF87132040BDEAE00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA1E44F0442D89100053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = lsp.c; - path = "../example-clients/lsp.c"; - refType = 4; + sourceTree = BUILT_PRODUCTS_DIR; }; 4BA1E4530442D99D00053105 = { buildActionMask = 2147483647; @@ -777,7 +932,7 @@ 4BA1E4540442D99D00053105 = { buildActionMask = 2147483647; files = ( - 4BA1E45A0442D9A500053105, + 4B4DCBBA05DD249E00DC3452, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -804,7 +959,7 @@ 4BA1E4560442D99D00053105, ); buildSettings = { - HEADER_SEARCH_PATHS = ". ../"; + HEADER_SEARCH_PATHS = ../../; OTHER_CFLAGS = ""; OTHER_LDFLAGS = "-framework Jack"; OTHER_REZFLAGS = ""; @@ -822,286 +977,102 @@ productReference = 4BA1E4580442D99D00053105; }; 4BA1E4580442D99D00053105 = { + explicitFileType = "compiled.mach-o.executable"; + fallbackIsa = PBXFileReference; isa = PBXExecutableFileReference; path = jack_lsp; refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; }; - 4BA1E45A0442D9A500053105 = { - fileRef = 4BA1E44F0442D89100053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7165F0408DFF5004F4E3A = { - children = ( - 4B5EA37B0406AB6E00053105, - 4B5EA35F0406AB6E00053105, - 4B813E0F0406AD3100053105, - 4BB3416004D5113A00053105, - ); - isa = PBXGroup; - name = Server; - refType = 4; - }; - 4BA716600408E047004F4E3A = { - children = ( - 4BB967410474044200053105, - 4BB967420474044200053105, - ); - isa = PBXGroup; - name = Driver; - refType = 4; - }; - 4BA716710408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = cycles.h; - path = ../jack/cycles.h; - refType = 2; - }; - 4BA716720408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = driver.h; - path = ../jack/driver.h; - refType = 2; - }; - 4BA716730408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = engine.h; - path = ../jack/engine.h; - refType = 2; - }; - 4BA716750408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = generic.h; - path = ../jack/generic.h; - refType = 2; - }; - 4BA716770408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = hardware.h; - path = ../jack/hardware.h; - refType = 2; - }; - 4BA7167A0408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = internal.h; - path = ../jack/internal.h; - refType = 2; - }; - 4BA7167B0408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = jack.h; - path = ../jack/jack.h; - refType = 2; - }; - 4BA7167C0408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = jslist.h; - path = ../jack/jslist.h; - refType = 2; - }; - 4BA7167F0408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = memops.h; - path = ../jack/memops.h; - refType = 2; - }; - 4BA716800408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = pool.h; - path = ../jack/pool.h; - refType = 2; - }; - 4BA716810408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = port.h; - path = ../jack/port.h; - refType = 2; - }; - 4BA716820408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = start.h; - path = ../jack/start.h; - refType = 2; - }; - 4BA716830408F4AD004F4E3A = { + 4BA39A1E05DD2C63008919E8 = { fileEncoding = 30; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; name = timestamps.h; - path = ../jack/timestamps.h; + path = ../../../jack/timestamps.h; refType = 2; + sourceTree = SOURCE_ROOT; }; - 4BA716840408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = transport.h; - path = ../jack/transport.h; - refType = 2; - }; - 4BA716850408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = types.h; - path = ../jack/types.h; - refType = 2; - }; - 4BA716860408F4AD004F4E3A = { - fileEncoding = 30; - isa = PBXFileReference; - name = version.h; - path = ../jack/version.h; - refType = 2; - }; - 4BA7173304090368004F4E3A = { - fileRef = 4BA716710408F4AD004F4E3A; + 4BA39A1F05DD2C63008919E8 = { + fileRef = 4BA39A1E05DD2C63008919E8; isa = PBXBuildFile; settings = { }; }; - 4BA7173404090369004F4E3A = { - fileRef = 4BA716720408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7173504090369004F4E3A = { - fileRef = 4BA716730408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA717370409036A004F4E3A = { - fileRef = 4BA716750408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA717380409036B004F4E3A = { - fileRef = 4BA716770408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA717390409036C004F4E3A = { - fileRef = 4BA7167A0408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7173A0409036C004F4E3A = { - fileRef = 4BA7167B0408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7173B0409036D004F4E3A = { - fileRef = 4BA7167C0408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7173C0409036D004F4E3A = { - fileRef = 4BA7167F0408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7173D0409036E004F4E3A = { - fileRef = 4BA716800408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7173E0409036F004F4E3A = { - fileRef = 4BA716810408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7173F0409036F004F4E3A = { - fileRef = 4BA716820408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; - }; - 4BA7174004090370004F4E3A = { - fileRef = 4BA716830408F4AD004F4E3A; + 4BA39A2005DD2C63008919E8 = { + fileRef = 4BA39A1E05DD2C63008919E8; isa = PBXBuildFile; settings = { + ATTRIBUTES = ( + Public, + ); }; }; - 4BA7174104090370004F4E3A = { - fileRef = 4BA716840408F4AD004F4E3A; - isa = PBXBuildFile; - settings = { - }; + 4BA39A2205DD2CA5008919E8 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = jack.h; + path = ../../../jack/jack.h; + refType = 2; + sourceTree = SOURCE_ROOT; }; - 4BA7174204090371004F4E3A = { - fileRef = 4BA716850408F4AD004F4E3A; + 4BA39A2305DD2CA5008919E8 = { + fileRef = 4BA39A2205DD2CA5008919E8; isa = PBXBuildFile; settings = { }; }; - 4BA7174304090372004F4E3A = { - fileRef = 4BA716860408F4AD004F4E3A; + 4BA39A2405DD2CA5008919E8 = { + fileRef = 4BA39A2205DD2CA5008919E8; isa = PBXBuildFile; settings = { + ATTRIBUTES = ( + Public, + ); }; }; - 4BA74630048BC86900053105 = { - fileEncoding = 30; - isa = PBXFileReference; - path = config.h; - refType = 2; + 4BA7165F0408DFF5004F4E3A = { + children = ( + 4B117C5805DD0C3600B5DA5A, + 4B117C5A05DD0C4100B5DA5A, + 4B117C5D05DD0C5B00B5DA5A, + ); + isa = PBXGroup; + name = Server; + refType = 4; + sourceTree = ""; }; - 4BA74631048BC86900053105 = { - fileRef = 4BA74630048BC86900053105; - isa = PBXBuildFile; - settings = { - }; + 4BA716600408E047004F4E3A = { + children = ( + 4B117C7F05DD0D7700B5DA5A, + 4B117C8105DD0D7D00B5DA5A, + ); + isa = PBXGroup; + name = Driver; + refType = 4; + sourceTree = ""; }; 4BA9D903040E0CC200053105 = { children = ( - 4BA716710408F4AD004F4E3A, - 4BA716720408F4AD004F4E3A, - 4BA716730408F4AD004F4E3A, - 4BA716750408F4AD004F4E3A, - 4BA716770408F4AD004F4E3A, - 4BA7167A0408F4AD004F4E3A, - 4BA7167B0408F4AD004F4E3A, - 4BA7167C0408F4AD004F4E3A, - 4BA7167F0408F4AD004F4E3A, - 4BA716800408F4AD004F4E3A, - 4BA716810408F4AD004F4E3A, - 4BA716820408F4AD004F4E3A, - 4BA716830408F4AD004F4E3A, - 4BA716840408F4AD004F4E3A, - 4BA716850408F4AD004F4E3A, - 4BA716860408F4AD004F4E3A, - 4B6BFD3D042B26F800053105, - 4B6BFD41042B274900053105, + 4BA39A2205DD2CA5008919E8, + 4BA39A1E05DD2C63008919E8, + 4B4DCBA105DD234100DC3452, + 4B4DCBA405DD234800DC3452, + 4B4DCBA705DD235B00DC3452, ); isa = PBXGroup; name = Headers; refType = 4; + sourceTree = ""; }; 4BAA76A6047E0D5200053105 = { fileEncoding = 30; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = getopt.h; refType = 2; + sourceTree = SOURCE_ROOT; }; 4BAA76A7047E0D5200053105 = { fileRef = 4BAA76A6047E0D5200053105; @@ -1109,187 +1080,13 @@ settings = { }; }; - 4BB3416004D5113A00053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = transengine.c; - path = ../jackd/transengine.c; - refType = 2; - }; - 4BB3416204D5113A00053105 = { - fileRef = 4BB3416004D5113A00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB3416404D5113A00053105 = { - fileRef = 4BB3416004D5113A00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB3416604D5115900053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = transclient.c; - path = ../libjack/transclient.c; - refType = 2; - }; - 4BB3416704D5115900053105 = { - fileRef = 4BB3416604D5115900053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB3FC2D048B7EF000053105 = { - buildActionMask = 2147483647; - files = ( - 4BB3FC38048B7F7C00053105, - ); - isa = PBXHeadersBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 4BB3FC2E048B7EF000053105 = { - buildActionMask = 2147483647; - files = ( - 4BB3FC35048B7F0000053105, - 4BB3FC39048B7F7C00053105, - ); - isa = PBXSourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 4BB3FC2F048B7EF000053105 = { - buildActionMask = 2147483647; - files = ( - ); - isa = PBXFrameworksBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 4BB3FC30048B7EF000053105 = { - buildActionMask = 2147483647; - files = ( - ); - isa = PBXRezBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 4BB3FC31048B7EF000053105 = { - buildPhases = ( - 4BB3FC2D048B7EF000053105, - 4BB3FC2E048B7EF000053105, - 4BB3FC2F048B7EF000053105, - 4BB3FC30048B7EF000053105, - ); - buildSettings = { - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = "-framework Jack -lsndfile"; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_rec; - REZ_EXECUTABLE = YES; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; - }; - dependencies = ( - ); - isa = PBXToolTarget; - name = jack_rec; - productInstallPath = /usr/local/bin; - productName = jack_rec; - productReference = 4BB3FC32048B7EF000053105; - }; - 4BB3FC32048B7EF000053105 = { - isa = PBXExecutableFileReference; - path = jack_rec; - refType = 3; - }; - 4BB3FC34048B7F0000053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = capture_client.c; - path = "../example-clients/capture_client.c"; - refType = 2; - }; - 4BB3FC35048B7F0000053105 = { - fileRef = 4BB3FC34048B7F0000053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB3FC36048B7F7C00053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = ringbuffer.h; - path = "../example-clients/ringbuffer.h"; - refType = 2; - }; - 4BB3FC37048B7F7C00053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = ringbuffer.c; - path = "../example-clients/ringbuffer.c"; - refType = 2; - }; - 4BB3FC38048B7F7C00053105 = { - fileRef = 4BB3FC36048B7F7C00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB3FC39048B7F7C00053105 = { - fileRef = 4BB3FC37048B7F7C00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB407B0044DB8EF00053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = shm.c; - path = ../libjack/shm.c; - refType = 4; - }; - 4BB407B2044DB8EF00053105 = { - fileRef = 4BB407B0044DB8EF00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB407C3044DBEA700053105 = { - fileRef = 4BB407B0044DB8EF00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB967410474044200053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = portaudio_driver.c; - path = ../drivers/portaudio/portaudio_driver.c; - refType = 2; - }; - 4BB967420474044200053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = portaudio_driver.h; - path = ../drivers/portaudio/portaudio_driver.h; - refType = 2; - }; - 4BB967430474044200053105 = { - fileRef = 4BB967410474044200053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BB967440474044200053105 = { - fileRef = 4BB967420474044200053105; - isa = PBXBuildFile; - settings = { - }; - }; 4BB9E091046FADED00053105 = { fileEncoding = 30; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = mach_port.h; refType = 4; + sourceTree = ""; }; 4BB9E095046FADED00053105 = { fileRef = 4BB9E091046FADED00053105; @@ -1306,11 +1103,9 @@ 4BBB872C0406EF300019BE76 = { buildActionMask = 2147483647; files = ( - 4B6BFD40042B26F800053105, - 4B6BFD44042B274900053105, 4BB9E097046FB05700053105, - 4BB967440474044200053105, 4B5B51EC047D353A00053105, + 4B117C8205DD0D7D00B5DA5A, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -1318,16 +1113,13 @@ 4BBB872D0406EF300019BE76 = { buildActionMask = 2147483647; files = ( - 4B032A29040AA91C00053105, - 4B032A2B040AA94B00053105, - 4B032A2C040AA95400053105, - 4B6CBA67041F79CE00053105, - 4B099348041FB67A00053105, - 4B6BFD48042B4F0800053105, - 4BB407C3044DBEA700053105, - 4BB967430474044200053105, - 4B5B51EB047D353A00053105, - 4BB3416404D5113A00053105, + 4B117C8005DD0D7700B5DA5A, + 4B117C8305DD0DA700B5DA5A, + 4B4DCB9405DD229F00DC3452, + 4B4DCB9505DD22AF00DC3452, + 4B4DCB9705DD22BB00DC3452, + 4B4DCB9805DD22C300DC3452, + 4B4DCB9905DD22C900DC3452, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -1356,8 +1148,8 @@ buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - HEADER_SEARCH_PATHS = "../ /sw/include"; - LIBRARY_SEARCH_PATHS = /sw/lib; + HEADER_SEARCH_PATHS = "../../ ../../../"; + LIBRARY_SEARCH_PATHS = ""; LIBRARY_STYLE = BUNDLE; OPTIMIZATION_CFLAGS = "-O3"; OTHER_LDFLAGS = "-framework PortAudio -framework CoreAudio "; @@ -1377,9 +1169,12 @@ productReference = 4BBB87310406EF300019BE76; }; 4BBB87310406EF300019BE76 = { + explicitFileType = "compiled.mach-o.dylib"; + fallbackIsa = PBXFileReference; isa = PBXLibraryReference; path = jack_portaudio.so; refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; }; 4BCA25FE040B8B9400053105 = { buildActionMask = 2147483647; @@ -1391,7 +1186,7 @@ 4BCA25FF040B8B9400053105 = { buildActionMask = 2147483647; files = ( - 4BCA2606040B8BC900053105, + 4B4DCBAF05DD23DE00DC3452, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -1418,7 +1213,7 @@ 4BCA2601040B8B9400053105, ); buildSettings = { - HEADER_SEARCH_PATHS = ../; + HEADER_SEARCH_PATHS = ../../; OPTIMIZATION_CFLAGS = "-O0"; OTHER_CFLAGS = ""; OTHER_LDFLAGS = "-framework Jack"; @@ -1438,40 +1233,12 @@ productReference = 4BCA2603040B8B9400053105; }; 4BCA2603040B8B9400053105 = { + explicitFileType = "compiled.mach-o.executable"; + fallbackIsa = PBXFileReference; isa = PBXExecutableFileReference; path = jack_metro; refType = 3; - }; - 4BCA2605040B8BC900053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = metro.c; - path = "../example-clients/metro.c"; - refType = 4; - }; - 4BCA2606040B8BC900053105 = { - fileRef = 4BCA2605040B8BC900053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BD69BCE040A860400053105 = { - fileRef = 4B5EA37B0406AB6E00053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BD69BCF040A860800053105 = { - fileRef = 4B813E0F0406AD3100053105; - isa = PBXBuildFile; - settings = { - }; - }; - 4BE14029041FB98500053105 = { - fileRef = 4B099342041FB67A00053105; - isa = PBXBuildFile; - settings = { - }; + sourceTree = BUILT_PRODUCTS_DIR; }; 4BF8712B040BDE8200053105 = { buildActionMask = 2147483647; @@ -1483,7 +1250,7 @@ 4BF8712C040BDE8200053105 = { buildActionMask = 2147483647; files = ( - 4BF87133040BDEAE00053105, + 4B4DCBB305DD243A00DC3452, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -1510,7 +1277,7 @@ 4BF8712E040BDE8200053105, ); buildSettings = { - HEADER_SEARCH_PATHS = ../; + HEADER_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; OTHER_LDFLAGS = "-framework Jack"; OTHER_REZFLAGS = ""; @@ -1528,22 +1295,12 @@ productReference = 4BF87130040BDE8200053105; }; 4BF87130040BDE8200053105 = { + explicitFileType = "compiled.mach-o.executable"; + fallbackIsa = PBXFileReference; isa = PBXExecutableFileReference; path = jack_connect; refType = 3; - }; - 4BF87132040BDEAE00053105 = { - fileEncoding = 30; - isa = PBXFileReference; - name = connect.c; - path = "../example-clients/connect.c"; - refType = 4; - }; - 4BF87133040BDEAE00053105 = { - fileRef = 4BF87132040BDEAE00053105; - isa = PBXBuildFile; - settings = { - }; + sourceTree = BUILT_PRODUCTS_DIR; }; //4B0 //4B1 diff --git a/macosx/mach_port.h b/config/os/macosx/mach_port.h similarity index 100% rename from macosx/mach_port.h rename to config/os/macosx/mach_port.h diff --git a/config/os/macosx/os_defines.h b/config/os/macosx/os_defines.h new file mode 100644 index 00000000..d73c63a6 --- /dev/null +++ b/config/os/macosx/os_defines.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2004 Jack O'Quin + + MacOS X specific defines. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ + +#ifndef _jack_os_defines +#define _jack_os_defines 1 + +/* a bigger process stack makes the application crash... */ +#define JACK_THREAD_STACK_TOUCH 10000 +#define JACK_CPP_VARARGS_BROKEN 1 +#define JACK_USE_MACH_THREADS 1 +#define JACK_DO_NOT_MLOCK 1 +#define PORTAUDIO_H +#define GETOPT_H + +/* MacOSX defines __POWERPC__ rather than __powerpc__ */ +#if defined(__POWERPC__) && !defined(__powerpc__) +#define __powerpc__ __POWERPC__ +#endif + +#endif /* _jack_os_defines */ diff --git a/config/os/macosx/pThreadUtilities.h b/config/os/macosx/pThreadUtilities.h new file mode 100644 index 00000000..bd1d1e8b --- /dev/null +++ b/config/os/macosx/pThreadUtilities.h @@ -0,0 +1,203 @@ +/* + Copyright: © Copyright 2002 Apple Computer, Inc. All rights + reserved. + + Disclaimer: IMPORTANT: This Apple software is supplied to + you by Apple Computer, Inc. ("Apple") in + consideration of your agreement to the + following terms, and your use, installation, + modification or redistribution of this Apple + software constitutes acceptance of these + terms. If you do not agree with these terms, + please do not use, install, modify or + redistribute this Apple software. + + In consideration of your agreement to abide by + the following terms, and subject to these + terms, Apple grants you a personal, + non-exclusive license, under AppleÕs + copyrights in this original Apple software + (the "Apple Software"), to use, reproduce, + modify and redistribute the Apple Software, + with or without modifications, in source + and/or binary forms; provided that if you + redistribute the Apple Software in its + entirety and without modifications, you must + retain this notice and the following text and + disclaimers in all such redistributions of the + Apple Software. Neither the name, trademarks, + service marks or logos of Apple Computer, + Inc. may be used to endorse or promote + products derived from the Apple Software + without specific prior written permission from + Apple. Except as expressly stated in this + notice, no other rights or licenses, express + or implied, are granted by Apple herein, + including but not limited to any patent rights + that may be infringed by your derivative works + or by other works in which the Apple Software + may be incorporated. + + The Apple Software is provided by Apple on an + "AS IS" basis. APPLE MAKES NO WARRANTIES, + EXPRESS OR IMPLIED, INCLUDING WITHOUT + LIMITATION THE IMPLIED WARRANTIES OF + NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE + SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY + SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE + USE, REPRODUCTION, MODIFICATION AND/OR + DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER + CAUSED AND WHETHER UNDER THEORY OF CONTRACT, + TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY + OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* pThreadUtilities.h */ + +#ifndef __PTHREADUTILITIES_H__ +#define __PTHREADUTILITIES_H__ + +#import "pthread.h" +#import + +#define THREAD_SET_PRIORITY 0 +#define THREAD_SCHEDULED_PRIORITY 1 + +#include +#include +#include +#include + +static inline UInt32 +_getThreadPriority(pthread_t inThread, int inWhichPriority) +{ + thread_basic_info_data_t threadInfo; + policy_info_data_t thePolicyInfo; + unsigned int count; + + // get basic info + count = THREAD_BASIC_INFO_COUNT; + thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, + (thread_info_t)&threadInfo, &count); + + switch (threadInfo.policy) { + case POLICY_TIMESHARE: + count = POLICY_TIMESHARE_INFO_COUNT; + thread_info(pthread_mach_thread_np (inThread), + THREAD_SCHED_TIMESHARE_INFO, + (thread_info_t)&(thePolicyInfo.ts), &count); + if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) { + return thePolicyInfo.ts.cur_priority; + } else { + return thePolicyInfo.ts.base_priority; + } + break; + + case POLICY_FIFO: + count = POLICY_FIFO_INFO_COUNT; + thread_info(pthread_mach_thread_np (inThread), + THREAD_SCHED_FIFO_INFO, + (thread_info_t)&(thePolicyInfo.fifo), &count); + if ( (thePolicyInfo.fifo.depressed) + && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { + return thePolicyInfo.fifo.depress_priority; + } + return thePolicyInfo.fifo.base_priority; + break; + + case POLICY_RR: + count = POLICY_RR_INFO_COUNT; + thread_info(pthread_mach_thread_np (inThread), + THREAD_SCHED_RR_INFO, + (thread_info_t)&(thePolicyInfo.rr), &count); + if ( (thePolicyInfo.rr.depressed) + && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { + return thePolicyInfo.rr.depress_priority; + } + return thePolicyInfo.rr.base_priority; + break; + } + + return 0; +} + +// returns the thread's priority as it was last set by the API +static inline UInt32 +getThreadSetPriority(pthread_t inThread) +{ + return _getThreadPriority (inThread, THREAD_SET_PRIORITY); +} + +// returns the thread's priority as it was last scheduled by the Kernel +static inline UInt32 +getThreadScheduledPriority(pthread_t inThread) +{ + return _getThreadPriority (inThread, THREAD_SCHEDULED_PRIORITY); +} + + +static inline void +setThreadToPriority(pthread_t inThread, UInt32 inPriority, Boolean inIsFixed, + UInt64 inHALIOProcCycleDurationInNanoseconds) +{ + if (inPriority == 96) + { + // REAL-TIME / TIME-CONSTRAINT THREAD + thread_time_constraint_policy_data_t theTCPolicy; + UInt64 theComputeQuanta; + UInt64 thePeriod; + UInt64 thePeriodNanos; + + thePeriodNanos = inHALIOProcCycleDurationInNanoseconds; + theComputeQuanta = AudioConvertNanosToHostTime ( thePeriodNanos * 0.15 ); + thePeriod = AudioConvertNanosToHostTime (thePeriodNanos); + + theTCPolicy.period = thePeriod; + theTCPolicy.computation = theComputeQuanta; + theTCPolicy.constraint = thePeriod; + theTCPolicy.preemptible = true; + thread_policy_set (pthread_mach_thread_np(inThread), + THREAD_TIME_CONSTRAINT_POLICY, + (thread_policy_t)&theTCPolicy, + THREAD_TIME_CONSTRAINT_POLICY_COUNT); + } else { + // OTHER THREADS + thread_extended_policy_data_t theFixedPolicy; + thread_precedence_policy_data_t thePrecedencePolicy; + SInt32 relativePriority; + + // [1] SET FIXED / NOT FIXED + theFixedPolicy.timeshare = !inIsFixed; + thread_policy_set (pthread_mach_thread_np(inThread), + THREAD_EXTENDED_POLICY, + (thread_policy_t)&theFixedPolicy, + THREAD_EXTENDED_POLICY_COUNT); + + // [2] SET PRECEDENCE N.B.: We expect that if thread A + // created thread B, and the program wishes to change the + // priority of thread B, then the call to change the + // priority of thread B must be made by thread A. This + // assumption allows us to use pthread_self() to correctly + // calculate the priority of the feeder thread (since + // precedency policy's importance is relative to the + // spawning thread's priority.) + relativePriority = inPriority - + getThreadSetPriority (pthread_self()); + + thePrecedencePolicy.importance = relativePriority; + thread_policy_set (pthread_mach_thread_np(inThread), + THREAD_PRECEDENCE_POLICY, + (thread_policy_t)&thePrecedencePolicy, + THREAD_PRECEDENCE_POLICY_COUNT); + } +} + +#endif /* __PTHREADUTILITIES_H__ */ diff --git a/config/os/macosx/poll.h b/config/os/macosx/poll.h new file mode 100644 index 00000000..32ef6d2b --- /dev/null +++ b/config/os/macosx/poll.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2004 Jack O'Quin + + Mac OS/X replacement for . Overrides system version, + using to emulate the needed features. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ + +#ifndef __poll_h__ +#define __poll_h__ + +#include + +#endif /* __poll_h__ */ diff --git a/macosx/config.h b/config/os/macosx/portaudio.h old mode 100755 new mode 100644 similarity index 80% rename from macosx/config.h rename to config/os/macosx/portaudio.h index a208680c..4c43b0cb --- a/macosx/config.h +++ b/config/os/macosx/portaudio.h @@ -1,6 +1,8 @@ /* - Copyright (C) 2001 Paul Davis - + Copyright (C) 2004 Jack O'Quin + + Mac OS/X specific defines. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or @@ -18,12 +20,9 @@ $Id$ */ -/* Defined "by hand" on Darwin/MacOSX */ - -#define VERSION "0.74.2" - -#define ADDON_DIR "/usr/local/lib" +#ifndef _macosx_portaudio +#define _macosx_portaudio 1 -#define USE_POSIX_SHM 1 +#include -#define HAVE_ATEXIT 1 +#endif /* _macosx_portaudio */ diff --git a/jack/time.h b/config/os/macosx/time.h similarity index 59% rename from jack/time.h rename to config/os/macosx/time.h index ad0f03d7..73fd898d 100644 --- a/jack/time.h +++ b/config/os/macosx/time.h @@ -21,33 +21,32 @@ #ifndef __jack_time_h__ #define __jack_time_h__ +/* + * This is the MacOSX version of . It overrides the + * generic version via the configure.hosts mechanism. + */ #include - -extern void jack_init_time (); - -#if defined(__APPLE__) && defined(__POWERPC__) - #include -extern double __jack_time_ratio; +/* This is a kludge. We need one global instantiation of this + * variable in each address space. So, libjack/client.c declares the + * actual storage. Other source files will see it as an extern. */ +#define JACK_TIME_GLOBAL_DECL double __jack_time_ratio +extern JACK_TIME_GLOBAL_DECL; -static inline jack_time_t jack_get_microseconds(void) +static inline jack_time_t +jack_get_microseconds(void) { return mach_absolute_time () * __jack_time_ratio; } -#else - -#include - -extern jack_time_t __jack_cpu_mhz; -extern jack_time_t jack_get_mhz(); -extern void jack_init_time (); - -static inline jack_time_t jack_get_microseconds (void) { - return get_cycles() / __jack_cpu_mhz; +/* This should only be called ONCE per process. */ +static inline void +jack_init_time () +{ + mach_timebase_info_data_t info; + mach_timebase_info(&info); + __jack_time_ratio = ((float)info.numer/info.denom) / 1000; } -#endif - #endif /* __jack_time_h__ */ diff --git a/config/sysdeps/.cvsignore b/config/sysdeps/.cvsignore new file mode 100644 index 00000000..eb921055 --- /dev/null +++ b/config/sysdeps/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +*.h diff --git a/config/sysdeps/Makefile.am b/config/sysdeps/Makefile.am new file mode 100644 index 00000000..efd1145f --- /dev/null +++ b/config/sysdeps/Makefile.am @@ -0,0 +1,23 @@ +# This directory contains links to platform-dependent headers in the +# source tree. None are installed or distributed from here. Remember +# that the build tree and the source tree are not always the same. + +MAINTAINERCLEANFILES = Makefile.in +CLEANFILES = *.h + +# Link all relevant headers into the `sysdeps' directory. The order +# of these loops determines header file precedence. + +all-local: + for h in ${top_srcdir}/config/cpu/generic/*.h; do \ + $(LN_S) -f $$h .; \ + done + for h in ${top_srcdir}/config/@cpu_include_dir@/*.h; do \ + $(LN_S) -f $$h .; \ + done + for h in ${top_srcdir}/config/os/generic/*.h; do \ + $(LN_S) -f $$h .; \ + done + for h in ${top_srcdir}/config/@os_include_dir@/*.h; do \ + $(LN_S) -f $$h .; \ + done diff --git a/configure.in b/configure.in index 32665c4c..ce2962d1 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(jackd/jackd.c) -AC_CONFIG_AUX_DIR(.) +AC_CONFIG_AUX_DIR(config) AC_CANONICAL_TARGET dnl --- @@ -14,8 +14,8 @@ dnl micro version = incremented when implementation-only dnl changes are made dnl --- JACK_MAJOR_VERSION=0 -JACK_MINOR_VERSION=95 -JACK_MICRO_VERSION=11 +JACK_MINOR_VERSION=96 +JACK_MICRO_VERSION=0 dnl --- dnl HOWTO: updating the jack protocol version @@ -68,63 +68,58 @@ AM_INIT_AUTOMAKE(jack-audio-connection-kit,${JACK_VERSION}) AM_MAINTAINER_MODE AM_CONFIG_HEADER(config.h) - AC_ENABLE_STATIC(no) AC_ENABLE_SHARED(yes) - AC_PROG_CC AC_PROG_CXX AC_PROG_LD AM_PROG_LIBTOOL +AC_PROG_LN_S AC_C_BIGENDIAN +# configure CPU and OS dependencies for host platform +AC_MSG_CHECKING([platform dependencies]) +source $srcdir/config/configure.host +AC_MSG_RESULT([${os_include_dir}, ${cpu_include_dir}]) +AC_SUBST(OS_LDFLAGS) +AC_SUBST(os_include_dir) +AC_SUBST(cpu_include_dir) + AC_CHECK_HEADERS(string.h strings.h) -AC_CHECK_FUNC(getopt_long, , AC_MSG_ERROR([GNU getopt is required to build jack])) +AC_CHECK_FUNC(getopt_long, , + AC_MSG_ERROR([GNU getopt is required to build jack])) AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) AC_CHECK_FUNC(connect, , AC_CHECK_LIB(inet, connect)) AC_CHECK_FUNCS(on_exit atexit) +AC_CHECK_FUNCS(posix_memalign) -dnl -dnl look for system support for POSIX shm API -dnl XXX this could probably be improved -dnl - +# look for system support for POSIX shm API AC_ARG_ENABLE(posix-shm, [ --enable-posix-shm use POSIX shm API ], - TRY_POSIX_SHM=$enableval , TRY_POSIX_SHM=no ) - + TRY_POSIX_SHM=$enableval , ) +AC_MSG_CHECKING([shared memory support]) if test "x$TRY_POSIX_SHM" = "xyes" then - - AC_MSG_CHECKING([POSIX shm support (compile time) ]) - df | grep -s /dev/shm >/dev/null 2>&1 - if test $? = 0 ; then - AC_DEFINE(USE_POSIX_SHM,1,[Use POSIX shared memory interface]) - AC_MSG_RESULT([found. - JACK will use shm_open() and friends.]) - - else - AC_MSG_RESULT([not found. - JACK will use System V shm API (shmget() and friends]) - fi + AC_MSG_RESULT([POSIX shm_open().]) + AC_DEFINE(USE_POSIX_SHM,1,[Use POSIX shared memory interface]) else - echo ' JACK will use System V shm API (shmget() and friends)' - + AC_MSG_RESULT([System V shmget().]) fi -JACK_CORE_CFLAGS="$CFLAGS -I\$(top_srcdir) -I\$(top_builddir) -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -Wall" +JACK_CORE_CFLAGS="$CFLAGS -I\$(top_builddir)/config -I\$(top_srcdir) -I\$(top_builddir) -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -Wall" JACK_CFLAGS="$JACK_CORE_CFLAGS -g" JACK_OPT_CFLAGS="$JACK_CORE_CFLAGS -g -march=pentium2 -mcpu=pentium4 -O3 -ffast-math -funroll-loops -fprefetch-loop-arrays" dnl dnl figure out how best to optimize +dnl JOQ: this should be done via config/configure.hosts dnl if test "$target_cpu" = "powerpc"; then AC_DEFINE(POWERPC, 1, "Are we running a ppc CPU?") - altivecLinux=`cat /proc/cpuinfo | grep -i altivec >/dev/null` + altivecLinux=`test -f /proc/cpuinfo && cat /proc/cpuinfo | grep -i altivec >/dev/null` if test "$?" = "0"; then AC_DEFINE(HAVE_ALTIVEC_LINUX, 1, "Is there Altivec Support ?") if test "$gcc_major_version" = "3"; then @@ -164,8 +159,10 @@ elif echo $target_cpu | grep "i*86" >/dev/null; then fi AC_ARG_ENABLE(optimize, - [ --enable-optimize ask the compiler for its best optimizations], - [ if test "x$enable_optimize" != "xno" ; then JACK_CFLAGS="$JACK_OPT_CFLAGS" ; fi ]) + [ --enable-optimize ask the compiler for its best optimizations], + [ if test "x$enable_optimize" != "xno" ; then + JACK_CFLAGS="$JACK_CORE_CFLAGS $JACK_OPT_FLAGS" ; + fi ]) AC_SUBST(JACK_CFLAGS) @@ -387,8 +384,8 @@ fi # on some systems, readline depends on termcap or ncurses, respectively READLINE_DEPS="" -AC_CHECK_LIB(termcap, tgetent, [READLINE_DEPS="$READLINE_DEPS -ltermcap"]) -AC_CHECK_LIB(ncurses, tgetent, [READLINE_DEPS="$READLINE_DEPS -lncurses"]) +##AC_CHECK_LIB(termcap, tgetent, [READLINE_DEPS="$READLINE_DEPS -ltermcap"]) +##AC_CHECK_LIB(ncurses, tgetent, [READLINE_DEPS="$READLINE_DEPS -lncurses"]) AC_CHECK_LIB(readline, readline, [HAVE_READLINE=true], [HAVE_READLINE=false], [$READLINE_DEPS] ) @@ -411,6 +408,8 @@ AM_CONDITIONAL(STRIPPED_JACKD, $STRIPPED_JACKD) AC_OUTPUT( Makefile +config/Makefile +config/sysdeps/Makefile doc/Makefile doc/reference.doxygen drivers/Makefile diff --git a/doc/Makefile.am b/doc/Makefile.am index d83b5d82..db503c88 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -4,12 +4,12 @@ MAINTAINERCLEANFILES=Makefile.in CLEANFILES=doxygen-build.stamp DOX=reference.doxygen -DOXSOURCES=mainpage.dox transport.dox fsm.png \ +DOXSOURCES=mainpage.dox transport.dox fsm.png fsm.eps \ ../jack/jack.h ../jack/types.h ../jack/transport.h \ ../jack/ringbuffer.h ../jack/port.h \ ../example-clients/simple_client.c ../example-clients/inprocess.c -EXTRA_DIST=mainpage.dox transport.dox fsm.png +EXTRA_DIST=mainpage.dox transport.dox fsm.png fsm.eps porting.dox INSTIMAGES=reference/html/doxygen.png reference/html/fsm.png diff --git a/doc/mainpage.dox b/doc/mainpage.dox index c437e750..e0a0a80f 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -104,6 +104,14 @@ useful. It includes - simple examples of wrapping a GUI around a JACK application. - tools for checking the status of a running JACK system. +@section porting Porting + +JACK is designed to be portable to any system supporting the relevant +POSIX and ANSI C standards. It currently runs under GNU/Linux and Mac +OS X on several different processor architectures. If you want to +port JACK to another platform, please read the @ref porting-guide +document. + @section license License Copyright (C) 2001-2003 by Paul Davis and others. diff --git a/doc/porting.dox b/doc/porting.dox new file mode 100644 index 00000000..3801d398 --- /dev/null +++ b/doc/porting.dox @@ -0,0 +1,119 @@ +/* + * This file documents the process of porting JACK to new platforms. + * It is part of the JACK reference manual, built using doxygen. + */ + +/** + +@page porting-guide Porting JACK + +The @ref index is designed to be portable to any system supporting the +relevant POSIX and C language standards. It currently works with +GNU/Linux and Mac OS X on several different processor architectures. +This document describes the steps needed to port JACK to another +platform, and the methods used to provide portability. + + - @ref portrequirements + - @ref portoverview + - @ref portopsys + - @ref portcpu + - @ref portissues + +@section portrequirements Requirements + + - Each platform should build directly from CVS or from a tarball + using the GNU @c ./configure tools. Platform-specific toolsets can + by used for development, but the GNU tools should at least work for + basic distribution and configuration. + + - For long-term maintainability we want to minimize the use of + conditional compilation in source files. + + - We should provide generic versions of all system-dependent + headers, so platforms need only provide those they modify. + + - In some cases, operating system-specific information must be able + to override processor-specific data. + +@section portoverview Overview + +JACK relies on two types of platform-specific headers: + + - @ref portopsys + - @ref portcpu + +OS-specific headers take precedence over CPU-specific headers. + +The JACK @c configure.host script and its system-dependent header +directories were adapted from the @c libstdc++-v3 component of the GNU +Compiler Collective, . + + +@section portopsys Operating System Dependencies + +JACK is intended to conform with C99, as defined in International +Standard ISO/IEC 9899. Because many existing C compilers do not fully +support this standard, some new features should be avoided for better +portablility. For example, variables should not be declared in the +middle of a compound statement, because many compilers still cannot +handle that extension to the language. + +Whenever possible, OS dependencies should be isolated in OS-specific +header files. Each target OS may optionally provide a @c + header, otherwise @c +conf/os/generic/os_defines.h will be used. The @c configure.host +script distinguishes OS variations using a case statement based on the +host system's type and version. + +Some needed POSIX features may be missing on certain platforms. If +so, the preferred solution is to provide a substitute, like the @c +fakepoll.c implementation for Mac OS X. + +If conditional compilation is required in mainline +platform-independent code, avoid using the system name. Instead, @c +#define a descriptive name in your @c , and test +it like this: + +@code + #ifdef JACK_USE_MACH_THREADS + allocate_mach_serverport(engine, client); + client->running = FALSE; + #endif +@endcode + +Be sure to place any generic implementation alternative in the @c +#else or use an @c #ifndef, so other OS ports are not required to know +your platform's conditional labels. + +@section portcpu Processor Dependencies + +JACK uses some low-level machine operations for thread-safe updates to +shared memory. A low-level implementation of @c +is provided for every target processor architecture. There is also a +generic implementation using POSIX spin locks, but that is not a good +enough solution for serious use. + +The GCC package provides versions that work on most modern hardware. +We've tried to keep things as close to the original as possible, while +removing a bunch of os-specific files that didn't seem relevant. A +primary goal has been to avoid changing the CPU-dependent @c + headers. + +The relevant GCC documentation provides some helpful background, +especially the @c atomicity.h discussion at +. + + +@section portissues Issues Not Addressed + + - Cross-compilation has not been tested, or even thought through in + much detail. The @a host is the system on which JACK will run. + This may differ from the @a build system doing the compilation. + These are selected using the standard @c ./configure options @c + --host and @c --build. Usually, @c ./config.guess can print the + appropriate canonical name for any system on which it runs. + + - Platform-specific build tools like Apple's Project Builder are not + well-supported. + +*/ diff --git a/doc/reference.doxygen.in b/doc/reference.doxygen.in index 0e6205ae..fec4555c 100644 --- a/doc/reference.doxygen.in +++ b/doc/reference.doxygen.in @@ -363,7 +363,8 @@ WARN_LOGFILE = # with spaces. INPUT = @top_srcdir@/doc/mainpage.dox \ - @top_srcdir@/doc/transport.dox \ + @top_srcdir@/doc/transport.dox \ + @top_srcdir@/doc/porting.dox \ @top_srcdir@/jack/jack.h \ @top_srcdir@/jack/types.h \ @top_srcdir@/jack/transport.h \ diff --git a/drivers/alsa/Makefile.am b/drivers/alsa/Makefile.am index 6961d4a2..427e7694 100644 --- a/drivers/alsa/Makefile.am +++ b/drivers/alsa/Makefile.am @@ -14,7 +14,6 @@ noinst_HEADERS = alsa_driver.h \ generic.h \ hammerfall.h \ hdsp.h \ - ice1712.h \ - memops.h + ice1712.h jack_alsa_la_LIBADD = $(ALSA_LIBS) diff --git a/drivers/alsa/alsa_driver.c b/drivers/alsa/alsa_driver.c index 1e01f5b6..7240e9ee 100644 --- a/drivers/alsa/alsa_driver.c +++ b/drivers/alsa/alsa_driver.c @@ -26,20 +26,22 @@ #include #include #include -#include #include #include #include #include -#include "alsa_driver.h" -#include + #include #include + +#include GETOPT_H +#include + +#include "alsa_driver.h" #include "hammerfall.h" #include "hdsp.h" #include "ice1712.h" #include "generic.h" -#include extern void store_work_time (int); extern void store_wait_time (int); diff --git a/drivers/alsa/alsa_driver.h b/drivers/alsa/alsa_driver.h index e0f911ca..3e005aed 100644 --- a/drivers/alsa/alsa_driver.h +++ b/drivers/alsa/alsa_driver.h @@ -36,7 +36,7 @@ #include #include #include -#include "memops.h" +#include #include typedef void (*ReadCopyFunction) (jack_default_audio_sample_t *dst, char *src, diff --git a/drivers/alsa/memops.c b/drivers/alsa/memops.c index 324f6868..9a0da6c1 100644 --- a/drivers/alsa/memops.c +++ b/drivers/alsa/memops.c @@ -31,7 +31,7 @@ #include #include -#include "memops.h" +#include #define SAMPLE_MAX_24BIT 8388608.0f #define SAMPLE_MAX_16BIT 32768.0f diff --git a/drivers/dummy/dummy_driver.c b/drivers/dummy/dummy_driver.c index 4e158d72..7adb786f 100644 --- a/drivers/dummy/dummy_driver.c +++ b/drivers/dummy/dummy_driver.c @@ -20,6 +20,8 @@ $Id$ */ +#include +#include GETOPT_H #include #include #include @@ -27,13 +29,12 @@ #include #include #include -#include #include #include #include #include -#include +#include #include "dummy_driver.h" diff --git a/drivers/iec61883/iec61883_driver.c b/drivers/iec61883/iec61883_driver.c index 04fa4cef..f2f81af6 100644 --- a/drivers/iec61883/iec61883_driver.c +++ b/drivers/iec61883/iec61883_driver.c @@ -20,9 +20,10 @@ * */ +#include +#include GETOPT_H #include #include -#include #include #include #include diff --git a/drivers/oss/oss_driver.c b/drivers/oss/oss_driver.c index 0c315656..c1d3d467 100644 --- a/drivers/oss/oss_driver.c +++ b/drivers/oss/oss_driver.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include "oss_driver.h" diff --git a/drivers/oss/oss_driver.h b/drivers/oss/oss_driver.h index 14edeef9..1ab16c43 100644 --- a/drivers/oss/oss_driver.h +++ b/drivers/oss/oss_driver.h @@ -30,7 +30,6 @@ #include #include #include -#include #include diff --git a/drivers/portaudio/portaudio_driver.c b/drivers/portaudio/portaudio_driver.c index 414490d9..5696b945 100644 --- a/drivers/portaudio/portaudio_driver.c +++ b/drivers/portaudio/portaudio_driver.c @@ -19,13 +19,27 @@ Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France grame@rd.grame.fr + 02-09-03 : Modify jack port naming : add the name of the used driver + Add the -n option to load a specific driver using it's name + 04-09-03 : Correct bug in -n option management : input and ouput have to be treated separately + 08-09-03 : More robust driver loading code : new portaudio_load_default and portaudio_load_driver functions. + 24-09-03 : Does not tries to load default device if the required one is not found, returns and error. + 14-10-03 : After jack port name size extension, does not use fixed length for CoreAudio driver name anymore + 09-01-04 : Handle different value for channel in and channel out (using -i and -o) + 12-01-04 : Connect port names (inverse "in" and "out") + 13-01-04 : Correct the length of jack port : use JACK_PORT_NAME_SIZE + 22-03-04 : Remove jack_init_time, rename input and ouput ports using "capture" and "playback" + */ +#include +#include GETOPT_H #include #include #include -#include + #include + #include "portaudio_driver.h" @@ -37,8 +51,8 @@ paCallback(void *inputBuffer, void *outputBuffer, portaudio_driver_t * driver = (portaudio_driver_t*)userData; driver->inPortAudio = (float*)inputBuffer; - driver->outPortAudio = (float*)outputBuffer; - + driver->outPortAudio = (float*)outputBuffer; + driver->last_wait_ust = jack_get_microseconds(); return driver->engine->run_cycle(driver->engine, framesPerBuffer, 0); } @@ -48,7 +62,7 @@ portaudio_driver_attach (portaudio_driver_t *driver, jack_engine_t *engine) jack_port_t *port; int port_flags; channel_t chn; - char buf[32]; + char buf[JACK_PORT_NAME_SIZE]; driver->engine = engine; @@ -65,7 +79,7 @@ portaudio_driver_attach (portaudio_driver_t *driver, jack_engine_t *engine) for (chn = 0; chn < driver->capture_nchannels; chn++) { - snprintf (buf, sizeof(buf) - 1, "capture_%lu", chn+1); + snprintf (buf, sizeof(buf) - 1, "%s:capture%lu", driver->driver_name, chn+1); if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) { jack_error ("portaudio: cannot register port for %s", buf); @@ -83,7 +97,7 @@ portaudio_driver_attach (portaudio_driver_t *driver, jack_engine_t *engine) port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal; for (chn = 0; chn < driver->playback_nchannels; chn++) { - snprintf (buf, sizeof(buf) - 1, "playback_%lu", chn+1); + snprintf (buf, sizeof(buf) - 1, "%s:playback%lu", driver->driver_name, chn+1); if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) { jack_error ("portaudio: cannot register port for %s", buf); @@ -229,12 +243,12 @@ portaudio_driver_set_parameters (portaudio_driver_t* driver, nframes, /* frames per buffer */ 0, /* number of buffers = default min */ paClipOff, /* we won't output out of - * range samples so don't - * bother clipping them */ + * range samples so don't + * bother clipping them */ paCallback, driver); - if (err == paNoError) { + if (err == paNoError) { driver->period_usecs = (((float) driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f; @@ -251,7 +265,7 @@ portaudio_driver_set_parameters (portaudio_driver_t* driver, } else { // JOQ: this driver is dead. How do we terminate it? - // Pa_Terminate(); + Pa_Terminate(); fprintf(stderr, "Unable to set portaudio parameters\n"); fprintf(stderr, "Error number: %d\n", err); fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err)); @@ -270,7 +284,7 @@ portaudio_driver_reset_parameters (portaudio_driver_t* driver, return EINVAL; } - Pa_CloseStream(driver->stream); + Pa_CloseStream(driver->stream); return portaudio_driver_set_parameters (driver, nframes, rate); } @@ -302,27 +316,156 @@ portaudio_driver_bufsize (portaudio_driver_t* driver, jack_nframes_t nframes) //== instance creation/destruction ============================================= +static int portaudio_load_default (portaudio_driver_t *driver, + int numDevices, + int capturing, + int playing, + int* inputDeviceID, + int* outputDeviceID) +{ + const PaDeviceInfo *pdi; + int i,j; + int found = 0; + + printf("Look for default driver\n"); + + *inputDeviceID = Pa_GetDefaultInputDeviceID(); + *outputDeviceID = Pa_GetDefaultOutputDeviceID(); + + for(i=0; icapture_nchannels = (capturing) ? pdi->maxInputChannels : 0; + strcpy (driver->driver_name,pdi->name); + found = 1; + } + + if (i == Pa_GetDefaultOutputDeviceID()){ + driver->playback_nchannels = (playing) ? pdi->maxOutputChannels : 0; + strcpy (driver->driver_name,pdi->name); + found = 1; + } + + printf("\nName = %s\n", pdi->name); + printf("Max Inputs = %d ", pdi->maxInputChannels); + printf("Max Outputs = %d\n", pdi->maxOutputChannels); + if( pdi->numSampleRates == -1 ){ + printf("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1]); + }else{ + printf("Sample Rates ="); + for(j=0; jnumSampleRates; j++){ + printf(" %8.2f,", pdi->sampleRates[j]); + } + printf("\n"); + } + + printf("Native Sample Formats = "); + if( pdi->nativeSampleFormats & paInt8 ) printf("paInt8, "); + if( pdi->nativeSampleFormats & paUInt8 ) printf("paUInt8, "); + if( pdi->nativeSampleFormats & paInt16 ) printf("paInt16, "); + if( pdi->nativeSampleFormats & paInt32 ) printf("paInt32, "); + if( pdi->nativeSampleFormats & paFloat32 ) printf("paFloat32, "); + if( pdi->nativeSampleFormats & paInt24 ) printf("paInt24, "); + if( pdi->nativeSampleFormats & paPackedInt24 ) printf("paPackedInt24, "); + printf("\n"); + } + + return found; +} + +static int portaudio_load_driver (portaudio_driver_t *driver, + int numDevices, + int capturing, + int playing, + int* inputDeviceID, + int* outputDeviceID, + char* driver_name) +{ + const PaDeviceInfo *pdi; + int found = 0; + int i,j; + + printf("Look for %s driver\n",driver_name); + + for(i=0; iname) == 0) { + if (strncmp(driver_name,pdi->name,JACK_DRIVER_PARAM_STRING_MAX) == 0) { // compare the JACK_DRIVER_PARAM_STRING_MAX first character + if (pdi->maxInputChannels > 0) { + *inputDeviceID = i; + driver->capture_nchannels = (capturing) ? pdi->maxInputChannels : 0; + strcpy(driver->driver_name,pdi->name); + printf("Found input driver = %s\n", driver_name); + found = 1; + }else if (pdi->maxOutputChannels > 0) { + *outputDeviceID = i; + driver->playback_nchannels = (playing) ? pdi->maxOutputChannels : 0; + strcpy (driver->driver_name,pdi->name); + printf("Found output driver = %s\n", driver_name); + found = 1; + }else { + printf("Found driver without input or ouput = %s\n", driver_name); + } + } + + printf("\nName = %s\n", pdi->name); + printf("Max Inputs = %d ", pdi->maxInputChannels); + printf("Max Outputs = %d\n", pdi->maxOutputChannels); + if( pdi->numSampleRates == -1 ){ + printf("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1]); + }else{ + printf("Sample Rates ="); + for(j=0; jnumSampleRates; j++){ + printf(" %8.2f,", pdi->sampleRates[j]); + } + printf("\n"); + } + + printf("Native Sample Formats = "); + if( pdi->nativeSampleFormats & paInt8 ) printf("paInt8, "); + if( pdi->nativeSampleFormats & paUInt8 ) printf("paUInt8, "); + if( pdi->nativeSampleFormats & paInt16 ) printf("paInt16, "); + if( pdi->nativeSampleFormats & paInt32 ) printf("paInt32, "); + if( pdi->nativeSampleFormats & paFloat32 ) printf("paFloat32, "); + if( pdi->nativeSampleFormats & paInt24 ) printf("paInt24, "); + if( pdi->nativeSampleFormats & paPackedInt24 ) printf("paPackedInt24, "); + printf("\n"); + } + + return found; +} + + /** create a new driver instance */ static jack_driver_t * portaudio_driver_new (char *name, - jack_client_t* client, - jack_nframes_t frames_per_cycle, - jack_nframes_t rate, - int capturing, - int playing, - int chan, - DitherAlgorithm dither) + jack_client_t* client, + jack_nframes_t frames_per_cycle, + jack_nframes_t rate, + int capturing, + int playing, + int chan_in, + int chan_out, + DitherAlgorithm dither, + char* driver_name) { portaudio_driver_t *driver; - PaError err = paNoError; - const PaDeviceInfo *pdi; - int numDevices; - int i,j; - - printf ("creating portaudio driver ... %" PRIu32 "|%" - PRIu32 "\n", frames_per_cycle, rate); - + PaError err = paNoError; + int numDevices; + int inputDeviceID,outputDeviceID; + int found; + + printf ("portaudio driver version : %d\n", kVersion); + printf ("creating portaudio driver ... %" PRIu32 "|%" PRIu32 "\n", + frames_per_cycle, rate); + driver = (portaudio_driver_t *) calloc (1, sizeof (portaudio_driver_t)); jack_driver_init ((jack_driver_t *) driver); @@ -333,109 +476,106 @@ portaudio_driver_new (char *name, } driver->frames_per_cycle = frames_per_cycle; - driver->frame_rate = rate; + driver->frame_rate = rate; driver->capturing = capturing; driver->playing = playing; driver->attach = (JackDriverAttachFunction) portaudio_driver_attach; driver->detach = (JackDriverDetachFunction) portaudio_driver_detach; - driver->read = (JackDriverReadFunction) portaudio_driver_read; + driver->read = (JackDriverReadFunction) portaudio_driver_read; driver->write = (JackDriverReadFunction) portaudio_driver_write; driver->null_cycle = (JackDriverNullCycleFunction) portaudio_driver_null_cycle; driver->bufsize = (JackDriverBufSizeFunction) portaudio_driver_bufsize; - driver->start = (JackDriverStartFunction) portaudio_driver_audio_start; + driver->start = (JackDriverStartFunction) portaudio_driver_audio_start; driver->stop = (JackDriverStopFunction) portaudio_driver_audio_stop; + driver->stream = NULL; - err = Pa_Initialize(); - numDevices = Pa_CountDevices(); - - if( numDevices < 0 ) - { - printf("ERROR: Pa_CountDevices returned 0x%x\n", numDevices ); - err = numDevices; - goto error; - } - - printf("Number of devices = %d\n", numDevices ); - - for( i=0; icapture_nchannels = (capturing) ? pdi->maxInputChannels : 0; - } - if( i == Pa_GetDefaultOutputDeviceID() ){ - driver->playback_nchannels = (playing) ? pdi->maxOutputChannels : 0; - } - printf("\nName = %s\n", pdi->name); - printf("Max Inputs = %d ", pdi->maxInputChannels); - printf("Max Outputs = %d\n", pdi->maxOutputChannels); - if( pdi->numSampleRates == -1 ){ - printf("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1] ); - }else{ - printf("Sample Rates ="); - for(j=0; jnumSampleRates; j++){ - printf(" %8.2f,", pdi->sampleRates[j] ); - } - printf("\n"); - } - - printf("Native Sample Formats = "); - if( pdi->nativeSampleFormats & paInt8 ) printf("paInt8, "); - if( pdi->nativeSampleFormats & paUInt8 ) printf("paUInt8, "); - if( pdi->nativeSampleFormats & paInt16 ) printf("paInt16, "); - if( pdi->nativeSampleFormats & paInt32 ) printf("paInt32, "); - if( pdi->nativeSampleFormats & paFloat32 ) printf("paFloat32, "); - if( pdi->nativeSampleFormats & paInt24 ) printf("paInt24, "); - if( pdi->nativeSampleFormats & paPackedInt24 ) printf("paPackedInt24, "); - printf("\n"); - } - - if(err != paNoError) goto error; - - printf("Pa_GetDefaultOutputDeviceID() %d\n", Pa_GetDefaultOutputDeviceID()); - printf("Pa_GetDefaultInputDeviceID() %d\n", Pa_GetDefaultInputDeviceID()); - - if (chan > 0) { - driver->capture_nchannels = (driver->capture_nchannels < chan) ? driver->capture_nchannels : chan; - driver->playback_nchannels = (driver->playback_nchannels < chan) ? driver->playback_nchannels : chan; - } + err = Pa_Initialize(); + printf("Pa_Initialize OK \n"); + + printf("Driver name required %s\n",driver_name); + + numDevices = Pa_CountDevices(); + + if( numDevices < 0 ) + { + printf("ERROR: Pa_CountDevices returned 0x%x\n", numDevices ); + err = numDevices; + goto error; + } + + printf("Number of devices = %d\n", numDevices); + + if (strcmp(driver_name,"") == 0) { + found = portaudio_load_default(driver,numDevices,capturing,playing,&inputDeviceID,&outputDeviceID); + if (!found) { + printf("ERROR : default driver has not been found\n"); + err = paHostError; + goto error; + } + }else{ + found = portaudio_load_driver(driver,numDevices,capturing,playing,&inputDeviceID,&outputDeviceID,driver_name); + if (!found) { + printf("ERROR : driver %s has not been found \n",driver_name); + err = paHostError; + goto error; + } + } - // JOQ: should use portaudio_driver_set_parameters(), instead - err = Pa_OpenStream(&driver->stream, - ((capturing) ? Pa_GetDefaultInputDeviceID() : paNoDevice), - ((capturing) ? driver->capture_nchannels : 0), - paFloat32, /* 32 bit floating point input */ - NULL, - ((playing) ? Pa_GetDefaultOutputDeviceID() : paNoDevice), - ((playing) ? driver->playback_nchannels : 0), - paFloat32, /* 32 bit floating point output */ - NULL, - rate, - frames_per_cycle, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - paCallback, - driver); - - if (err != paNoError) goto error; - - driver->client = client; - driver->period_usecs = (((float) driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f; + if (err != paNoError) goto error; + + printf("Pa_GetDefaultOutputDeviceID() %ld\n", (long)Pa_GetDefaultOutputDeviceID()); + printf("Pa_GetDefaultInputDeviceID() %ld\n", (long)Pa_GetDefaultInputDeviceID()); + + printf("--------------------------------------------------\n"); + printf("CoreAudio driver %s will be loaded\n", driver->driver_name); + printf("inputDeviceID %ld\n", (long)inputDeviceID); + printf("outputDeviceID %ld\n", (long)outputDeviceID); + printf("driver->capture_nchannels %ld\n", driver->capture_nchannels); + printf("driver->playback_nchannels %ld\n", driver->playback_nchannels); + + printf("chan_in, chan_out %ld %ld\n", (long)chan_in, (long)chan_out); - jack_init_time(); - - return((jack_driver_t *) driver); - + if (chan_in > 0) + driver->capture_nchannels = (driver->capture_nchannels < chan_in) ? driver->capture_nchannels : chan_in; + + if (chan_out > 0) + driver->playback_nchannels = (driver->playback_nchannels < chan_out) ? driver->playback_nchannels : chan_out; + + printf("driver->capture_nchannels %ld\n", driver->capture_nchannels); + printf("driver->playback_nchannels %ld\n", driver->playback_nchannels); + + err = Pa_OpenStream(&driver->stream, + ((capturing && (driver->capture_nchannels > 0)) ? inputDeviceID : paNoDevice), + ((capturing) ? driver->capture_nchannels : 0), + paFloat32, // 32 bit floating point input + NULL, + ((playing && (driver->playback_nchannels > 0)) ? outputDeviceID : paNoDevice), + ((playing) ? driver->playback_nchannels : 0), + paFloat32, // 32 bit floating point output + NULL, + rate, + frames_per_cycle, // frames per buffer + 0, // number of buffers, if zero then use default minimum + paClipOff, // we won't output out of range samples so don't bother clipping them + paCallback, + driver); + + if (err != paNoError) goto error; + + driver->client = client; + driver->period_usecs = (((float) driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f; + + return((jack_driver_t *) driver); + error: - - Pa_Terminate(); - fprintf(stderr, "An error occured while using the portaudio stream\n"); - fprintf(stderr, "Error number: %d\n", err); - fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err)); - free(driver); - return NULL; + + Pa_Terminate(); + fprintf(stderr, "An error occured while using the portaudio stream\n"); + fprintf(stderr, "Error number: %d\n", err); + fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err)); + free(driver); + return NULL; } /** free all memory allocated by a driver instance @@ -461,7 +601,7 @@ driver_get_descriptor () desc = calloc (1, sizeof (jack_driver_desc_t)); strcpy (desc->name, "portaudio"); - desc->nparams = 7; + desc->nparams = 10; desc->params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); @@ -470,7 +610,23 @@ driver_get_descriptor () desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamInt; desc->params[i].value.ui = 0; - strcpy (desc->params[i].short_desc, "Maximium number of channels"); + strcpy (desc->params[i].short_desc, "Maximum number of channels"); + strcpy (desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy (desc->params[i].name, "channelin"); + desc->params[i].character = 'i'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy (desc->params[i].short_desc, "Maximum number of input channels"); + strcpy (desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy (desc->params[i].name, "channelout"); + desc->params[i].character = 'o'; + desc->params[i].type = JackDriverParamInt; + desc->params[i].value.ui = 0; + strcpy (desc->params[i].short_desc, "Maximum number of ouput channels"); strcpy (desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -509,9 +665,17 @@ driver_get_descriptor () strcpy (desc->params[i].name, "period"); desc->params[i].character = 'p'; desc->params[i].type = JackDriverParamUInt; - desc->params[i].value.ui = 128U; + desc->params[i].value.ui = 1024U; strcpy (desc->params[i].short_desc, "Frames per period"); strcpy (desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy (desc->params[i].name, "name"); + desc->params[i].character = 'n'; + desc->params[i].type = JackDriverParamString; + desc->params[i].value.ui = 128U; + strcpy (desc->params[i].short_desc, "Driver name"); + strcpy (desc->params[i].long_desc, desc->params[i].short_desc); i++; strcpy (desc->params[i].name, "dither"); @@ -525,8 +689,6 @@ driver_get_descriptor () " t : triangular\n" " s : shaped\n" " - : no dithering"); - - return desc; } @@ -537,18 +699,25 @@ driver_initialize (jack_client_t *client, const JSList * params) { jack_nframes_t srate = 48000; jack_nframes_t frames_per_interrupt = 1024; + int capture = FALSE; int playback = FALSE; - int chan = -1; + int chan_in = -1; + int chan_out = -1; DitherAlgorithm dither = None; const JSList * node; const jack_driver_param_t * param; - + char *name = ""; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; switch (param->character) { + + case 'n': + name = (char *) param->value.str; + printf("Driver name found %s\n",name); + break; case 'D': capture = TRUE; @@ -556,15 +725,24 @@ driver_initialize (jack_client_t *client, const JSList * params) break; case 'c': - chan = (int) param->value.ui; + chan_in = (int) param->value.ui; + chan_out = (int) param->value.ui; + break; + + case 'i': + chan_in = (int) param->value.ui; + break; + + case 'o': + chan_out = (int) param->value.ui; break; case 'C': - capture = TRUE; + capture = param->value.i; break; case 'P': - playback = TRUE; + playback = param->value.i; break; case 'r': @@ -605,9 +783,11 @@ driver_initialize (jack_client_t *client, const JSList * params) } return portaudio_driver_new ("portaudio", client, frames_per_interrupt, - srate, capture, playback, chan, dither); + srate, capture, playback, chan_in, + chan_out, dither,name); } + void driver_finish (jack_driver_t *driver) { diff --git a/drivers/portaudio/portaudio_driver.h b/drivers/portaudio/portaudio_driver.h index 99e24ad9..6962c781 100644 --- a/drivers/portaudio/portaudio_driver.h +++ b/drivers/portaudio/portaudio_driver.h @@ -23,19 +23,14 @@ #define __jack_portaudio_driver_h__ -#if defined(__APPLE__) && defined(__POWERPC__) -#include -#include -#else -#include "../alsa/memops.h" -#include -#endif +#include PORTAUDIO_H #include #include #include #include #include +#include typedef struct { @@ -57,10 +52,12 @@ typedef struct { JSList *playback_ports; float *inPortAudio; - float *outPortAudio; - + float *outPortAudio; + char driver_name[256]; PortAudioStream* stream; } portaudio_driver_t; +#define kVersion 101 + #endif /* __jack_portaudio_driver_h__ */ diff --git a/example-clients/Makefile.am b/example-clients/Makefile.am index f19e525a..a574034e 100644 --- a/example-clients/Makefile.am +++ b/example-clients/Makefile.am @@ -48,55 +48,56 @@ AM_CFLAGS = -I.. $(JACK_CFLAGS) $(sndfile_cflags) AM_CXXFLAGS = -I.. $(JACK_CFLAGS) $(sndfile_cflags) jack_simple_client_SOURCES = simple_client.c -jack_simple_client_LDFLAGS = -lrt -ldl -lpthread +jack_simple_client_LDFLAGS = -ldl -lpthread @OS_LDFLAGS@ jack_simple_client_LDADD = ../libjack/libjack.la jack_connect_SOURCES = connect.c -jack_connect_LDFLAGS = -lrt -ldl -lpthread +jack_connect_LDFLAGS = -ldl -lpthread @OS_LDFLAGS@ jack_connect_LDADD = ../libjack/libjack.la jack_disconnect_SOURCES = connect.c -jack_disconnect_LDFLAGS = -lrt -ldl -lpthread +jack_disconnect_LDFLAGS = -ldl -lpthread @OS_LDFLAGS@ jack_disconnect_LDADD = ../libjack/libjack.la jack_monitor_client_SOURCES = monitor_client.c -jack_monitor_client_LDFLAGS = -lrt -ldl -lpthread +jack_monitor_client_LDFLAGS = -ldl -lpthread @OS_LDFLAGS@ jack_monitor_client_LDADD = ../libjack/libjack.la jack_metro_SOURCES = metro.c -jack_metro_LDFLAGS = -lrt -ldl -lpthread +jack_metro_LDFLAGS = -ldl -lpthread @OS_LDFLAGS@ jack_metro_LDADD = ../libjack/libjack.la jack_lsp_SOURCES = lsp.c -jack_lsp_LDFLAGS = -lrt -ldl -lpthread +jack_lsp_LDFLAGS = -ldl -lpthread @OS_LDFLAGS@ jack_lsp_LDADD = ../libjack/libjack.la jack_showtime_SOURCES = showtime.c -jack_showtime_LDFLAGS = -lrt -ldl -lpthread +jack_showtime_LDFLAGS = -ldl -lpthread @OS_LDFLAGS@ jack_showtime_LDADD = ../libjack/libjack.la jack_bufsize_SOURCES = bufsize.c -jack_bufsize_LDFLAGS = +jack_bufsize_LDFLAGS = @OS_LDFLAGS@ jack_bufsize_LDADD = ../libjack/libjack.la jack_freewheel_SOURCES = freewheel.c -jack_freewheel_LDFLAGS = +jack_freewheel_LDFLAGS = @OS_LDFLAGS@ jack_freewheel_LDADD = ../libjack/libjack.la if HAVE_SNDFILE jackrec_SOURCES = capture_client.c -jackrec_LDFLAGS = @SNDFILE_LIBS@ -lrt -ldl -lpthread +jackrec_LDFLAGS = @SNDFILE_LIBS@ -ldl -lpthread @OS_LDFLAGS@ jackrec_LDADD = ../libjack/libjack.la endif if HAVE_READLINE jack_transport_SOURCES = transport.c -jack_transport_LDFLAGS = -lhistory -lreadline @READLINE_DEPS@ -lrt -ldl -lpthread +jack_transport_LDFLAGS = -lreadline @READLINE_DEPS@ \ + -ldl -lpthread @OS_LDFLAGS@ jack_transport_LDADD = ../libjack/libjack.la endif jack_impulse_grabber_SOURCES = impulse_grabber.c -jack_impulse_grabber_LDFLAGS = -lrt -ldl -lpthread -lm +jack_impulse_grabber_LDFLAGS = -ldl -lpthread -lm @OS_LDFLAGS@ jack_impulse_grabber_LDADD = ../libjack/libjack.la # @@ -104,11 +105,11 @@ jack_impulse_grabber_LDADD = ../libjack/libjack.la # jack_load_SOURCES = ipload.c -jack_load_LDFLAGS = -lrt -ldl -lpthread -lm +jack_load_LDFLAGS = -ldl -lpthread -lm @OS_LDFLAGS@ jack_load_LDADD = ../libjack/libjack.la jack_unload_SOURCES = ipunload.c -jack_unload_LDFLAGS = -lrt -ldl -lpthread -lm +jack_unload_LDFLAGS = -ldl -lpthread -lm @OS_LDFLAGS@ jack_unload_LDADD = ../libjack/libjack.la # @@ -119,10 +120,10 @@ ip_clientdir = $(ADDON_DIR) ip_client_LTLIBRARIES = inprocess.la intime.la -inprocess_la_LDFLAGS = -module -avoid-version +inprocess_la_LDFLAGS = -module -avoid-version @OS_LDFLAGS@ inprocess_la_SOURCES = inprocess.c -intime_la_LDFLAGS = -module -avoid-version +intime_la_LDFLAGS = -module -avoid-version @OS_LDFLAGS@ intime_la_SOURCES = intime.c dist-hook: dist-check-sndfile diff --git a/example-clients/capture_client.c b/example-clients/capture_client.c index 775554a0..93257ca8 100644 --- a/example-clients/capture_client.c +++ b/example-clients/capture_client.c @@ -22,6 +22,7 @@ $Id$ */ +#include #include #include #include @@ -29,7 +30,7 @@ #include #include #include -#include +#include GETOPT_H #include #include @@ -45,7 +46,7 @@ typedef struct _thread_info { volatile int can_capture; volatile int can_process; volatile int status; -} thread_info_t; +} jack_thread_info_t; /* JACK data */ unsigned int nports; @@ -65,7 +66,7 @@ long overruns = 0; void * disk_thread (void *arg) { - thread_info_t *info = (thread_info_t *) arg; + jack_thread_info_t *info = (jack_thread_info_t *) arg; static jack_nframes_t total_captured = 0; jack_nframes_t samples_per_frame = info->channels; size_t bytes_per_frame = samples_per_frame * sample_size; @@ -116,7 +117,7 @@ process (jack_nframes_t nframes, void *arg) { int chn; size_t i; - thread_info_t *info = (thread_info_t *) arg; + jack_thread_info_t *info = (jack_thread_info_t *) arg; /* Do nothing until we're ready to begin. */ if ((!info->can_process) || (!info->can_capture)) @@ -158,7 +159,7 @@ jack_shutdown (void *arg) } void -setup_disk_thread (thread_info_t *info) +setup_disk_thread (jack_thread_info_t *info) { SF_INFO sf_info; int short_mask; @@ -195,7 +196,7 @@ setup_disk_thread (thread_info_t *info) } void -run_disk_thread (thread_info_t *info) +run_disk_thread (jack_thread_info_t *info) { info->can_capture = 1; pthread_join (info->thread_id, NULL); @@ -213,7 +214,7 @@ run_disk_thread (thread_info_t *info) } void -setup_ports (int sources, char *source_names[], thread_info_t *info) +setup_ports (int sources, char *source_names[], jack_thread_info_t *info) { unsigned int i; size_t in_size; @@ -261,7 +262,7 @@ main (int argc, char *argv[]) { jack_client_t *client; - thread_info_t thread_info; + jack_thread_info_t thread_info; int c; int longopt_index = 0; extern int optind, opterr; diff --git a/example-clients/impulse_grabber.c b/example-clients/impulse_grabber.c index 2eac2a15..c5a3d835 100644 --- a/example-clients/impulse_grabber.c +++ b/example-clients/impulse_grabber.c @@ -18,12 +18,13 @@ * $Id$ */ +#include #include #include #include #include #include -#include +#include GETOPT_H #include diff --git a/example-clients/inprocess.c b/example-clients/inprocess.c index 8847db52..550044b8 100644 --- a/example-clients/inprocess.c +++ b/example-clients/inprocess.c @@ -4,7 +4,7 @@ * that runs within the JACK server process. * * For the sake of example, a port_pair_t is allocated in - * jack_initialize(), passed to process() as an argument, then freed + * jack_initialize(), passed to inprocess() as an argument, then freed * in jack_finish(). */ @@ -15,7 +15,7 @@ /** * For the sake of example, an instance of this struct is allocated in - * jack_initialize(), passed to process() as an argument, then freed + * jack_initialize(), passed to inprocess() as an argument, then freed * in jack_finish(). */ typedef struct { @@ -25,14 +25,15 @@ typedef struct { /** * Called in the realtime thread on every process cycle. The entry - * point name was passed to jack_set_process_callback() by - * jack_initialize(). + * point name was passed to jack_set_process_callback() from + * jack_initialize(). Although this is an internal client, its + * process() interface is identical to @ref simple_client.c. * * @return 0 if successful; otherwise jack_finish() will be called and * the client terminated immediately. */ int -process (jack_nframes_t nframes, void *arg) +inprocess (jack_nframes_t nframes, void *arg) { port_pair_t *pp = arg; jack_default_audio_sample_t *out = @@ -63,7 +64,7 @@ jack_initialize (jack_client_t *client, const char *so_data) if (pp == NULL) return 1; /* heap exhausted */ - jack_set_process_callback (client, process, pp); + jack_set_process_callback (client, inprocess, pp); /* create a pair of ports */ pp->input_port = jack_port_register (client, "input", @@ -96,9 +97,9 @@ jack_initialize (jack_client_t *client, const char *so_data) * This required entry point is called immediately before the client * is unloaded, which could happen due to a call to * jack_internal_client_close(), or a nonzero return from either - * jack_initialize() or process(). + * jack_initialize() or inprocess(). * - * @param arg the same parameter provided to process(). + * @param arg the same parameter provided to inprocess(). */ void jack_finish (void *arg) diff --git a/example-clients/lsp.c b/example-clients/lsp.c index 26529a83..6613b005 100644 --- a/example-clients/lsp.c +++ b/example-clients/lsp.c @@ -1,8 +1,9 @@ +#include #include #include #include #include -#include +#include GETOPT_H #include diff --git a/example-clients/metro.c b/example-clients/metro.c index a20100c7..17c0e1af 100644 --- a/example-clients/metro.c +++ b/example-clients/metro.c @@ -16,15 +16,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include #include #include +#include GETOPT_H +#include + #include #include -#include -#include typedef jack_default_audio_sample_t sample_t; diff --git a/jack.pc.in b/jack.pc.in index fce463bb..6c77aca7 100644 --- a/jack.pc.in +++ b/jack.pc.in @@ -6,5 +6,5 @@ includedir=@includedir@ Name: jack Description: the Jack Audio Connection Kit: a low-latency synchronous callback-based media server Version: @JACK_VERSION@ -Libs: -L${libdir} -ljack -lpthread -ldl -lrt +Libs: -L${libdir} -ljack -lpthread -ldl Cflags: -I${includedir} diff --git a/jack/Makefile.am b/jack/Makefile.am index 673ccc39..15839817 100644 --- a/jack/Makefile.am +++ b/jack/Makefile.am @@ -10,19 +10,18 @@ libjackinclude_HEADERS = \ types.h noinst_HEADERS = \ - cycles.h \ + atomicity.h \ driver.h \ + driver_interface.h \ + driver_parse.h \ engine.h \ hardware.h \ internal.h \ jslist.h \ + memops.h \ pool.h \ port.h \ ringbuffer.h \ shm.h \ start.h \ - time.h \ - version.h \ - driver_interface.h \ - driver_parse.h - + version.h diff --git a/jack/atomicity.h b/jack/atomicity.h new file mode 100644 index 00000000..5e949f61 --- /dev/null +++ b/jack/atomicity.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2004 Jack O'Quin + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __jack_atomicity_h__ +#define __jack_atomicity_h__ + +/* + * Interface with various machine-dependent headers derived from the + * gcc/libstdc++.v3 sources. We try to modify the GCC sources as + * little as possible. The following include is resolved using the + * config/configure.hosts mechanism. It will use an OS-dependent + * version if available, otherwise the one for this CPU. Some of + * these files might not work with older GCC compilers. + */ +#include + +/* These functions are defined for each platform. The C++ library + * function names start with "__" to avoid namespace pollution. */ +#define exchange_and_add __exchange_and_add +#define atomic_add __atomic_add + +#endif /* __jack_atomicity_h__ */ diff --git a/jack/engine.h b/jack/engine.h index 189019b1..08493d11 100644 --- a/jack/engine.h +++ b/jack/engine.h @@ -137,7 +137,7 @@ struct _jack_engine { float spare_usecs; float usecs_per_cycle; -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* specific resources for server/client real-time thread communication */ mach_port_t servertask, bp; int portnum; diff --git a/jack/internal.h b/jack/internal.h index 32de811b..e6c00f1a 100644 --- a/jack/internal.h +++ b/jack/internal.h @@ -27,29 +27,35 @@ #ifndef __jack_internal_h__ #define __jack_internal_h__ +#include + #include #include #include #include +#include #include #include -#include -#if defined(__APPLE__) && defined(__POWERPC__) - #include "mach_port.h" -#endif +/* Needed by */ +extern void jack_error (const char *fmt, ...); #include #include #include #include -#include +#include +#include + +#ifdef JACK_USE_MACH_THREADS +#include +#endif #ifdef DEBUG_ENABLED #define DEBUG(format,args...) \ fprintf (stderr, "jack:%5d:%" PRIu64 " %s:%s:%d: " format "\n", getpid(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args) #else -#if defined(__APPLE__) && defined(__POWERPC__) +#if JACK_CPP_VARARGS_BROKEN #define DEBUG(format...) #else #define DEBUG(format,args...) @@ -92,7 +98,7 @@ typedef struct { jack_position_t pending_time; /* position for next cycle */ jack_position_t request_time; /* latest requested position */ jack_unique_t prev_request; /* previous request unique ID */ - volatile uint32_t seq_number; /* unique ID sequence number */ + volatile _Atomic_word seq_number; /* unique ID sequence number */ int8_t new_pos; /* new position this cycle */ int8_t pending_pos; /* new position request pending */ jack_nframes_t pending_frame; /* pending frame number */ @@ -112,7 +118,7 @@ typedef struct { float cpu_load; uint32_t port_max; int32_t engine_ok; - uint32_t n_port_types; + jack_port_type_id_t n_port_types; jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES]; jack_port_shared_t ports[0]; @@ -249,7 +255,7 @@ typedef struct { jack_client_control_t *client_control; /* JOQ: 64/32 problem */ jack_control_t *engine_control; /* JOQ: 64/32 problem */ -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* specific resources for server/client real-time thread communication */ int32_t portnum; #endif @@ -338,13 +344,13 @@ typedef struct _jack_client_internal { void (*finish)(void *); /* internal clients only */ int error; -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* specific resources for server/client real-time thread communication */ mach_port_t serverport; trivial_message message; int running; int portnum; -#endif +#endif /* JACK_USE_MACH_THREADS */ } jack_client_internal_t; @@ -364,8 +370,6 @@ extern char *jack_server_dir; extern void *jack_zero_filled_buffer; -extern void jack_error (const char *fmt, ...); - extern jack_port_functions_t jack_builtin_audio_functions; extern jack_port_type_info_t jack_builtin_port_types[]; diff --git a/jack/jack.h b/jack/jack.h index 84862d0e..bec9ad03 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -148,15 +148,16 @@ int jack_set_freewheel_callback (jack_client_t *client, void *arg); /** - * Start or stop JACK's "freewheel" mode. + * Start/Stop JACK's "freewheel" mode. * - * When in "freewheel" mode, JACK no longer waits for any external - * event to begin the start of the next process cycle. External - * hardware I/O is muted. + * When in "freewheel" mode, JACK no longer waits for + * any external event to begin the start of the next process + * cycle. * - * As a result, freewheel mode causes "faster than realtime" execution - * of a JACK graph. If possessed, real-time scheduling is dropped when - * entering freewheel mode, and reacquired when stopping. + * As a result, freewheel mode causes "faster than realtime" + * execution of a JACK graph. If possessed, real-time + * scheduling is dropped when entering freewheel mode, and + * if appropriate it is reacquired when stopping. * * @param client pointer to JACK client structure * @param onoff if non-zero, freewheel mode starts. Otherwise diff --git a/jack/memops.h b/jack/memops.h new file mode 100644 index 00000000..ba310c4b --- /dev/null +++ b/jack/memops.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 1999-2000 Paul Davis + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __jack_memops_h__ +#define __jack_memops_h__ + +#include + +typedef enum { + None, + Rectangular, + Triangular, + Shaped +} DitherAlgorithm; + +#define DITHER_BUF_SIZE 8 +#define DITHER_BUF_MASK 7 + +typedef struct { + unsigned int depth; + float rm1; + unsigned int idx; + float e[DITHER_BUF_SIZE]; +} dither_state_t; + + +void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); + +void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_rect_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); + +void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); +void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); +void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); + +void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); +void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); + +static __inline__ void +sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) + +{ + while (cnt--) { + *dst += *src; + dst++; + src++; + } +} + +static __inline__ void +sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) + +{ + memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t)); +} + +void memset_interleave (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes); +void memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); + +void memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); +void memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); +void memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); + +void merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); +void merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); +void merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); + +void merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); +void merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); + +#endif /* __jack_memops_h__ */ diff --git a/jack/types.h b/jack/types.h index e7baa5ed..0cc0965a 100644 --- a/jack/types.h +++ b/jack/types.h @@ -41,15 +41,7 @@ typedef uint32_t jack_nframes_t; * Type used to represent the value of free running * monotonic clock with units of microseconds. */ - -/* JOQ: this is trouble. APPLE POWERPC should use a compatible - * typedef, explicitly converting from double, if necessary. - * Otherwise applications cannot safely print a jack_time_t. */ -#if defined(__APPLE__) && defined(__POWERPC__) -typedef double jack_time_t; -#else typedef uint64_t jack_time_t; -#endif /** * jack_port_t is an opaque type. You may only access it using the diff --git a/jack/version.h.in b/jack/version.h.in index fb4fd8b2..d2626658 100644 --- a/jack/version.h.in +++ b/jack/version.h.in @@ -1,5 +1,7 @@ /* Copyright (C) 2003 Paul Davis + + @configure_input@ 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 @@ -14,6 +16,5 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ #define jack_protocol_version @JACK_PROTOCOL_VERSION@ diff --git a/jackd/Makefile.am b/jackd/Makefile.am index cdf7fe34..0ac11b36 100644 --- a/jackd/Makefile.am +++ b/jackd/Makefile.am @@ -24,7 +24,7 @@ bin_PROGRAMS = jackd $(CAP_PROGS) AM_CFLAGS = $(JACK_CFLAGS) -DJACK_LOCATION=\"$(bindir)\" jackd_SOURCES = jackd.c engine.c transengine.c -jackd_LDADD = ../libjack/libjack.la -lm -ldl -lrt -lpthread $(CAP_LIBS) +jackd_LDADD = ../libjack/libjack.la -lm -ldl -lpthread $(CAP_LIBS) @OS_LDFLAGS@ noinst_HEADERS = jack_md5.h md5.h md5_loc.h transengine.h diff --git a/jackd/engine.c b/jackd/engine.c index fa04903d..3029ab39 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -19,17 +19,11 @@ $Id$ */ +#include + #include #include #include - -#if defined(__APPLE__) && defined(__POWERPC__) - #include "fakepoll.h" - #include "ipc.h" -#else - #include -#endif - #include #include #include @@ -38,21 +32,22 @@ #include #include #include -#include #include #include -#include #include #include -#include - #include #include #include -#include #include #include +#include +#include + +#ifndef JACK_DO_NOT_MLOCK +#include +#endif /* JACK_DO_NOT_MLOCK */ #ifdef USE_CAPABILITIES /* capgetp and capsetp are linux only extensions, not posix */ @@ -454,7 +449,8 @@ jack_resize_port_segment (jack_engine_t *engine, memset (jack_zero_filled_buffer, 0, one_buffer); } - if (engine->control->real_time && engine->control->do_mlock) { +#ifndef JACK_DO_NOT_MLOCK + if (engine->control->real_time) { /* Although we've called mlockall(CURRENT|FUTURE), the * Linux VM manager still allows newly allocated pages @@ -471,6 +467,7 @@ jack_resize_port_segment (jack_engine_t *engine, "%s", strerror(errno)); } } +#endif /* JACK_DO_NOT_MLOCK */ /* Tell everybody about this segment. */ event.type = AttachPortSegment; @@ -577,7 +574,7 @@ jack_process_internal(jack_engine_t *engine, JSList *node, return jack_slist_next (node); } -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS static JSList * jack_process_external(jack_engine_t *engine, JSList *node) { @@ -595,11 +592,14 @@ jack_process_external(jack_engine_t *engine, JSList *node) ctl->awake_at = 0; ctl->finished_at = 0; - jack_client_resume(client); + if (jack_client_resume(client) < 0) { + jack_error("Client will be removed\n"); + ctl->state = Finished; + } return jack_slist_next (node); } -#else +#else /* !JACK_USE_MACH_THREADS */ static JSList * jack_process_external(jack_engine_t *engine, JSList *node) { @@ -610,7 +610,7 @@ jack_process_external(jack_engine_t *engine, JSList *node) jack_client_internal_t *client; jack_client_control_t *ctl; jack_time_t now, then; - + client = (jack_client_internal_t *) node->data; ctl = client->control; @@ -731,7 +731,7 @@ jack_process_external(jack_engine_t *engine, JSList *node) return node; } -#endif +#endif /* JACK_USE_MACH_THREADS */ static int @@ -1022,8 +1022,8 @@ setup_client (jack_engine_t *engine, int client_fd, res->engine_shm = engine->control_shm; res->realtime = engine->control->real_time; res->realtime_priority = engine->rtpriority - 1; - -#if defined(__APPLE__) && defined(__POWERPC__) + +#ifdef JACK_USE_MACH_THREADS /* specific resources for server/client real-time thread * communication */ res->portnum = client->portnum; @@ -1840,9 +1840,9 @@ jack_server_thread (void *arg) (engine, pfd[i].fd)) { jack_error ("could not handle external" " client request"); -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* poll is implemented using - select (see the fakepool + select (see the macosx/fakepoll code). When the socket is closed select does not return any error, POLLIN is true and the next read @@ -1854,7 +1854,7 @@ jack_server_thread (void *arg) */ handle_client_socket_error(engine, pfd[i].fd); -#endif +#endif /* JACK_USE_MACH_THREADS */ } } } @@ -2068,8 +2068,8 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int temporary, engine->control->has_capabilities = 0; -#if defined(__APPLE__) && defined(__POWERPC__) - /* specific ressources for server/client real-time thread +#ifdef JACK_USE_MACH_THREADS + /* specific resources for server/client real-time thread * communication */ engine->servertask = mach_task_self(); if (task_get_bootstrap_port(engine->servertask, &engine->bp)){ @@ -2077,7 +2077,7 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int temporary, return 0; } engine->portnum = 0; -#endif +#endif /* JACK_USE_MACH_THREADS */ #ifdef USE_CAPABILITIES @@ -2131,18 +2131,16 @@ jack_become_real_time (jack_engine_t *engine, pthread_t thread, int priority) return -1; } -#if defined(__APPLE__) && defined(__POWERPC__) - // To be implemented -#else +#ifndef JACK_DO_NOT_MLOCK if (engine->control->do_mlock && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) { jack_error ("cannot lock down memory for RT thread (%s)", strerror (errno)); #ifdef ENSURE_MLOCK - return -1; + return -1; #endif /* ENSURE_MLOCK */ } -#endif +#endif /* JACK_DO_NOT_MLOCK */ return 0; } @@ -2168,7 +2166,6 @@ jack_watchdog_thread (void *arg) while (1) { usleep (5000000); - pthread_testcancel(); if ( engine->watchdog_check == 0) { jack_error ("jackd watchdog: timeout - killing jackd"); @@ -2183,6 +2180,11 @@ jack_watchdog_thread (void *arg) kill (-getpgrp(), SIGABRT); /*NOTREACHED*/ exit (1); + +#if 0 /* suppress watchdog message */ + } else { + VERBOSE(engine, "jackd watchdog: all is well.\n"); +#endif } engine->watchdog_check = 0; } @@ -2564,7 +2566,7 @@ jack_setup_client_control (jack_engine_t *engine, int fd, jack_transport_client_new (client); -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* specific resources for server/client real-time thread * communication */ allocate_mach_serverport(engine, client); diff --git a/jackd/jackd.c b/jackd/jackd.c index 0d1c16c7..dfefb89a 100644 --- a/jackd/jackd.c +++ b/jackd/jackd.c @@ -19,9 +19,12 @@ $Id$ */ +#include +#include + #include #include -#include +#include GETOPT_H #include #include #include @@ -31,8 +34,6 @@ #include #include -#include - #include #include #include @@ -144,7 +145,8 @@ jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params) fprintf (stderr, "loading driver ..\n"); if (jack_engine_load_driver (engine, driver_desc, driver_params)) { - fprintf (stderr, "cannot load driver module %s\n", driver_desc->name); + fprintf (stderr, "cannot load driver module %s\n", + driver_desc->name); return -1; } @@ -255,7 +257,6 @@ jack_drivers_get_descriptor (JSList * drivers, const char * sofile) jack_error ("error closing driver .so '%s': %s\n", filename, dlerror ()); } - /* check it doesn't exist already */ for (node = drivers; node; node = jack_slist_next (node)) { other_descriptor = (jack_driver_desc_t *) node->data; @@ -377,7 +378,7 @@ int main (int argc, char *argv[]) { - jack_driver_desc_t * desc; + jack_driver_desc_t * desc; const char *options = "-ad:P:vshVRTFl:t:m"; struct option long_options[] = { diff --git a/libjack/ChangeLog b/libjack/ChangeLog index 353dc342..202479d5 100644 --- a/libjack/ChangeLog +++ b/libjack/ChangeLog @@ -6,6 +6,12 @@ int jack_port_name_size(void); int jack_port_type_size(void); +2004-02-16 Jack O'Quin + + * Changed JACK_PORT_NAME_SIZE from 32 to 256 + + This could affect some client that defines its own value. + 2003-10-15 Paul Davis * new ring buffer interface: diff --git a/libjack/Makefile.am b/libjack/Makefile.am index 058daaa0..46ea29fe 100644 --- a/libjack/Makefile.am +++ b/libjack/Makefile.am @@ -20,6 +20,6 @@ AM_CXXFLAGS = $(JACK_CFLAGS) libjack_la_CFLAGS = $(AM_CFLAGS) libjack_la_SOURCES = $(SOURCE_FILES) -libjack_la_LIBADD = -lm -lpthread -lrt +libjack_la_LIBADD = -lm -lpthread @OS_LDFLAGS@ libjack_la_LDFLAGS = -export-dynamic -version-info @JACK_SO_VERSION@ diff --git a/libjack/client.c b/libjack/client.c index a0a97bcd..59575f44 100644 --- a/libjack/client.c +++ b/libjack/client.c @@ -19,42 +19,40 @@ $Id$ */ -#if defined(__APPLE__) && defined(__POWERPC__) - #include "pThreadUtilities.h" - #include "ipc.h" - #include "fakepoll.h" -#else - #include -#endif +#include -#include -#include #include #include #include -#include -#include -#include - #include #include #include #include -#include - -#include +#include +#include +#include +#include -#include #include +#include #include #include -#include #include #include #include +#include +JACK_TIME_GLOBAL_DECL; /* One instance per process. */ + #include "local.h" +#include +#include + +#ifdef JACK_USE_MACH_THREADS +#include +#endif + #ifdef WITH_TIMESTAMPS #include #endif /* WITH_TIMESTAMPS */ @@ -168,6 +166,9 @@ jack_client_alloc () client->engine = NULL; client->control = NULL; client->thread_ok = FALSE; +#if JACK_USE_MACH_THREADS + client->rt_thread_ok = FALSE; +#endif client->first_active = TRUE; client->on_shutdown = NULL; client->n_port_types = 0; @@ -433,7 +434,7 @@ _start_server (void) } if (!good) { -#if defined(__APPLE__) && defined(__POWERPC__) +#if 0 /* JOQ: need a good way to select the right default MACOSX driver */ command = JACK_LOCATION "/jackd"; strncpy(arguments, JACK_LOCATION "/jackd -T -d portaudio -p 512", 255); #elif defined(USE_CAPABILITIES) @@ -624,7 +625,7 @@ jack_attach_port_segment (jack_client_t *client, jack_port_type_id_t ptid) client->port_segment = (jack_shm_info_t*) realloc (client->port_segment, sizeof (jack_shm_info_t) * (ptid+1)); - + memset (&client->port_segment[client->n_port_types], 0, sizeof (jack_shm_info_t) * @@ -636,7 +637,14 @@ jack_attach_port_segment (jack_client_t *client, jack_port_type_id_t ptid) /* release any previous segment */ +#if JACK_USE_MACH_THREADS + /* Stephane Letz : letz@grame.fr + Need a fix : this crash on MacOSX : temporary removed + jack_release_shm (&client->port_segment[ptid]); + */ +#else jack_release_shm (&client->port_segment[ptid]); +#endif } /* get the index into the shm registry */ @@ -747,7 +755,7 @@ jack_client_new (const char *client_name) client->event_fd = ev_fd; -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* specific resources for server/client real-time thread * communication */ client->clienttask = mach_task_self(); @@ -761,7 +769,7 @@ jack_client_new (const char *client_name) jack_error("Can't allocate mach port"); goto fail; }; -#endif +#endif /* JACK_USE_MACH_THREADS */ return client; fail: @@ -815,6 +823,24 @@ jack_internal_client_close (const char *client_name) return; } +#if JACK_USE_MACH_THREADS + +int +jack_drop_real_time_scheduling (pthread_t thread) +{ + setThreadToPriority(thread, 31, false, 10000000); + return 0; +} + +int +jack_acquire_real_time_scheduling (pthread_t thread, int priority) //priority is unused +{ + setThreadToPriority(thread, 96, true, 10000000); + return 0; +} + +#else + int jack_drop_real_time_scheduling (pthread_t thread) { @@ -849,6 +875,8 @@ jack_acquire_real_time_scheduling (pthread_t thread, int priority) return 0; } +#endif + int jack_set_freewheel (jack_client_t* client, int onoff) { @@ -863,7 +891,11 @@ jack_start_freewheel (jack_client_t* client) jack_client_control_t *control = client->control; if (client->engine->real_time) { +#if JACK_USE_MACH_THREADS + jack_drop_real_time_scheduling (client->process_thread); +#else jack_drop_real_time_scheduling (client->thread); +#endif } if (control->freewheel_cb) { @@ -881,8 +913,13 @@ jack_stop_freewheel (jack_client_t* client) } if (client->engine->real_time) { +#if JACK_USE_MACH_THREADS + jack_acquire_real_time_scheduling (client->process_thread, + client->engine->client_priority); +#else jack_acquire_real_time_scheduling (client->thread, client->engine->client_priority); +#endif } } @@ -1164,7 +1201,7 @@ jack_client_thread (void *arg) } -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* real-time thread : separated from the normal client thread, it will * communicate with the server using fast mach RPC mechanism */ @@ -1176,14 +1213,17 @@ jack_client_process_thread (void *arg) int err = 0; client->control->pid = getpid(); - DEBUG ("client process thread is now running"); + DEBUG ("client process thread is now running"); - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + client->rt_thread_ok = TRUE; while (err == 0) { if (jack_client_suspend(client) < 0) { - pthread_exit (0); + jack_error ("jack_client_process_thread : resume error"); + goto zombie; } control->awake_at = jack_get_microseconds(); @@ -1192,6 +1232,9 @@ jack_client_process_thread (void *arg) control->state = Running; + if (control->sync_cb) + jack_call_sync_client (client); + if (control->process) { if (control->process (control->nframes, control->process_arg) == 0) { @@ -1200,6 +1243,9 @@ jack_client_process_thread (void *arg) } else { control->state = Finished; } + + if (control->timebase_cb) + jack_call_timebase_master (client); control->finished_at = jack_get_microseconds(); @@ -1226,27 +1272,31 @@ jack_client_process_thread (void *arg) jack_error ("jack_client_process_thread : zombified"); + client->rt_thread_ok = FALSE; + if (client->on_shutdown) { jack_error ("zombified - calling shutdown handler"); client->on_shutdown (client->on_shutdown_arg); } else { jack_error ("zombified - exiting from JACK"); - jack_client_close (client); /* Need a fix : possibly make client crash if zombified without shutdown handler */ + jack_client_close (client); /* Need a fix : possibly make client crash if zombified without shutdown handler */ } pthread_exit (0); /*NOTREACHED*/ return 0; } -#endif +#endif /* JACK_USE_MACH_THREADS */ static int jack_start_thread (jack_client_t *client) { - pthread_attr_t *attributes = 0; +#ifndef JACK_USE_MACH_THREADS int policy = SCHED_OTHER; struct sched_param client_param, temp_param; +#endif + pthread_attr_t *attributes = 0; if (client->engine->real_time) { @@ -1282,9 +1332,7 @@ jack_start_thread (jack_client_t *client) return -1; } -#if defined(__APPLE__) && defined(__POWERPC__) - // To be implemented -#else +#ifndef JACK_DO_NOT_MLOCK if (client->engine->do_mlock && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) { jack_error ("cannot lock down memory for RT thread (%s)", @@ -1293,23 +1341,17 @@ jack_start_thread (jack_client_t *client) return -1; #endif /* ENSURE_MLOCK */ } -#endif - +#endif /* JACK_DO_NOT_MLOCK */ } + +#ifdef JACK_USE_MACH_THREADS if (pthread_create (&client->thread, attributes, jack_client_thread, client)) { - if (client->engine->real_time) { - /* we are probably dealing with a broken glibc so try - to work around the bug, see below for more details - */ - goto realtime_workaround; - } return -1; } - -#if defined(__APPLE__) && defined(__POWERPC__) - /* a spcial real-time thread to call the "process" + + /* a special real-time thread to call the "process" * callback. It will communicate with the server using fast * mach RPC mechanism */ if (pthread_create (&client->process_thread, attributes, @@ -1319,18 +1361,22 @@ jack_start_thread (jack_client_t *client) } if (client->engine->real_time){ /* time constraint thread */ - setThreadToPriority(client->process_thread, 96, true, 10000000); + setThreadToPriority(client->process_thread, 96, TRUE, 10000000); }else{ /* fixed priority thread */ - setThreadToPriority(client->process_thread, 63, true, 10000000); + setThreadToPriority(client->process_thread, 63, TRUE, 10000000); } -#endif - - return 0; - /* we get here only with engine running realtime */ +#else /* !JACK_USE_MACH_THREADS */ - realtime_workaround: + if (pthread_create (&client->thread, attributes, + jack_client_thread, client) == 0) { + return 0; + } + + if (!client->engine->real_time) { + return -1; + } /* the version of glibc I've played with has a bug that makes that code fail when running under a non-root user but with the @@ -1420,6 +1466,8 @@ jack_start_thread (jack_client_t *client) } } } +#endif /* JACK_USE_MACH_THREADS */ + return 0; } @@ -1433,22 +1481,13 @@ jack_activate (jack_client_t *client) * usage in jack_start_thread()) */ -#if defined(__APPLE__) && defined(__POWERPC__) -/* a bigger stack makes the application crash... */ -#define BIG_ENOUGH_STACK 10000 -#else -#define BIG_ENOUGH_STACK 1048576 -#endif - - char buf[BIG_ENOUGH_STACK]; + char buf[JACK_THREAD_STACK_TOUCH]; int i; - for (i = 0; i < BIG_ENOUGH_STACK; i++) { + for (i = 0; i < JACK_THREAD_STACK_TOUCH; i++) { buf[i] = (char) (i & 0xff); } -#undef BIG_ENOUGH_STACK - if (client->control->type == ClientInternal || client->control->type == ClientDriver) { goto startit; @@ -1546,6 +1585,16 @@ jack_client_close (jack_client_t *client) } if (client->control->type == ClientExternal) { + +#if JACK_USE_MACH_THREADS + if (client->rt_thread_ok) { + // MacOSX pthread_cancel not implemented in + // Darwin 5.5, 6.4 + mach_port_t machThread = + pthread_mach_thread_np (client->process_thread); + thread_terminate (machThread); + } +#endif /* stop the thread that communicates with the jack * server, only if it was actually running @@ -1889,69 +1938,3 @@ jack_port_type_size(void) { return JACK_PORT_TYPE_SIZE; } - -#if defined(__APPLE__) && defined(__POWERPC__) - -double __jack_time_ratio; - -void jack_init_time () -{ - mach_timebase_info_data_t info; - mach_timebase_info(&info); - __jack_time_ratio = ((float)info.numer/info.denom) / 1000; -} -#else - -jack_time_t -jack_get_mhz (void) -{ - FILE *f = fopen("/proc/cpuinfo", "r"); - if (f == 0) - { - perror("can't open /proc/cpuinfo\n"); - exit(1); - } - - for ( ; ; ) - { - jack_time_t mhz; - int ret; - char buf[1000]; - - if (fgets(buf, sizeof(buf), f) == NULL) { - jack_error ("FATAL: cannot locate cpu MHz in " - "/proc/cpuinfo\n"); - exit(1); - } - -#if defined(__powerpc__) - ret = sscanf(buf, "clock\t: %" SCNu64 "MHz", &mhz); -#elif defined( __i386__ ) || defined (__hppa__) || defined (__ia64__) || \ - defined(__x86_64__) - ret = sscanf(buf, "cpu MHz : %" SCNu64, &mhz); -#elif defined( __sparc__ ) - ret = sscanf(buf, "Cpu0Bogo : %" SCNu64, &mhz); -#elif defined( __mc68000__ ) - ret = sscanf(buf, "Clocking: %" SCNu64, &mhz); -#elif defined( __s390__ ) - ret = sscanf(buf, "bogomips per cpu: %" SCNu64, &mhz); -#else /* MIPS, ARM, alpha */ - ret = sscanf(buf, "BogoMIPS : %" SCNu64, &mhz); -#endif - - if (ret == 1) - { - fclose(f); - return (jack_time_t)mhz; - } - } -} - -jack_time_t __jack_cpu_mhz; - -void jack_init_time () -{ - __jack_cpu_mhz = jack_get_mhz (); -} - -#endif diff --git a/libjack/driver.c b/libjack/driver.c index 9af751fb..addc4ff4 100644 --- a/libjack/driver.c +++ b/libjack/driver.c @@ -19,20 +19,22 @@ $Id$ */ +#include #include #include #include #include #include -#include #include -#include - -#include #include +#include #include +#ifndef JACK_DO_NOT_MLOCK +#include +#endif /* JACK_DO_NOT_MLOCK */ + static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; } static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; } static int dummy_write (jack_driver_t *drv, @@ -105,6 +107,7 @@ jack_driver_nt_become_real_time (jack_driver_nt_t* driver) return -1; } +#ifndef JACK_DO_NOT_MLOCK if (driver->engine->control->do_mlock && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) { jack_error ("cannot lock down memory for RT thread (%s)", @@ -113,6 +116,7 @@ jack_driver_nt_become_real_time (jack_driver_nt_t* driver) return -1; #endif /* ENSURE_MLOCK */ } +#endif /* JACK_DO_NOT_MLOCK */ return 0; } diff --git a/libjack/local.h b/libjack/local.h index 4336e85b..55f24b9f 100644 --- a/libjack/local.h +++ b/libjack/local.h @@ -31,11 +31,12 @@ struct _jack_client { char first_active : 1; pthread_t thread_id; -#if defined(__APPLE__) && defined(__POWERPC__) +#ifdef JACK_USE_MACH_THREADS /* specific ressources for server/client real-time thread communication */ mach_port_t clienttask, bp, serverport, replyport; trivial_message message; pthread_t process_thread; + char rt_thread_ok : 1; #endif }; diff --git a/libjack/pool.c b/libjack/pool.c index 2721958e..1c094d1a 100644 --- a/libjack/pool.c +++ b/libjack/pool.c @@ -18,18 +18,26 @@ $Id$ */ +#include + +#ifdef HAVE_POSIX_MEMALIGN #define _XOPEN_SOURCE 600 +#endif #include #include #include +/* XXX need RT-pool based allocator here */ void * jack_pool_alloc (size_t bytes) { - /* XXX need RT-pool based allocator here */ +#ifdef HAVE_POSIX_MEMALIGN void* m; int err = posix_memalign (&m, 16, bytes); return (!err) ? m : 0; +#else + return malloc (bytes); +#endif /* HAVE_POSIX_MEMALIGN */ } void diff --git a/libjack/ringbuffer.c b/libjack/ringbuffer.c index d1aa4489..a5d8529a 100644 --- a/libjack/ringbuffer.c +++ b/libjack/ringbuffer.c @@ -20,9 +20,12 @@ This is safe for the case of one read thread and one write thread. */ +#include #include #include +#ifndef JACK_DO_NOT_MLOCK #include +#endif /* JACK_DO_NOT_MLOCK */ #include /* Create a new ringbuffer to hold at least `sz' bytes of data. The @@ -54,9 +57,11 @@ jack_ringbuffer_create (size_t sz) void jack_ringbuffer_free (jack_ringbuffer_t * rb) { +#ifndef JACK_DO_NOT_MLOCK if (rb->mlocked) { munlock (rb->buf, rb->size); } +#endif /* JACK_DO_NOT_MLOCK */ free (rb->buf); } @@ -65,9 +70,11 @@ jack_ringbuffer_free (jack_ringbuffer_t * rb) int jack_ringbuffer_mlock (jack_ringbuffer_t * rb) { +#ifndef JACK_DO_NOT_MLOCK if (mlock (rb->buf, rb->size)) { return -1; } +#endif /* JACK_DO_NOT_MLOCK */ rb->mlocked = 1; return 0; } diff --git a/libjack/shm.c b/libjack/shm.c index 1ba41ac7..420f607a 100644 --- a/libjack/shm.c +++ b/libjack/shm.c @@ -17,6 +17,7 @@ $Id$ */ +#include #include #include @@ -25,12 +26,10 @@ #include #include #include +#include #include #include -#include -#include #include -#include #include #include diff --git a/libjack/timestamps.c b/libjack/timestamps.c index 9e5e041d..e13bed0a 100644 --- a/libjack/timestamps.c +++ b/libjack/timestamps.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include typedef struct { jack_time_t when; diff --git a/libjack/transclient.c b/libjack/transclient.c index 7139c796..f6df27ad 100644 --- a/libjack/transclient.c +++ b/libjack/transclient.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "local.h" @@ -34,40 +35,8 @@ jack_unique_t jack_generate_unique_id (jack_control_t *ectl) { - /* The jack_unique_t is an opaque type. Its structure is only - * known here. We use the least significant word of the CPU - * cycle counter. For SMP, I would like to include the - * current thread ID, since only one thread runs on a CPU at a - * time. - * - * But, pthread_self() is broken on my Debian GNU/Linux - * system, it always seems to return 16384. That's useless. - * So, I'm using the process ID instead. With Linux 2.4 and - * Linuxthreads there is an LWP for each thread so this works, - * but is not portable. :-( - */ - volatile union { - jack_unique_t unique; - struct { - pid_t pid; - unsigned long cycle; - } field; - } id; - - id.field.cycle = (unsigned long) get_cycles(); - id.field.pid = getpid(); - - // JOQ: Alternatively, we could keep a sequence number in - // shared memory, using to increment it. I - // really like the simplicity of that approach. But I hate - // forcing JACK to either depend on that pesky header file, or - // maintain its own like ardour does. - - // fprintf (stderr, "unique ID 0x%" PRIx64 - // ", process %d, cycle 0x%" PRIx32 "\n", - // id.unique, id.field.pid, id.field.cycle); - - return id.unique; + /* The jack_unique_t is an opaque type. */ + return exchange_and_add(&ectl->seq_number, 1); } static inline void @@ -226,7 +195,8 @@ jack_get_current_transport_frame (const jack_client_t *client) */ usecs = jack_get_microseconds() - position.usecs; - elapsed = (jack_nframes_t) floor ((((float) position.frame_rate) / 1000000.0f) * usecs); + elapsed = (jack_nframes_t) floor ((((float) position.frame_rate) + / 1000000.0f) * usecs); /* return the estimated transport frame position */ diff --git a/macosx/fakepoll.h b/macosx/fakepoll.h deleted file mode 100755 index c2568eec..00000000 --- a/macosx/fakepoll.h +++ /dev/null @@ -1,53 +0,0 @@ - -// fakepoll.h -// poll using select -// Warning: a call to this poll() takes about 4K of stack space. - -// Greg Parker gparker-web@sealiesoftware.com December 2000 -// This code is in the public domain and may be copied or modified without -// permission. - -// Updated May 2002: -// * fix crash when an fd is less than 0 -// * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE -// * don't set POLLIN or POLLOUT in revents if it wasn't requested -// in events (only happens when an fd is in the poll set twice) - -#ifndef _FAKE_POLL_H -#define _FAKE_POLL_H - -#include -#define FD_SETSIZE OPEN_MAX -#include -#include -#include -#include -#include - -typedef struct pollfd { - int fd; /* file desc to poll */ - short events; /* events of interest on fd */ - short revents; /* events that occurred on fd */ -} pollfd_t; - - -// poll flags -#define POLLIN 0x0001 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 - -// synonyms -#define POLLNORM POLLIN -#define POLLPRI POLLIN -#define POLLRDNORM POLLIN -#define POLLRDBAND POLLIN -#define POLLWRNORM POLLOUT -#define POLLWRBAND POLLOUT - -// ignored -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 - -inline int poll(struct pollfd *pollSet, int pollCount, int pollTimeout); - -#endif diff --git a/macosx/pThreadUtilities.c b/macosx/pThreadUtilities.c deleted file mode 100644 index 099a0809..00000000 --- a/macosx/pThreadUtilities.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright: © Copyright 2002 Apple Computer, Inc. All rights reserved. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/* pThreadUtilities.c */ - -#define THREAD_SET_PRIORITY 0 -#define THREAD_SCHEDULED_PRIORITY 1 - -#include -#include -#include - -#include "pThreadUtilities.h" - - -UInt32 _getThreadPriority (pthread_t inThread, int inWhichPriority); - - -void setThreadToPriority(pthread_t inThread, UInt32 inPriority, Boolean inIsFixed, UInt64 inHALIOProcCycleDurationInNanoseconds) -{ - if (inPriority == 96) - { - // REAL-TIME / TIME-CONSTRAINT THREAD - thread_time_constraint_policy_data_t theTCPolicy; - UInt64 theComputeQuanta; - UInt64 thePeriod; - UInt64 thePeriodNanos; - - thePeriodNanos = inHALIOProcCycleDurationInNanoseconds; - theComputeQuanta = AudioConvertNanosToHostTime ( thePeriodNanos * 0.15 ); - thePeriod = AudioConvertNanosToHostTime (thePeriodNanos); - - theTCPolicy.period = thePeriod; - theTCPolicy.computation = theComputeQuanta; - theTCPolicy.constraint = thePeriod; - theTCPolicy.preemptible = true; - thread_policy_set (pthread_mach_thread_np(inThread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); - } else { - // OTHER THREADS - thread_extended_policy_data_t theFixedPolicy; - thread_precedence_policy_data_t thePrecedencePolicy; - SInt32 relativePriority; - - // [1] SET FIXED / NOT FIXED - theFixedPolicy.timeshare = !inIsFixed; - thread_policy_set (pthread_mach_thread_np(inThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT); - - // [2] SET PRECEDENCE - // N.B.: We expect that if thread A created thread B, and the program wishes to change - // the priority of thread B, then the call to change the priority of thread B must be - // made by thread A. - // This assumption allows us to use pthread_self() to correctly calculate the priority - // of the feeder thread (since precedency policy's importance is relative to the - // spawning thread's priority.) - relativePriority = inPriority - getThreadSetPriority (pthread_self()); - - thePrecedencePolicy.importance = relativePriority; - thread_policy_set (pthread_mach_thread_np(inThread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); - } -} - -// returns the thread's priority as it was last set by the API -UInt32 getThreadSetPriority(pthread_t inThread) -{ - return _getThreadPriority (inThread, THREAD_SET_PRIORITY); -} - -// returns the thread's priority as it was last scheduled by the Kernel -UInt32 getThreadScheduledPriority(pthread_t inThread) -{ - return _getThreadPriority (inThread, THREAD_SCHEDULED_PRIORITY); -} - -UInt32 _getThreadPriority(pthread_t inThread, int inWhichPriority) -{ - thread_basic_info_data_t threadInfo; - policy_info_data_t thePolicyInfo; - unsigned int count; - - // get basic info - count = THREAD_BASIC_INFO_COUNT; - thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count); - - switch (threadInfo.policy) { - case POLICY_TIMESHARE: - count = POLICY_TIMESHARE_INFO_COUNT; - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count); - if (inWhichPriority == THREAD_SCHEDULED_PRIORITY) { - return thePolicyInfo.ts.cur_priority; - } else { - return thePolicyInfo.ts.base_priority; - } - break; - - case POLICY_FIFO: - count = POLICY_FIFO_INFO_COUNT; - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count); - if ( (thePolicyInfo.fifo.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { - return thePolicyInfo.fifo.depress_priority; - } - return thePolicyInfo.fifo.base_priority; - break; - - case POLICY_RR: - count = POLICY_RR_INFO_COUNT; - thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count); - if ( (thePolicyInfo.rr.depressed) && (inWhichPriority == THREAD_SCHEDULED_PRIORITY) ) { - return thePolicyInfo.rr.depress_priority; - } - return thePolicyInfo.rr.base_priority; - break; - } - - return 0; -} - diff --git a/macosx/pThreadUtilities.h b/macosx/pThreadUtilities.h deleted file mode 100644 index ace1fb37..00000000 --- a/macosx/pThreadUtilities.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright: © Copyright 2002 Apple Computer, Inc. All rights reserved. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/* pThreadUtilities.h */ - -#ifndef __PTHREADUTILITIES_H__ -#define __PTHREADUTILITIES_H__ - -#import "pthread.h" -#import - -void setThreadToPriority(pthread_t inThread, UInt32 inPriority, Boolean inIsFixed, UInt64 inHALIOProcCycleDurationInNanoseconds); -UInt32 getThreadSetPriority(pthread_t inThread); -UInt32 getThreadScheduledPriority(pthread_t inThread); - -#endif /* __PTHREADUTILITIES_H__ */ diff --git a/macosx/readme.txt b/macosx/readme.txt deleted file mode 100755 index 162e90d6..00000000 --- a/macosx/readme.txt +++ /dev/null @@ -1,133 +0,0 @@ - -Darwin/MacOSX port for Jack : architecture changes in the implementation -======================================================================== - -Shared memory -============= - -The system V shared memory is not very reliable on Darwin/MacOSX. The POSIX shared memory API is used instead. - - -Jack server audio cycle -======================== - -On Linux, the jack server audio cycle (jack_run_cycle function) is called in a real-time SCHED_FIFO thread. -On Darwin/MacOSX, the jack_run_cycle is directly called inside the CoreAudio audio callback. - - -External client activation -=========================== - -Jack Linux implementation use system fifo/pipe to trigger the clients real-time callback from the server : -the first client of an external subgraph is triggered, does it's job and wakes up the next one in the list, -and so on until the last client that wakes up the Jack server. This avoid uneeded context switches between -the server and clients and thus is more efficient. - -This Linux implementation works also on Darwin/MacOSX but is not very efficient : audio gliches occur quite -frequently. - -A more efficient system for external client activation has been developed. It use low-level mach messages -system to implement fast IPC between the Jack server and the running clients. The Darwin/MacOSX has a very -efficient Remote Procedure Call (RPC) implementation that can be used : the Jack server activate each external -client in turn in a loop. - -On the client side, each client uses an additionnal thread only used for the real-time process callback, -that will be triggered by the Jack server using this fast RPC mechanism. - - -Real-time threads -================== - -The Darwin/MacOSX system use a special class of scheduling for real-time threads : - -Since the server audio cycle is called directly from the CoreAudio callback, there is nothing special -to do on the server side. On the client side, the thread used to call the "process" callback from the -server is made real-time, using the mach thread API. - - -Compilation and installation -============================= - -- In the jack/jack folder, you'll have to produce the version.h manually from the version.h.in file ): -Edit the version.h.in, replace the JACK_PROTOCOL_VERSION value with the one found in configure.in and -save as a new version.h file. You should get something like "#define jack_protocol_version 6" in the file. - -Several packages need to be installed before compiling Jack : - -- Fink dlcompat (fink.sourceforge.net) : this package define the dlopen, dlsym... API used in Jack to -load drivers and internal clients. The package has to be installed before compiling Jack. - -- fakepoll is a implementation of the poll function using select. The Fink version of poll does not - work correctly, thus the public domain "fakepoll" code has been used instead. It is directly included - in the Jack Darwin/MacOSX port. - -- PortAudio (www.portaudio.com) : PortAudio is a free, cross platform, open-source, audio I/O library. -The Jack CoreAudio driver actually is implemented using PortAudio. The PortAudio source code for MacOSX -has to be installed and compiled to produce a framework called "PortAudio.framework" that will be used -in the Jack link phase. - - -Several targets are avaiblable in the Project Builder project : - -- jackd : build the Jack server ("jackd" executable) -- jack framework : build the "Jack.framework" library. -- driver : build the PortAudio driver as a "jack_portaudio.so" shared library. -- jack_metro : build the "jack_metro" executable. -- jack_lsp : build the "jack_lsp" executable. -- jack_connect : build the "jack_connect" executable. -- jack_disconnect : build the "jack_disconnect" executable. - -Server, driver and library installation : ------------------------------------------ - -First copy the Jack.framework in /Library/Framework. Then as root : - -cp jack_portaudio /usr/local/lib -cp jackd /usr/local/bin - -Launching Jack server : ------------------------ - -By default buffer size is 128 frames and sample rate is 44100. - -jackd -v -R -d coreaudio - -To setup a 32 frames buffer and a 4800 Hz sample rate : - -jackd -v -R -d coreaudio -p 32 -r 48000 - -Performances -============= - -The Darwin/MacOSX implementation is quite efficient : on a G4/867 Mhz, the Jack server can run with -a 32 frames buffer size without noticable problems. - - -Known problems or unimplemented features -========================================= - -- thread cancellation : the pthread API pthread_cancel is not completely available on Darwin/MacOSX. -Thread cannot be cancelled in the general case : they must use explicit cancelation points like -"pthread_testcancel" (see the "jack_client_thread" function) - -- xruns detection and report : not implemented. - - -Possible improvements -====================== - -- The audio driver is built on top of PortAudio. It may be more efficient to directly use the -CoreAudio API in order to avoid additionnal buffer copy and interleaving/desinterleaving operations. - -- The project uses Project Builder. It would be helpful to work on the autoconf, automake ... tools -as in the Linux version. Is this case, the macosx/config.h file would have to be removed and generated -by configure, and jack/version.h will be generated automatically from jack/version.h.in - -- Better separation of Linux and Darwin/MacOSX only code. - -The Jack port for Darwin/MacOSX version has be done by : - -Grame Research Laboratory -9, rue du Garet 69001 Lyon - France -Mail : letz@grame.fr -