diff -Nru jack-audio-connection-kit-0.118+svn4104/config/os/generic/time.h jack-audio-connection-kit-0.121.0+svn4538/config/os/generic/time.h --- jack-audio-connection-kit-0.118+svn4104/config/os/generic/time.h 2007-04-18 16:53:03.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/config/os/generic/time.h 2011-05-29 00:46:51.000000000 +0000 @@ -30,4 +30,10 @@ return jack_get_microseconds_from_system (); } +typedef jack_time_t (*jack_get_microseconds_t)(void); +static inline jack_get_microseconds_t jack_get_microseconds_pointer(void) +{ + return jack_get_microseconds_from_system; +} + #endif /* __jack_time_h__ */ diff -Nru jack-audio-connection-kit-0.118+svn4104/config/os/gnu-linux/sanitycheck.c jack-audio-connection-kit-0.121.0+svn4538/config/os/gnu-linux/sanitycheck.c --- jack-audio-connection-kit-0.118+svn4104/config/os/gnu-linux/sanitycheck.c 2010-08-30 12:13:47.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/config/os/gnu-linux/sanitycheck.c 2011-01-27 11:20:15.000000000 +0000 @@ -39,7 +39,7 @@ relogin++; fprintf (stderr, "Please check your /etc/security/limits.conf for the following line\n"); fprintf (stderr, "and correct/add it if necessary:\n\n"); - fprintf(stderr, " @audio - rtprio 100\n"); + fprintf(stderr, " @audio - rtprio 99\n"); } else if (!system_has_audiogroup()) { errors++; relogin++; @@ -64,12 +64,7 @@ fprintf(stderr, "\t (this second option only works on relatively recent computers)\n"); fprintf(stderr, "--------------------------------------------------------------------------------\n\n"); } - if (system_memlock_is_unlimited()) { - fprintf(stderr, "\nMemory locking is unlimited - this is dangerous. You should probably alter the line:\n"); - fprintf(stderr, " @audio - memlock unlimited"); - fprintf(stderr, "\nin your /etc/limits.conf to read:\n"); - fprintf(stderr, " @audio - memlock %llu\n", (system_available_physical_mem()*3)/4096); - } else if (0==system_memlock_amount()) { + if (0==system_memlock_amount()) { errors++; relogin++; fprintf(stderr, "\nYou are not allowed to lock memory. Please add a line\n"); diff -Nru jack-audio-connection-kit-0.118+svn4104/config/os/gnu-linux/systemtest.c jack-audio-connection-kit-0.121.0+svn4538/config/os/gnu-linux/systemtest.c --- jack-audio-connection-kit-0.118+svn4104/config/os/gnu-linux/systemtest.c 2009-11-16 14:25:57.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/config/os/gnu-linux/systemtest.c 2011-02-09 13:02:33.000000000 +0000 @@ -110,8 +110,8 @@ while (!done) { (void) snprintf(filename, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpu); if (0 Tue, 06 Mar 2012 00:00:00 +0000 + +jack-audio-connection-kit (1:0.121.0+svn4538-3ubuntu1) precise; urgency=low + + * Merge from debian unstable. Remaining changes: + - Drop libcelt-dev build dependency, it's in universe. + + -- Luke Yelavich Tue, 18 Oct 2011 13:12:24 +1100 + +jack-audio-connection-kit (1:0.121.0+svn4538-3) unstable; urgency=low + + * Fix FTBFS on amd64 due to missing jack_log (Closes: #641911) + + -- Adrian Knoth Sat, 24 Sep 2011 22:34:07 +0200 + +jack-audio-connection-kit (1:0.121.0+svn4538-2) unstable; urgency=low + + * Replace hardcoded architecture list by linux-any (Closes: #634361) + * Add Dutch translation for debconf templates. + * Add Danish translation for debconf templates. + * Remove unused type-handling Build-Depends (Closes: #639159) + * Enable multiarch support (Closes: #637599) + * New upstream snapshot (Closes: #636231) + * Drop SH4 patch (integrated upstream) + + -- Adrian Knoth Wed, 07 Sep 2011 10:49:32 +0200 + +jack-audio-connection-kit (1:0.121.0+svn4469-2ubuntu2) oneiric; urgency=low + + * Build for multiarch. LP: #825342. + * Drop dh-buildinfo build-dependency; this creates conflicting + per-architecture buildinfo.gz files that prevent multiarch + co-installability, and all this information is already available in the + build logs. + + -- Steve Langasek Fri, 12 Aug 2011 13:01:12 -0700 + +jack-audio-connection-kit (1:0.121.0+svn4469-2ubuntu1) oneiric; urgency=low + + * Merge from Debian experimental. Remaining changes: (LP: #685345) + - debian/control: Drop libcelt-dev build dependency, it's in universe. + - Ubuntu-specific changes to gbp.conf + * debian/rules: Remove declaration of libdir, as things now resolve properly + + -- Luke Yelavich Mon, 08 Aug 2011 14:12:42 +1000 + +jack-audio-connection-kit (1:0.121.0+svn4469-2) unstable; urgency=low + + * Don't use /dev/shm on non-Linux archictures (Closes: #618982) + * Apply patch to enable jackd on Renesas SH (Closes: #623295) + * Imported Upstream version 0.121.0+svn4469 + * Include python example code in the example directory + + -- Adrian Knoth Thu, 23 Jun 2011 18:25:28 +0200 + +jack-audio-connection-kit (1:0.120.1+svn4142-1) unstable; urgency=low + + * Imported Upstream version 0.120.1+svn4142 + + -- Adrian Knoth Thu, 03 Mar 2011 14:07:32 +0100 + jack-audio-connection-kit (1:0.118+svn4104-1ubuntu2) natty; urgency=low * debian/rules: Explicitly set --libdir=/usr/lib as the configure script diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/compat jack-audio-connection-kit-0.121.0+svn4538/debian/compat --- jack-audio-connection-kit-0.118+svn4104/debian/compat 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/compat 2011-09-25 06:09:47.000000000 +0000 @@ -1 +1 @@ -7 +9 diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/control jack-audio-connection-kit-0.121.0+svn4538/debian/control --- jack-audio-connection-kit-0.118+svn4104/debian/control 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/control 2011-10-18 00:11:37.000000000 +0000 @@ -11,22 +11,20 @@ Build-Depends: libtool, automake1.11, autoconf, - cdbs (>= 0.4.53), - debhelper (>= 7.0.1), - dh-buildinfo, + cdbs (>= 0.4.93~), + debhelper (>= 8.1.3), d-shlibs, doxygen, - libasound2-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], + libasound2-dev [linux-any], libffado-dev (>= 2.0.0) [amd64 i386 powerpc], - libraw1394-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], + libraw1394-dev [linux-any], libreadline-dev, libsamplerate-dev, libsndfile1-dev, libtool, patchutils, - po-debconf, - type-handling -Standards-Version: 3.9.1 + po-debconf +Standards-Version: 3.9.2 DM-Upload-Allowed: yes Homepage: http://jackaudio.org/ Vcs-Git: git://git.debian.org/git/pkg-multimedia/jack-audio-connection-kit.git @@ -34,6 +32,7 @@ Package: jackd1 Architecture: any +Pre-Depends: ${misc:Pre-Depends} Depends: coreutils (>= 4.0), debconf | debconf-2.0, libjack0 (= ${binary:Version}), @@ -58,7 +57,9 @@ Package: libjack0 Architecture: any +Multi-Arch: same Section: libs +Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends} Conflicts: jackd1 (<< ${binary:Version}), @@ -95,7 +96,8 @@ ${misc:Depends}, pkg-config, ${shlibs:Depends} -Provides: libjack0.100.0-dev +Provides: libjack0.100.0-dev, + libjack-dev-session Description: JACK Audio Connection Kit (development files) JACK is a low-latency sound server, allowing multiple applications to connect to one audio device, and to share audio between themselves. diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/control.in jack-audio-connection-kit-0.121.0+svn4538/debian/control.in --- jack-audio-connection-kit-0.118+svn4104/debian/control.in 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/control.in 2011-10-18 00:11:12.000000000 +0000 @@ -11,17 +11,16 @@ Build-Depends: @cdbs@, d-shlibs, doxygen, - libasound2-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], + libasound2-dev [linux-any], libffado-dev (>= 2.0.0) [amd64 i386 powerpc], - libraw1394-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], + libraw1394-dev [linux-any], libreadline-dev, libsamplerate-dev, libsndfile1-dev, libtool, patchutils, - po-debconf, - type-handling -Standards-Version: 3.9.1 + po-debconf +Standards-Version: 3.9.2 DM-Upload-Allowed: yes Homepage: http://jackaudio.org/ Vcs-Git: git://git.debian.org/git/pkg-multimedia/jack-audio-connection-kit.git @@ -29,6 +28,7 @@ Package: jackd1 Architecture: any +Pre-Depends: ${misc:Pre-Depends} Depends: coreutils (>= 4.0), debconf | debconf-2.0, libjack0 (= ${binary:Version}), @@ -53,7 +53,9 @@ Package: libjack0 Architecture: any +Multi-Arch: same Section: libs +Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends} Conflicts: jackd1 (<< ${binary:Version}), @@ -90,7 +92,8 @@ ${misc:Depends}, pkg-config, ${shlibs:Depends} -Provides: libjack0.100.0-dev +Provides: libjack0.100.0-dev, + libjack-dev-session Description: JACK Audio Connection Kit (development files) JACK is a low-latency sound server, allowing multiple applications to connect to one audio device, and to share audio between themselves. diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/gbp.conf jack-audio-connection-kit-0.121.0+svn4538/debian/gbp.conf --- jack-audio-connection-kit-0.118+svn4104/debian/gbp.conf 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -[DEFAULT] -upstream-branch = upstream -debian-branch = ubuntu -upstream-tag = upstream/%(version)s -debian-tag = debian/%(version)s -pristine-tar = True diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/jackd1.examples jack-audio-connection-kit-0.121.0+svn4538/debian/jackd1.examples --- jack-audio-connection-kit-0.118+svn4104/debian/jackd1.examples 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/jackd1.examples 2011-09-25 06:09:47.000000000 +0000 @@ -1 +1,2 @@ debian/asound.rc +python/ diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/jackd1-firewire.install jack-audio-connection-kit-0.121.0+svn4538/debian/jackd1-firewire.install --- jack-audio-connection-kit-0.118+svn4104/debian/jackd1-firewire.install 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/jackd1-firewire.install 2011-09-25 06:09:47.000000000 +0000 @@ -1 +1 @@ -debian/tmp/usr/lib/jack/jack_firewire.so +debian/tmp/usr/lib/*/jack/jack_firewire.so diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/jackd1.install jack-audio-connection-kit-0.121.0+svn4538/debian/jackd1.install --- jack-audio-connection-kit-0.118+svn4104/debian/jackd1.install 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/jackd1.install 2011-09-25 06:09:47.000000000 +0000 @@ -1,10 +1,10 @@ debian/tmp/usr/bin/jack* -debian/tmp/usr/lib/libjackserver.so.* -debian/tmp/usr/lib/jack/inprocess.so -debian/tmp/usr/lib/jack/intime.so -debian/tmp/usr/lib/jack/jack_dummy.so -debian/tmp/usr/lib/jack/jack_net.so -debian/tmp/usr/lib/jack/jack_oss.so +debian/tmp/usr/lib/*/libjackserver.so.* +debian/tmp/usr/lib/*/jack/inprocess.so +debian/tmp/usr/lib/*/jack/intime.so +debian/tmp/usr/lib/*/jack/jack_dummy.so +debian/tmp/usr/lib/*/jack/jack_net.so +debian/tmp/usr/lib/*/jack/jack_oss.so debian/bash_completion.d etc debian/audio.conf etc/security/limits.d debian/audio.conf usr/share/jackd diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/libjack0.install jack-audio-connection-kit-0.121.0+svn4538/debian/libjack0.install --- jack-audio-connection-kit-0.118+svn4104/debian/libjack0.install 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/libjack0.install 2011-09-25 06:09:47.000000000 +0000 @@ -1 +1 @@ -debian/tmp/usr/lib/libjack.so.* +debian/tmp/usr/lib/*/libjack.so.* diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/libjack-dev.install jack-audio-connection-kit-0.121.0+svn4538/debian/libjack-dev.install --- jack-audio-connection-kit-0.118+svn4104/debian/libjack-dev.install 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/libjack-dev.install 2011-09-25 06:09:47.000000000 +0000 @@ -1,5 +1,5 @@ debian/tmp/usr/include -debian/tmp/usr/lib/lib*.a -debian/tmp/usr/lib/lib*.so -debian/tmp/usr/lib/pkgconfig +debian/tmp/usr/lib/*/lib*.a +debian/tmp/usr/lib/*/lib*.so +debian/tmp/usr/lib/*/pkgconfig debian/tmp/usr/share/jack-audio-connection-kit/reference/html/* usr/share/doc/libjack-dev/HTML diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/patches/debian-changes-1:0.118+svn4104-1ubuntu2 jack-audio-connection-kit-0.121.0+svn4538/debian/patches/debian-changes-1:0.118+svn4104-1ubuntu2 --- jack-audio-connection-kit-0.118+svn4104/debian/patches/debian-changes-1:0.118+svn4104-1ubuntu2 2011-02-14 10:50:50.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/patches/debian-changes-1:0.118+svn4104-1ubuntu2 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -Description: Upstream changes introduced in version 1:0.118+svn4104-1ubuntu2 - This patch has been created by dpkg-source during the package build. - Here's the last changelog entry, hopefully it gives details on why - those changes were made: - . - jack-audio-connection-kit (1:0.118+svn4104-1ubuntu2) natty; urgency=low - . - * debian/rules: Explicitly set --libdir=/usr/lib as the configure script - decides to use $prefix/lib64 if on a 64-bit system, causing an FTBFS, as - the package install files look in usr/lib - . - The person named in the Author field signed this changelog entry. -Author: Luke Yelavich - ---- -The information above should follow the Patch Tagging Guidelines, please -checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here -are templates for supplementary fields that you might want to add: - -Origin: , -Bug: -Bug-Debian: http://bugs.debian.org/ -Bug-Ubuntu: https://launchpad.net/bugs/ -Forwarded: -Reviewed-By: -Last-Update: - ---- jack-audio-connection-kit-0.118+svn4104.orig/configure.ac -+++ jack-audio-connection-kit-0.118+svn4104/configure.ac -@@ -171,8 +171,19 @@ AC_SUBST(OS_LDFLAGS) - - # - # We need to establish suitable defaults for a 64-bit OS --# But we don't use /usr/lib64 in Debian - libnn=lib -+case "${host_os}" in -+ linux*) -+ case "${host_cpu}" in -+ x86_64|mips64|ppc64|sparc64|s390x) -+ libnn=lib64 -+ ;; -+ esac -+ ;; -+ solaris*) -+ ## libnn=lib/sparcv9 ## on 64-bit only, but that's compiler-specific -+ ;; -+esac - - ## take care not to override the command-line setting - if test "${libdir}" = '${exec_prefix}/lib'; then diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/patches/jack_log.patch jack-audio-connection-kit-0.121.0+svn4538/debian/patches/jack_log.patch --- jack-audio-connection-kit-0.118+svn4104/debian/patches/jack_log.patch 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/patches/jack_log.patch 2011-09-24 20:29:02.000000000 +0000 @@ -0,0 +1,19 @@ +From: Adrian Knoth +Bugs-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=641911 +Description: Fix leftover reference to jack_log +Forwarded: http://trac.jackaudio.org/attachment/ticket/239 +--- a/libjack/client.c ++++ b/libjack/client.c +@@ -89,12 +89,6 @@ + init_cpu () + { + cpu_type = ((have_3dnow() << 8) | have_sse()); +- if (ARCH_X86_HAVE_3DNOW(cpu_type)) +- jack_log("Enhanced3DNow! detected"); +- if (ARCH_X86_HAVE_SSE2(cpu_type)) +- jack_log("SSE2 detected"); +- if ((!ARCH_X86_HAVE_3DNOW(cpu_type)) && (!ARCH_X86_HAVE_SSE2(cpu_type))) +- jack_log("No supported SIMD instruction sets detected"); + jack_port_set_funcs(); + } + diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/patches/series jack-audio-connection-kit-0.121.0+svn4538/debian/patches/series --- jack-audio-connection-kit-0.118+svn4104/debian/patches/series 2011-02-14 10:50:50.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/patches/series 2011-09-25 06:09:48.000000000 +0000 @@ -1,2 +1,2 @@ 2001_debian_lib64.patch -debian-changes-1:0.118+svn4104-1ubuntu2 +jack_log.patch diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/po/da.po jack-audio-connection-kit-0.121.0+svn4538/debian/po/da.po --- jack-audio-connection-kit-0.118+svn4104/debian/po/da.po 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/po/da.po 2011-08-18 22:34:08.000000000 +0000 @@ -0,0 +1,49 @@ +# Danish translation jackd2. +# Copyright (C) 2011 jackd2 & nedenstående oversættere. +# This file is distributed under the same license as the jackd2 package. +# Joe Hansen , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: jackd2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-04-01 10:29+0200\n" +"PO-Revision-Date: 2011-04-03 17:30+01:00\n" +"Last-Translator: Joe Hansen \n" +"Language-Team: Danish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../jackd2.templates:2001 +msgid "Enable realtime process priority?" +msgstr "Aktiver realtidsprocesprioritet?" + +#. Type: boolean +#. Description +#: ../jackd2.templates:2001 +msgid "" +"If you want to run jackd with realtime priorities, the user starting jackd " +"needs realtime permissions. Accept this option to create the file /etc/" +"security/limits.d/audio.conf, granting realtime priority and memlock " +"privileges to the audio group." +msgstr "" +"Hvis du ønsker at køre jackd med realtidsprioriteter, skal brugeren der " +"starter jackd have rettigheder for realtid. Accepter denne indstilling for " +"at oprette filen /etc/security/limits.d/audio.conf der giver realtidsprioritet " +"og memlock-privilegier til lydgruppen." + +#. Type: boolean +#. Description +#: ../jackd2.templates:2001 +msgid "" +"Running jackd with realtime priority minimizes latency, but may lead to " +"complete system lock-ups by requesting all the available physical system " +"memory, which is unacceptable in multi-user environments." +msgstr "" +"Kørsel af jackd med realtidsprioritet minimerer latens, men kan føre til " +"fuldstændig systemlåsning ved at anmode om al den tilgængelige fysiske " +"systemhukommelse, hvilket er uacceptabelt i flerbrugermiljøer." + diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/po/it.po jack-audio-connection-kit-0.121.0+svn4538/debian/po/it.po --- jack-audio-connection-kit-0.118+svn4104/debian/po/it.po 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/po/it.po 2011-09-25 06:09:49.000000000 +0000 @@ -1,50 +1,50 @@ -# Italian translation of jack-audio-connection-kit. -# COPYRIGHT (C) 2009 THE JACK-AUDIO-CONNECTION-KIT'S COPYRIGHT HOLDER -# This file is distributed under the same license as the jack-audio-connection-kit package. -# Luca Monducci , 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: jack-audio-connection-kit 0.116.2+svn3592 debconf " -"templates\n" -"Report-Msgid-Bugs-To: jack-audio-connection-kit@packages.debian.org\n" -"POT-Creation-Date: 2009-10-10 14:57+0100\n" -"PO-Revision-Date: 2009-10-21 21:31+0200\n" -"Last-Translator: Luca Monducci \n" -"Language-Team: Italian \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: boolean -#. Description -#: ../jackd.templates:2001 -msgid "Enable realtime process priority?" -msgstr "Attivare la priorità realtime del processo?" - -#. Type: boolean -#. Description -#: ../jackd.templates:2001 -msgid "" -"If you want to run jackd with realtime priorities, the user starting jackd " -"needs realtime permissions. Accept this option to create the file /etc/" -"security/limits.d/audio.conf, granting realtime priority and memlock " -"privileges to the audio group." -msgstr "" -"Per eseguire jackd con le priorità realtime, l'utente che avvia jackd " -"necessita dei permessi realtime. Accettando verrà creato il file /etc/" -"security/limits.conf, che garantirà i privilegi di priorità realtime e di " -"memlock al gruppo audio." - -#. Type: boolean -#. Description -#: ../jackd.templates:2001 -msgid "" -"Running jackd with realtime priority minimizes latency, but may lead to " -"complete system lock-ups by requesting all the available physical system " -"memory, which is unacceptable in multi-user environments." -msgstr "" -"L'esecuzione di jackd con priorità in realtime minimizza la latenza, ma " -"potrebbe comportare dei blocchi del sistema dovuti alla richiesta di tutta " -"la memoria fisica disponibile sul sistema, inaccettabile in ambienti multi-" -"utente." +# Italian translation of jack-audio-connection-kit. +# COPYRIGHT (C) 2009 THE JACK-AUDIO-CONNECTION-KIT'S COPYRIGHT HOLDER +# This file is distributed under the same license as the jack-audio-connection-kit package. +# Luca Monducci , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: jack-audio-connection-kit 0.116.2+svn3592 debconf " +"templates\n" +"Report-Msgid-Bugs-To: jack-audio-connection-kit@packages.debian.org\n" +"POT-Creation-Date: 2009-10-10 14:57+0100\n" +"PO-Revision-Date: 2009-10-21 21:31+0200\n" +"Last-Translator: Luca Monducci \n" +"Language-Team: Italian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "Enable realtime process priority?" +msgstr "Attivare la priorità realtime del processo?" + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "" +"If you want to run jackd with realtime priorities, the user starting jackd " +"needs realtime permissions. Accept this option to create the file /etc/" +"security/limits.d/audio.conf, granting realtime priority and memlock " +"privileges to the audio group." +msgstr "" +"Per eseguire jackd con le priorità realtime, l'utente che avvia jackd " +"necessita dei permessi realtime. Accettando verrà creato il file /etc/" +"security/limits.conf, che garantirà i privilegi di priorità realtime e di " +"memlock al gruppo audio." + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "" +"Running jackd with realtime priority minimizes latency, but may lead to " +"complete system lock-ups by requesting all the available physical system " +"memory, which is unacceptable in multi-user environments." +msgstr "" +"L'esecuzione di jackd con priorità in realtime minimizza la latenza, ma " +"potrebbe comportare dei blocchi del sistema dovuti alla richiesta di tutta " +"la memoria fisica disponibile sul sistema, inaccettabile in ambienti multi-" +"utente." diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/po/ja.po jack-audio-connection-kit-0.121.0+svn4538/debian/po/ja.po --- jack-audio-connection-kit-0.118+svn4104/debian/po/ja.po 2011-02-14 09:50:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/po/ja.po 2011-09-25 06:09:49.000000000 +0000 @@ -1,48 +1,48 @@ -# Copyright (C) 2009 Debian Multimedia Maintainers -# This file is distributed under the same license as jack-audio-connection-kit package. -# Hideki Yamane (Debian-JP) , 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: jack-audio-connection-kit 0.116.2+svn3592-3\n" -"Report-Msgid-Bugs-To: jack-audio-connection-kit@packages.debian.org\n" -"POT-Creation-Date: 2009-10-10 14:57+0100\n" -"PO-Revision-Date: 2009-10-14 17:32+0900\n" -"Last-Translator: Hideki Yamane (Debian-JP) \n" -"Language-Team: Japanese \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: boolean -#. Description -#: ../jackd.templates:2001 -msgid "Enable realtime process priority?" -msgstr "リアルタイム実行優先度の設定を有効にしますか?" - -#. Type: boolean -#. Description -#: ../jackd.templates:2001 -msgid "" -"If you want to run jackd with realtime priorities, the user starting jackd " -"needs realtime permissions. Accept this option to create the file /etc/" -"security/limits.d/audio.conf, granting realtime priority and memlock " -"privileges to the audio group." -msgstr "" -"jackd をリアルタイム優先度で動作させたい場合、jackd を起動したユーザはリア" -"ルタイム動作をさせられるパーミッションが必要です。このオプションを選択すると、" -"/etc/security/limits.d/audio.conf ファイルを作成し、audio グループに対し" -"てリアルタイム優先度と memlock 権限を許可します。" - -#. Type: boolean -#. Description -#: ../jackd.templates:2001 -msgid "" -"Running jackd with realtime priority minimizes latency, but may lead to " -"complete system lock-ups by requesting all the available physical system " -"memory, which is unacceptable in multi-user environments." -msgstr "" -"レイテンシー (遅延) を抑えて jackd をリアルタイム優先度でに動作させると、" -"システムの物理メモリを可能な限り要求して完全にシステム停止を引き起こす" -"可能性があります。これは、マルチユーザ環境では容認出来ません。" - +# Copyright (C) 2009 Debian Multimedia Maintainers +# This file is distributed under the same license as jack-audio-connection-kit package. +# Hideki Yamane (Debian-JP) , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: jack-audio-connection-kit 0.116.2+svn3592-3\n" +"Report-Msgid-Bugs-To: jack-audio-connection-kit@packages.debian.org\n" +"POT-Creation-Date: 2009-10-10 14:57+0100\n" +"PO-Revision-Date: 2009-10-14 17:32+0900\n" +"Last-Translator: Hideki Yamane (Debian-JP) \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "Enable realtime process priority?" +msgstr "リアルタイム実行優先度の設定を有効にしますか?" + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "" +"If you want to run jackd with realtime priorities, the user starting jackd " +"needs realtime permissions. Accept this option to create the file /etc/" +"security/limits.d/audio.conf, granting realtime priority and memlock " +"privileges to the audio group." +msgstr "" +"jackd をリアルタイム優先度で動作させたい場合、jackd を起動したユーザはリア" +"ルタイム動作をさせられるパーミッションが必要です。このオプションを選択すると、" +"/etc/security/limits.d/audio.conf ファイルを作成し、audio グループに対し" +"てリアルタイム優先度と memlock 権限を許可します。" + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "" +"Running jackd with realtime priority minimizes latency, but may lead to " +"complete system lock-ups by requesting all the available physical system " +"memory, which is unacceptable in multi-user environments." +msgstr "" +"レイテンシー (遅延) を抑えて jackd をリアルタイム優先度でに動作させると、" +"システムの物理メモリを可能な限り要求して完全にシステム停止を引き起こす" +"可能性があります。これは、マルチユーザ環境では容認出来ません。" + diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/po/nl.po jack-audio-connection-kit-0.121.0+svn4538/debian/po/nl.po --- jack-audio-connection-kit-0.118+svn4104/debian/po/nl.po 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/po/nl.po 2011-08-12 20:03:34.000000000 +0000 @@ -0,0 +1,51 @@ +# Dutch translation of jackd2 debconf templates. +# Copyright (C) 2011 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the jackd2 package. +# Jeroen Schot , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: jackd2 1.9.7~dfsg-1\n" +"Report-Msgid-Bugs-To: jack-audio-connection-kit@packages.debian.org\n" +"POT-Creation-Date: 2009-10-10 14:57+0100\n" +"PO-Revision-Date: 2011-07-22 10:11+0200\n" +"Last-Translator: Jeroen Schot \n" +"Language-Team: Debian l10n Dutch \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nl\n" + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "Enable realtime process priority?" +msgstr "Realtime procesprioriteit activeren?" + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "" +"If you want to run jackd with realtime priorities, the user starting jackd " +"needs realtime permissions. Accept this option to create the file /etc/" +"security/limits.d/audio.conf, granting realtime priority and memlock " +"privileges to the audio group." +msgstr "" +"Als u wilt dat jackd wordt uitgevoerd met \"realtime\" prioriteit, dan heeft " +"de gebruiker die jackd start realtime-privileges nodig. Als u deze optie " +"accepteert wordt het bestand /etc/security/limits.d/audio.conf aangemaakt. " +"Hiermee worden de realtime prioriteit- en memlock-privileges aan de groep " +"\"audio\" toegekend." + +#. Type: boolean +#. Description +#: ../jackd.templates:2001 +msgid "" +"Running jackd with realtime priority minimizes latency, but may lead to " +"complete system lock-ups by requesting all the available physical system " +"memory, which is unacceptable in multi-user environments." +msgstr "" +"Het uitvoeren van jackd met realtime prioriteit minimaliseert vertragingen, " +"maar kan er voor zorgen dat het systeem vastloopt wanneer deze het volledige " +"fysieke geheugen opvraagt. Dit is onaanvaardbaar op systemen waar meerdere " +"gebruikers tegelijk werken." diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/po/pt_BR.po jack-audio-connection-kit-0.121.0+svn4538/debian/po/pt_BR.po --- jack-audio-connection-kit-0.118+svn4104/debian/po/pt_BR.po 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/po/pt_BR.po 2011-09-25 06:09:49.000000000 +0000 @@ -0,0 +1,51 @@ +# Debconf translations for jack-audio-connection-kit. +# Copyright (C) 2009 THE jack-audio-connection-kit'S COPYRIGHT HOLDER +# This file is distributed under the same license as the jack-audio-connection-kit package. +# Adriano Rafael Gomes , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: jack-audio-connection-kit 0.118+svn3796-8\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-07-07 10:34+0200\n" +"PO-Revision-Date: 2010-12-12 00:15-0200\n" +"Last-Translator: Adriano Rafael Gomes \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"pt_BR utf-8\n" + +#. Type: boolean +#. Description +#: ../jackd1.templates:2001 +msgid "Enable realtime process priority?" +msgstr "Habilitar prioridade de processo em tempo real?" + +#. Type: boolean +#. Description +#: ../jackd1.templates:2001 +msgid "" +"If you want to run jackd with realtime priorities, the user starting jackd " +"needs realtime permissions. Accept this option to create the file /etc/" +"security/limits.d/audio.conf, granting realtime priority and memlock " +"privileges to the audio group." +msgstr "" +"Se você quiser executar o jackd com prioridades de tempo real, o usuário que " +"for iniciar o jackd precisa ter permissões de tempo real. Aceite esta opção " +"para criar o arquivo /etc/security/limits.d/audio.conf, concedendo " +"prioridade de tempo real e privilégios de memlock para o grupo audio." + +#. Type: boolean +#. Description +#: ../jackd1.templates:2001 +msgid "" +"Running jackd with realtime priority minimizes latency, but may lead to " +"complete system lock-ups by requesting all the available physical system " +"memory, which is unacceptable in multi-user environments." +msgstr "" +"Executar o jackd com prioridade de tempo real minimiza a latência, mas pode " +"levar a travamentos completos do sistema por requisitar toda a memória " +"física disponível do sistema, o que é inaceitável em ambientes multi-usuário." diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/rules jack-audio-connection-kit-0.121.0+svn4538/debian/rules --- jack-audio-connection-kit-0.118+svn4104/debian/rules 2011-02-14 10:49:29.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/rules 2011-09-25 06:09:47.000000000 +0000 @@ -24,13 +24,19 @@ CDBS_BUILD_DEPENDS_rules_upstream-tarball = CDBS_BUILD_DEPENDS_rules_utils_copyright-check = +# Explicitly require these versions until cdbs knows about multiarch +CDBS_BUILD_DEPENDS += , cdbs (>= 0.4.93~),\ + debhelper (>= 8.1.3) +CDBS_BUILD_DEPENDS_rules_debhelper_buildinfo = + DEB_UPSTREAM_PACKAGE = jack-audio-connection-kit DEB_UPSTREAM_TARBALL_BASENAME_MANGLE = s/\+.*// DEB_UPSTREAM_URL = http://jackaudio.org/downloads #unused, TODO get this soname from configure.in #DEB_SONAME_VERSION := 0.91.1-0 -DEB_CONFIGURE_EXTRA_FLAGS := --libdir=/usr/lib --enable-resize \ +DEB_CONFIGURE_EXTRA_FLAGS := --enable-resize \ + --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ --enable-timestamps --disable-iec61883 --with-oldtrans \ --disable-ensure-mlock --enable-sse=yes --enable-static=yes # --enable-posix-shm @@ -50,6 +56,8 @@ ifeq (linux-gnu,$(DEB_HOST_GNU_SYSTEM)) DEB_CONFIGURE_EXTRA_FLAGS += --with-default-tmpdir=/dev/shm +else + DEB_CONFIGURE_EXTRA_FLAGS += --with-default-tmpdir=/tmp endif ifneq (,$(filter doopt,$(DEB_BUILD_OPTIONS))) @@ -91,17 +99,9 @@ install/jackd1:: dh_install -pjackd1 debian/tmp/usr/bin/alsa_in dh_install -pjackd1 debian/tmp/usr/bin/alsa_out - dh_install -pjackd1 debian/tmp/usr/lib/jack/jack_alsa.so + dh_install -pjackd1 debian/tmp/usr/lib/*/jack/jack_alsa.so endif -binary-post-install/libjack0:: - d-devlibdeps \ - --override s/libffado2-dev/libffado-dev/ \ - --override s/libcelt0-0-dev/libcelt-dev/ \ - debian/libjack-dev.substvars \ - debian/tmp/usr/lib/*.so \ - debian/tmp/usr/lib/jack/*.so - .PHONY: faq # this target fetches the FAQ from the JACK homepage faq: diff -Nru jack-audio-connection-kit-0.118+svn4104/debian/source/lintian-overrides jack-audio-connection-kit-0.121.0+svn4538/debian/source/lintian-overrides --- jack-audio-connection-kit-0.118+svn4104/debian/source/lintian-overrides 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/debian/source/lintian-overrides 2011-09-06 15:17:30.000000000 +0000 @@ -0,0 +1,2 @@ +# compat level is 9 for multiarch, but we only require dh 8.1.3 +jack-audio-connection-kit source: package-needs-versioned-debhelper-build-depends diff -Nru jack-audio-connection-kit-0.118+svn4104/doc/mainpage.dox jack-audio-connection-kit-0.121.0+svn4538/doc/mainpage.dox --- jack-audio-connection-kit-0.118+svn4104/doc/mainpage.dox 2008-11-24 09:51:34.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/doc/mainpage.dox 2011-06-23 15:10:03.000000000 +0000 @@ -90,11 +90,15 @@ - @ref ServerControl - @ref PortFunctions - @ref PortSearching + - @ref LatencyFunctions - @ref TimeFunctions - @ref TransportControl - @ref ErrorOutput - @ref NonCallbackAPI - @ref MIDIAPI + - @ref SessionClientFunctions + - @ref WeakLinkage + - @ref ControlAPI The full API is described in: @@ -115,6 +119,10 @@ creation for JACK and its clients. - @ref midiport.h "" functions to handle reading and writing of MIDI data to a port + - @ref session.h "" functions that form the JACK + session API + - @ref control.h "" the API for starting and +controlling a JACK server In addition, the tools directory provides numerous examples of simple JACK clients that nevertheless use the API to do something @@ -140,7 +148,7 @@ @section license License -Copyright (C) 2001-2008 by Paul Davis and others. +Copyright (C) 2001-2011 by Paul Davis, Stephane Letz, Jack O'Quinn, Torben Hohn and others. JACK is free software; you can redistribute it and/or modify it under the terms of the GNU GPL and LGPL licenses as published by the Free diff -Nru jack-audio-connection-kit-0.118+svn4104/doc/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/doc/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/doc/Makefile.am 2006-05-04 15:14:45.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/doc/Makefile.am 2011-06-23 15:10:03.000000000 +0000 @@ -14,7 +14,10 @@ ../jack/thread.h \ ../jack/transport.h \ ../jack/types.h \ - ../jack/midiport.h + ../jack/midiport.h \ + ../jack/session.h \ + ../jack/weakjack.h \ + ../jack/control.h EXTRA_DIST=mainpage.dox transport.dox fsm.png fsm.eps porting.dox diff -Nru jack-audio-connection-kit-0.118+svn4104/doc/reference.doxygen.in jack-audio-connection-kit-0.121.0+svn4538/doc/reference.doxygen.in --- jack-audio-connection-kit-0.118+svn4104/doc/reference.doxygen.in 2009-02-18 12:56:37.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/doc/reference.doxygen.in 2011-06-23 15:10:03.000000000 +0000 @@ -525,7 +525,10 @@ @top_srcdir@/jack/thread.h \ @top_srcdir@/jack/transport.h \ @top_srcdir@/jack/types.h \ - @top_srcdir@/jack/midiport.h + @top_srcdir@/jack/midiport.h \ + @top_srcdir@/jack/session.h \ + @top_srcdir@/jack/weakjack.h \ + @top_srcdir@/jack/control.h \ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -830,7 +833,7 @@ # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. -DISABLE_INDEX = YES +DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. diff -Nru jack-audio-connection-kit-0.118+svn4104/doc/transport.dox jack-audio-connection-kit-0.121.0+svn4538/doc/transport.dox --- jack-audio-connection-kit-0.118+svn4104/doc/transport.dox 2004-02-20 04:31:22.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/doc/transport.dox 2011-03-18 17:31:06.000000000 +0000 @@ -115,6 +115,8 @@ void jack_transport_stop (jack_client_t *client); @endcode +@subsection slowsyncclients Slow-sync clients + The engine handles polling of slow-sync clients. When someone calls jack_transport_start(), the engine resets the poll bits and changes to a new state, ::JackTransportStarting. The @a sync_callback function @@ -155,6 +157,8 @@ sync_callback for these clients continues being invoked, giving them an opportunity to catch up. +@subsection repositioning Repositioning + @code int jack_transport_reposition (jack_client_t *client, jack_position_t *pos); @@ -169,6 +173,7 @@ enter the ::JackTransportStarting state and begin invoking their @a sync_callbacks until ready. +@subsection transportstatetransitiondiagram Transport State Transition Diagram @image html fsm.png "Transport State Transition Diagram" @image latex fsm.eps "Transport State Transition Diagram" diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/alsa/alsa_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa/alsa_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/alsa/alsa_driver.c 2010-11-02 11:21:30.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa/alsa_driver.c 2011-05-29 00:46:51.000000000 +0000 @@ -233,102 +233,85 @@ static void alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) { - if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d32_s32; + if (driver->playback_handle) { + if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { + driver->write_via_copy = sample_move_dS_floatLE; } else { - driver->channel_copy = memcpy_fake; - } - driver->read_via_copy = sample_move_floatLE_sSs; - driver->write_via_copy = sample_move_dS_floatLE; - } else { - - switch (driver->playback_sample_bytes) { - case 2: - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d16_s16; - } else { - driver->channel_copy = memcpy_fake; - } - - switch (driver->dither) { - case Rectangular: - jack_info("Rectangular dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_rect_d16_sSs: - sample_move_dither_rect_d16_sS; - break; - - case Triangular: - jack_info("Triangular dithering at 16 bits"); - driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_tri_d16_sSs: - sample_move_dither_tri_d16_sS; + switch (driver->playback_sample_bytes) { + case 2: + switch (driver->dither) { + case Rectangular: + jack_info("Rectangular dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_rect_d16_sSs: + sample_move_dither_rect_d16_sS; + break; + + case Triangular: + jack_info("Triangular dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_tri_d16_sSs: + sample_move_dither_tri_d16_sS; + break; + + case Shaped: + jack_info("Noise-shaped dithering at 16 bits"); + driver->write_via_copy = driver->quirk_bswap? + sample_move_dither_shaped_d16_sSs: + sample_move_dither_shaped_d16_sS; + break; + + default: + driver->write_via_copy = driver->quirk_bswap? + sample_move_d16_sSs : + sample_move_d16_sS; + break; + } break; - - case Shaped: - jack_info("Noise-shaped dithering at 16 bits"); + + case 3: /* NO DITHER */ driver->write_via_copy = driver->quirk_bswap? - sample_move_dither_shaped_d16_sSs: - sample_move_dither_shaped_d16_sS; + sample_move_d24_sSs: + sample_move_d24_sS; + break; - - default: + + case 4: /* NO DITHER */ driver->write_via_copy = driver->quirk_bswap? - sample_move_d16_sSs : - sample_move_d16_sS; + sample_move_d32u24_sSs: + sample_move_d32u24_sS; break; - } - break; - - case 3: /* NO DITHER */ - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d24_s24; - } else { - driver->channel_copy = memcpy_fake; - } - - driver->write_via_copy = driver->quirk_bswap? - sample_move_d24_sSs: - sample_move_d24_sS; - break; - - case 4: /* NO DITHER */ - if (driver->playback_interleaved) { - driver->channel_copy = memcpy_interleave_d32_s32; - } else { - driver->channel_copy = memcpy_fake; + default: + jack_error ("impossible sample width (%d) discovered!", + driver->playback_sample_bytes); + exit (1); } - - driver->write_via_copy = driver->quirk_bswap? - sample_move_d32u24_sSs: - sample_move_d32u24_sS; - break; - - default: - jack_error ("impossible sample width (%d) discovered!", - driver->playback_sample_bytes); - exit (1); } } - switch (driver->capture_sample_bytes) { - case 2: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s16s: - sample_move_dS_s16; - break; - case 3: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s24s: - sample_move_dS_s24; - break; - case 4: - driver->read_via_copy = driver->quirk_bswap? - sample_move_dS_s32u24s: - sample_move_dS_s32u24; - break; + if (driver->capture_handle) { + if (SND_PCM_FORMAT_FLOAT_LE == driver->capture_sample_format) { + driver->read_via_copy = sample_move_floatLE_sSs; + } else { + switch (driver->capture_sample_bytes) { + case 2: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s16s: + sample_move_dS_s16; + break; + case 3: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s24s: + sample_move_dS_s24; + break; + case 4: + driver->read_via_copy = driver->quirk_bswap? + sample_move_dS_s32u24s: + sample_move_dS_s32u24; + break; + } + } } } @@ -1279,7 +1262,7 @@ nfds++; } - poll_enter = jack_get_microseconds (); + poll_enter = driver->engine->get_microseconds (); if (poll_enter > driver->poll_next) { /* @@ -1313,7 +1296,7 @@ } - poll_ret = jack_get_microseconds (); + poll_ret = driver->engine->get_microseconds (); if (extra_fd < 0) { if (driver->poll_next && poll_ret > driver->poll_next) { @@ -1698,7 +1681,7 @@ offset, contiguous)) < 0) { jack_error ("ALSA: could not complete playback of %" PRIu32 " frames: error = %d", contiguous, err); - if (err != EPIPE && err != ESTRPIPE) + if (err != -EPIPE && err != -ESTRPIPE) return -1; } @@ -1745,6 +1728,7 @@ channel_t chn; jack_port_t *port; int port_flags; + jack_latency_range_t range; if (driver->engine->set_buffer_size (driver->engine, driver->frames_per_cycle)) { jack_error ("ALSA: cannot set engine buffer size for %d (check MIDI)", driver->frames_per_cycle); @@ -1769,7 +1753,8 @@ break; } - jack_port_set_latency (port, driver->frames_per_cycle + driver->capture_frame_latency); + range.min = range.max = driver->frames_per_cycle + driver->capture_frame_latency; + jack_port_set_latency_range (port, JackCaptureLatency, &range); driver->capture_ports = jack_slist_append (driver->capture_ports, port); @@ -1789,7 +1774,8 @@ break; } - jack_port_set_latency (port, (driver->frames_per_cycle * (driver->user_nperiods - 1)) + driver->playback_frame_latency); + range.min = range.max = (driver->frames_per_cycle * (driver->user_nperiods - 1)) + driver->playback_frame_latency; + jack_port_set_latency_range (port, JackPlaybackLatency, &range); driver->playback_ports = jack_slist_append (driver->playback_ports, port); @@ -1805,7 +1791,8 @@ "port for %s", buf); } else { - jack_port_set_latency (monitor_port, driver->frames_per_cycle); + range.min = range.max = driver->frames_per_cycle; + jack_port_set_latency_range (port, JackCaptureLatency, &range); driver->monitor_ports = jack_slist_append (driver->monitor_ports, monitor_port); @@ -1983,6 +1970,108 @@ free (driver); } +static char* +discover_alsa_using_apps () +{ + char found[2048]; + char command[5192]; + char* path = getenv ("PATH"); + char* dir; + size_t flen = 0; + int card; + int device; + size_t cmdlen = 0; + + if (!path) { + return NULL; + } + + /* look for lsof and give up if its not in PATH */ + + path = strdup (path); + dir = strtok (path, ":"); + while (dir) { + char maybe[PATH_MAX+1]; + snprintf (maybe, sizeof(maybe), "%s/lsof", dir); + if (access (maybe, X_OK)) { + break; + } + dir = strtok (NULL, ":"); + } + free (path); + + if (!dir) { + return NULL; + } + + snprintf (command, sizeof (command), "lsof -Fc0 "); + cmdlen = strlen (command); + + for (card = 0; card < 8; ++card) { + for (device = 0; device < 8; ++device) { + char buf[32]; + + snprintf (buf, sizeof (buf), "/dev/snd/pcmC%dD%dp", card, device); + if (access (buf, F_OK) == 0) { + snprintf (command+cmdlen, sizeof(command)-cmdlen, "%s ", buf); + } + cmdlen = strlen (command); + + snprintf (buf, sizeof (buf), "/dev/snd/pcmC%dD%dc", card, device); + if (access (buf, F_OK) == 0) { + snprintf (command+cmdlen, sizeof(command)-cmdlen, "%s ", buf); + } + cmdlen = strlen (command); + } + } + + FILE* f = popen (command, "r"); + + if (!f) { + return NULL; + } + + while (!feof (f)) { + char buf[1024]; /* lsof doesn't output much */ + + if (!fgets (buf, sizeof (buf), f)) { + break; + } + + if (*buf != 'p') { + return NULL; + } + + /* buf contains NULL as a separator between the process field and the command field */ + char *pid = buf; + ++pid; /* skip leading 'p' */ + char *cmd = pid; + + /* skip to NULL */ + while (*cmd) { + ++cmd; + } + ++cmd; /* skip to 'c' */ + ++cmd; /* skip to first character of command */ + + snprintf (found+flen, sizeof (found)-flen, "%s (process ID %s)\n", cmd, pid); + flen = strlen (found); + + if (flen >= sizeof (found)) { + break; + } + } + + pclose (f); + + if (flen) { + return strdup (found); + } else { + return NULL; + } +} + + static jack_driver_t * alsa_driver_new (char *name, char *playback_alsa_device, char *capture_alsa_device, @@ -2006,7 +2095,7 @@ ) { int err; - + char* current_apps; alsa_driver_t *driver; jack_info ("creating alsa driver ... %s|%s|%" PRIu32 "|%" PRIu32 @@ -2102,11 +2191,23 @@ SND_PCM_NONBLOCK) < 0) { switch (errno) { case EBUSY: - jack_error ("the playback device \"%s\" is " - "already in use. Please stop the" - " application using it and " - "run JACK again", - playback_alsa_device); + current_apps = discover_alsa_using_apps (); + if (current_apps) { + jack_error ("\n\nATTENTION: The playback device \"%s\" is " + "already in use. The following applications " + " are using your soundcard(s) so you should " + " check them and stop them as necessary before " + " trying to start JACK again:\n\n%s", + playback_alsa_device, + current_apps); + free (current_apps); + } else { + jack_error ("\n\nATTENTION: The playback device \"%s\" is " + "already in use. Please stop the" + " application using it and " + "run JACK again", + playback_alsa_device); + } alsa_driver_delete (driver); return NULL; break; @@ -2135,11 +2236,23 @@ SND_PCM_NONBLOCK) < 0) { switch (errno) { case EBUSY: - jack_error ("the capture device \"%s\" is " - "already in use. Please stop the" - " application using it and " - "run JACK again", - capture_alsa_device); + current_apps = discover_alsa_using_apps (); + if (current_apps) { + jack_error ("\n\nATTENTION: The capture device \"%s\" is " + "already in use. The following applications " + " are using your soundcard(s) so you should " + " check them and stop them as necessary before " + " trying to start JACK again:\n\n%s", + capture_alsa_device, + current_apps); + free (current_apps); + } else { + jack_error ("\n\nATTENTION: The capture (recording) device \"%s\" is " + "already in use. Please stop the" + " application using it and " + "run JACK again", + capture_alsa_device); + } alsa_driver_delete (driver); return NULL; break; diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/alsa/alsa_driver.h jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa/alsa_driver.h --- jack-audio-connection-kit-0.118+svn4104/drivers/alsa/alsa_driver.h 2009-03-13 14:58:13.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa/alsa_driver.h 2011-03-15 12:29:07.000000000 +0000 @@ -47,11 +47,6 @@ unsigned long src_bytes, unsigned long dst_skip_bytes, dither_state_t *state); -typedef void (*CopyCopyFunction) (char *dst, char *src, - unsigned long src_bytes, - unsigned long dst_skip_bytes, - unsigned long src_skip_byte); - typedef struct _alsa_driver { JACK_DRIVER_NT_DECL @@ -125,7 +120,6 @@ ReadCopyFunction read_via_copy; WriteCopyFunction write_via_copy; - CopyCopyFunction channel_copy; int dither; dither_state_t *dither_state; @@ -210,20 +204,6 @@ alsa_driver_mark_channel_done (driver, channel); } -static inline void -alsa_driver_copy_channel (alsa_driver_t *driver, - channel_t input_channel, - channel_t output_channel, - jack_nframes_t nsamples) { - - driver->channel_copy (driver->playback_addr[output_channel], - driver->capture_addr[input_channel], - nsamples * driver->playback_sample_bytes, - driver->playback_interleave_skip[output_channel], - driver->capture_interleave_skip[input_channel]); - alsa_driver_mark_channel_done (driver, output_channel); -} - void alsa_driver_silence_untouched_channels (alsa_driver_t *driver, jack_nframes_t nframes); void alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/alsa/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/drivers/alsa/Makefile.am 2009-03-13 14:58:13.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa/Makefile.am 2011-05-29 00:46:42.000000000 +0000 @@ -20,4 +20,4 @@ ice1712.h \ usx2y.h -jack_alsa_la_LIBADD = $(ALSA_LIBS) +jack_alsa_la_LIBADD = $(ALSA_LIBS) $(top_builddir)/libjack/libjack.la $(top_builddir)/jackd/libjackserver.la diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/alsa-midi/alsa_midi_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa-midi/alsa_midi_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/alsa-midi/alsa_midi_driver.c 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa-midi/alsa_midi_driver.c 2011-05-29 00:45:58.000000000 +0000 @@ -0,0 +1,122 @@ + +#include "alsa_midi.h" +#include + +static int +alsa_midi_driver_attach( alsa_midi_driver_t *driver, jack_engine_t *engine ) +{ + return driver->midi->attach(driver->midi); +} + +static int +alsa_midi_driver_detach( alsa_midi_driver_t *driver, jack_engine_t *engine ) +{ + return driver->midi->detach(driver->midi); +} + +static int +alsa_midi_driver_read( alsa_midi_driver_t *driver, jack_nframes_t nframes ) +{ + driver->midi->read(driver->midi, nframes); + return 0; +} + +static int +alsa_midi_driver_write( alsa_midi_driver_t *driver, jack_nframes_t nframes ) +{ + driver->midi->write(driver->midi, nframes); + return 0; +} + +static int +alsa_midi_driver_start( alsa_midi_driver_t *driver ) +{ + return driver->midi->start(driver->midi); +} + +static int +alsa_midi_driver_stop( alsa_midi_driver_t *driver ) +{ + return driver->midi->stop(driver->midi); +} + +static void +alsa_midi_driver_delete( alsa_midi_driver_t *driver ) +{ + if (driver->midi) + (driver->midi->destroy)(driver->midi); + + free (driver); +} + +static jack_driver_t * +alsa_midi_driver_new (jack_client_t *client, const char *name) +{ + alsa_midi_driver_t *driver; + + jack_info ("creating alsa_midi driver ..."); + + driver = (alsa_midi_driver_t *) calloc (1, sizeof (alsa_midi_driver_t)); + + jack_driver_init ((jack_driver_t *) driver); + + driver->attach = (JackDriverAttachFunction) alsa_midi_driver_attach; + driver->detach = (JackDriverDetachFunction) alsa_midi_driver_detach; + driver->read = (JackDriverReadFunction) alsa_midi_driver_read; + driver->write = (JackDriverWriteFunction) alsa_midi_driver_write; + driver->start = (JackDriverStartFunction) alsa_midi_driver_start; + driver->stop = (JackDriverStartFunction) alsa_midi_driver_stop; + + + driver->midi = alsa_seqmidi_new(client, NULL); + driver->client = client; + + return (jack_driver_t *) driver; +} + +/* DRIVER "PLUGIN" INTERFACE */ + +const char driver_client_name[] = "alsa_midi"; + +const jack_driver_desc_t * +driver_get_descriptor () +{ + jack_driver_desc_t * desc; + jack_driver_param_desc_t * params; + //unsigned int i; + + desc = calloc (1, sizeof (jack_driver_desc_t)); + + strcpy (desc->name,"alsa_midi"); + desc->nparams = 0; + + params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + desc->params = params; + + return desc; +} + +jack_driver_t * +driver_initialize (jack_client_t *client, const JSList * params) +{ + const JSList * node; + const jack_driver_param_t * param; + + for (node = params; node; node = jack_slist_next (node)) { + param = (const jack_driver_param_t *) node->data; + + switch (param->character) { + default: + break; + } + } + + return alsa_midi_driver_new (client, NULL); +} + +void +driver_finish (jack_driver_t *driver) +{ + alsa_midi_driver_delete ((alsa_midi_driver_t *) driver); +} diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/alsa-midi/alsa_midi.h jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa-midi/alsa_midi.h --- jack-audio-connection-kit-0.118+svn4104/drivers/alsa-midi/alsa_midi.h 2007-05-09 22:53:39.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa-midi/alsa_midi.h 2011-05-29 00:45:58.000000000 +0000 @@ -20,6 +20,7 @@ #define __jack_alsa_midi_h__ #include +#include typedef struct alsa_midi_t alsa_midi_t; struct alsa_midi_t { @@ -35,4 +36,13 @@ alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack); alsa_midi_t* alsa_seqmidi_new(jack_client_t *jack, const char* alsa_name); +typedef struct _alsa_midi_driver { + + JACK_DRIVER_DECL; + + alsa_midi_t *midi; + jack_client_t *client; + +} alsa_midi_driver_t; + #endif /* __jack_alsa_midi_h__ */ diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/alsa-midi/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa-midi/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/drivers/alsa-midi/Makefile.am 2007-11-01 11:02:39.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/alsa-midi/Makefile.am 2011-05-29 00:45:58.000000000 +0000 @@ -1,5 +1,16 @@ MAINTAINERCLEANFILES=Makefile.in +AM_CFLAGS = $(JACK_CFLAGS) + +plugindir = $(ADDON_DIR) + +plugin_LTLIBRARIES = jack_alsa_midi.la + +jack_alsa_midi_la_LDFLAGS = -module -avoid-version +jack_alsa_midi_la_SOURCES = alsa_rawmidi.c alsa_seqmidi.c alsa_midi_driver.c + noinst_HEADERS = alsa_midi.h \ midi_pack.h \ midi_unpack.h + +jack_alsa_midi_la_LIBADD = $(ALSA_LIBS) diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/coreaudio/coreaudio_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/coreaudio/coreaudio_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/coreaudio/coreaudio_driver.c 2010-01-28 15:40:35.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/coreaudio/coreaudio_driver.c 2011-05-29 00:46:51.000000000 +0000 @@ -297,16 +297,16 @@ AudioUnitRender(ca_driver->au_hal, ioActionFlags, inTimeStamp, 1, inNumberFrames, ca_driver->input_list); if (ca_driver->xrun_detected > 0) { /* XRun was detected */ - jack_time_t current_time = jack_get_microseconds(); + jack_time_t current_time = ca_driver->engine->get_microseconds(); ca_driver->engine->delay(ca_driver->engine, current_time - (ca_driver->last_wait_ust + ca_driver->period_usecs)); ca_driver->last_wait_ust = current_time; ca_driver->xrun_detected = 0; return 0; } else { - ca_driver->last_wait_ust = jack_get_microseconds(); + ca_driver->last_wait_ust = ca_driver->engine->get_microseconds(); ca_driver->engine->transport_cycle_start(ca_driver->engine, - jack_get_microseconds()); + ca_driver->engine->get_microseconds()); res = ca_driver->engine->run_cycle(ca_driver->engine, inNumberFrames, 0); } @@ -337,16 +337,16 @@ coreaudio_driver_t* ca_driver = (coreaudio_driver_t*)inRefCon; AudioUnitRender(ca_driver->au_hal, ioActionFlags, inTimeStamp, 1, inNumberFrames, ca_driver->input_list); if (ca_driver->xrun_detected > 0) { /* XRun was detected */ - jack_time_t current_time = jack_get_microseconds(); + jack_time_t current_time = ca_driver->engine->get_microseconds(); ca_driver->engine->delay(ca_driver->engine, current_time - (ca_driver->last_wait_ust + ca_driver->period_usecs)); ca_driver->last_wait_ust = current_time; ca_driver->xrun_detected = 0; return 0; } else { - ca_driver->last_wait_ust = jack_get_microseconds(); + ca_driver->last_wait_ust = ca_driver->engine->get_microseconds(); ca_driver->engine->transport_cycle_start(ca_driver->engine, - jack_get_microseconds()); + ca_driver->engine->get_microseconds()); return ca_driver->engine->run_cycle(ca_driver->engine, inNumberFrames, 0); } } @@ -437,6 +437,7 @@ UInt32 size; UInt32 value1,value2; Boolean isWritable; + jack_latency_range_t range; driver->engine = engine; @@ -481,7 +482,9 @@ if (err != noErr) JCALog("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error \n"); - jack_port_set_latency(port, driver->frames_per_cycle + value1 + value2 + driver->capture_frame_latency); + range.min = range.max = driver->frames_per_cycle + value1 + value2 + driver->capture_frame_latency; + jack_port_set_latency_range(port, JackCaptureLatency, &range); + driver->capture_ports = jack_slist_append(driver->capture_ports, port); } @@ -515,7 +518,9 @@ if (err != noErr) JCALog("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error \n"); - jack_port_set_latency(port, driver->frames_per_cycle + value1 + value2 + driver->playback_frame_latency); + range.min = range.max = driver->frames_per_cycle + value1 + value2 + driver->playback_frame_latency; + jack_port_set_latency_range(port, JackCaptureLatency, &range); + driver->playback_ports = jack_slist_append(driver->playback_ports, port); } diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/dummy/dummy_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/dummy/dummy_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/dummy/dummy_driver.c 2010-11-02 14:06:45.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/dummy/dummy_driver.c 2011-05-29 00:46:51.000000000 +0000 @@ -146,7 +146,7 @@ driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time); } - driver->last_wait_ust = jack_get_microseconds (); + driver->last_wait_ust = driver->engine->get_microseconds (); driver->engine->transport_cycle_start (driver->engine, driver->last_wait_ust); @@ -165,7 +165,7 @@ dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, float *delayed_usecs) { - jack_time_t now = jack_get_microseconds(); + jack_time_t now = driver->engine->get_microseconds(); if (driver->next_time < now) { if (driver->next_time == 0) { @@ -191,7 +191,7 @@ driver->next_time += driver->wait_time; } - driver->last_wait_ust = jack_get_microseconds (); + driver->last_wait_ust = driver->engine->get_microseconds (); driver->engine->transport_cycle_start (driver->engine, driver->last_wait_ust); diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/dummy/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/drivers/dummy/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/drivers/dummy/Makefile.am 2003-09-17 14:15:50.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/dummy/Makefile.am 2011-05-29 00:46:42.000000000 +0000 @@ -11,4 +11,4 @@ noinst_HEADERS = dummy_driver.h -# jack_alsa_la_LIBADD = +jack_dummy_la_LIBADD = $(top_builddir)/libjack/libjack.la $(top_builddir)/jackd/libjackserver.la diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/firewire/ffado_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/firewire/ffado_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/firewire/ffado_driver.c 2010-01-28 15:40:35.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/firewire/ffado_driver.c 2011-05-29 00:46:51.000000000 +0000 @@ -63,6 +63,7 @@ channel_t chn; jack_port_t *port=NULL; int port_flags; + jack_latency_range_t range; g_verbose=driver->engine->verbose; @@ -180,7 +181,8 @@ driver->capture_ports = jack_slist_append (driver->capture_ports, NULL); } - jack_port_set_latency (port, driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + jack_port_set_latency_range (port, JackCaptureLatency, &range); } port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal; @@ -245,7 +247,8 @@ driver->playback_ports = jack_slist_append (driver->playback_ports, NULL); } - jack_port_set_latency (port, (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency; + jack_port_set_latency_range (port, JackPlaybackLatency, &range); } if(ffado_streaming_prepare(driver->dev)) { @@ -517,7 +520,7 @@ printEnter(); - wait_enter = jack_get_microseconds (); + wait_enter = driver->engine->get_microseconds (); if (wait_enter > driver->wait_next) { /* * This processing cycle was delayed past the @@ -533,7 +536,7 @@ response = ffado_streaming_wait(driver->dev); - wait_ret = jack_get_microseconds (); + wait_ret = driver->engine->get_microseconds (); if (driver->wait_next && wait_ret > driver->wait_next) { *delayed_usecs = wait_ret - driver->wait_next; diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/firewire/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/drivers/firewire/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/drivers/firewire/Makefile.am 2007-05-17 21:30:12.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/firewire/Makefile.am 2011-05-29 00:47:09.000000000 +0000 @@ -12,7 +12,7 @@ jack_firewire_la_SOURCES = ffado_driver.c -jack_firewire_la_LIBADD = $(LIBFFADO_LIBS) $(ALSA_LIBS) +jack_firewire_la_LIBADD = $(LIBFFADO_LIBS) $(ALSA_LIBS) $(top_builddir)/libjack/libjack.la $(top_builddir)/jackd/libjackserver.la jack_firewire_la_LDFLAGS = -module -avoid-version diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/freebob/freebob_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/freebob/freebob_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/freebob/freebob_driver.c 2010-01-28 15:40:35.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/freebob/freebob_driver.c 2011-05-29 00:46:51.000000000 +0000 @@ -70,6 +70,7 @@ jack_port_t *port=NULL; int port_flags; int error=0; + jack_latency_range_t range; g_verbose=driver->engine->verbose; driver->device_options.verbose=g_verbose; @@ -174,7 +175,8 @@ if(error) break; - jack_port_set_latency (port, driver->period_size + driver->capture_frame_latency); + range.min = range.max = driver->period_size + driver->capture_frame_latency; + jack_port_set_latency_range (port, JackCaptureLatency, &range); } port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal; @@ -231,7 +233,8 @@ if(error) break; - jack_port_set_latency (port, (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency); + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency; + jack_port_set_latency_range (port, JackPlaybackLatency, &range); } return jack_activate (driver->client); @@ -449,7 +452,7 @@ printEnter(); - wait_enter = jack_get_microseconds (); + wait_enter = driver->engine->get_microseconds (); if (wait_enter > driver->wait_next) { /* * This processing cycle was delayed past the @@ -465,7 +468,7 @@ nframes=freebob_streaming_wait(driver->dev); - wait_ret = jack_get_microseconds (); + wait_ret = driver->engine->get_microseconds (); if (driver->wait_next && wait_ret > driver->wait_next) { *delayed_usecs = wait_ret - driver->wait_next; diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/netjack/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/drivers/netjack/Makefile.am 2009-11-13 19:04:25.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/Makefile.am 2011-05-29 00:47:09.000000000 +0000 @@ -10,6 +10,7 @@ jack_net_la_LDFLAGS = -module -avoid-version @NETJACK_LIBS@ jack_net_la_CFLAGS = @NETJACK_CFLAGS@ jack_net_la_SOURCES = net_driver.c netjack_packet.c netjack.c +jack_net_la_LIBADD = $(top_builddir)/libjack/libjack.la $(top_builddir)/jackd/libjackserver.la noinst_HEADERS = netjack.h net_driver.h netjack_packet.h diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/netjack/net_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/net_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/netjack/net_driver.c 2010-06-24 11:17:31.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/net_driver.c 2011-05-29 00:47:47.000000000 +0000 @@ -60,14 +60,14 @@ netjack_driver_state_t *netj = &( driver->netj ); int delay; - delay = netjack_wait( netj ); + delay = netjack_wait( netj, driver->engine->get_microseconds ); if( delay ) { //driver->engine->delay( driver->engine, (float)delay ); jack_error( "netxruns amount: %dms", delay/1000 ); } - driver->last_wait_ust = jack_get_microseconds (); + driver->last_wait_ust = driver->engine->get_microseconds (); driver->engine->transport_cycle_start (driver->engine, driver->last_wait_ust); /* this driver doesn't work so well if we report a delay */ diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack.c jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack.c --- jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack.c 2010-10-06 14:21:19.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack.c 2011-05-29 00:47:47.000000000 +0000 @@ -88,7 +88,7 @@ return retval; } -int netjack_wait( netjack_driver_state_t *netj ) +int netjack_wait( netjack_driver_state_t *netj, jack_time_t (*get_microseconds)(void) ) { int we_have_the_expected_frame = 0; jack_nframes_t next_frame_avail; @@ -96,7 +96,7 @@ jacknet_packet_header *pkthdr; if( !netj->next_deadline_valid ) { - netj->next_deadline = jack_get_time() + netj->period_usecs; + netj->next_deadline = get_microseconds() + netj->period_usecs; netj->next_deadline_valid = 1; } @@ -106,7 +106,7 @@ netj->expected_framecnt += 1; } else { // starting up.... lets look into the packetcache, and fetch the highest packet. - packet_cache_drain_socket( netj->packcache, netj->sockfd ); + packet_cache_drain_socket( netj->packcache, netj->sockfd, get_microseconds ); if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) { netj->expected_framecnt = next_frame_avail; netj->expected_framecnt_valid = 1; @@ -130,11 +130,11 @@ break; } } - if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) { + if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline, get_microseconds ) ) { break; } - packet_cache_drain_socket( netj->packcache, netj->sockfd ); + packet_cache_drain_socket( netj->packcache, netj->sockfd, get_microseconds ); } // check if we know who to send our packets too. @@ -156,7 +156,7 @@ if( we_have_the_expected_frame ) { - jack_time_t now = jack_get_time(); + jack_time_t now = get_microseconds(); if( now < netj->next_deadline ) netj->time_to_deadline = netj->next_deadline - now; else diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack.h jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack.h --- jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack.h 2010-06-24 11:17:31.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack.h 2011-05-29 00:47:47.000000000 +0000 @@ -118,7 +118,7 @@ #endif }; -int netjack_wait( netjack_driver_state_t *netj ); +int netjack_wait( netjack_driver_state_t *netj, jack_time_t (*get_microseconds)(void) ); void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ); void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ; void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate ); diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack_packet.c jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack_packet.c --- jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack_packet.c 2010-10-06 14:21:19.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack_packet.c 2011-05-29 00:47:47.000000000 +0000 @@ -363,7 +363,7 @@ // new poll using nanoseconds resolution and // not waiting forever. int -netjack_poll_deadline (int sockfd, jack_time_t deadline) +netjack_poll_deadline (int sockfd, jack_time_t deadline, jack_time_t (*get_microseconds)(void)) { struct pollfd fds; int poll_err = 0; @@ -374,7 +374,7 @@ #endif - jack_time_t now = jack_get_time(); + jack_time_t now = get_microseconds(); if( now >= deadline ) return 0; @@ -490,7 +490,7 @@ return 0; } int -netjack_poll_deadline (int sockfd, jack_time_t deadline) +netjack_poll_deadline (int sockfd, jack_time_t deadline, jack_time_t (*get_microseconds)(void)) { fd_set fds; FD_ZERO( &fds ); @@ -498,7 +498,7 @@ struct timeval timeout; while( 1 ) { - jack_time_t now = jack_get_time(); + jack_time_t now = get_microseconds(); if( now >= deadline ) return 0; @@ -520,7 +520,7 @@ // replacing netjack_recv functions. void -packet_cache_drain_socket( packet_cache *pcache, int sockfd ) +packet_cache_drain_socket( packet_cache *pcache, int sockfd, jack_time_t (*get_microseconds)(void) ) { char *rx_packet = alloca (pcache->mtu); jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; @@ -564,7 +564,7 @@ cpack = packet_cache_get_packet (pcache, framecnt); cache_packet_add_fragment (cpack, rx_packet, rcv_len); - cpack->recv_timestamp = jack_get_time(); + cpack->recv_timestamp = get_microseconds(); } } diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack_packet.h jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack_packet.h --- jack-audio-connection-kit-0.118+svn4104/drivers/netjack/netjack_packet.h 2010-06-24 11:17:33.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/netjack/netjack_packet.h 2011-05-29 00:47:47.000000000 +0000 @@ -121,7 +121,7 @@ void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); int cache_packet_is_complete(cache_packet *pack); -void packet_cache_drain_socket( packet_cache *pcache, int sockfd ); +void packet_cache_drain_socket( packet_cache *pcache, int sockfd, jack_time_t (*get_microseconds)(void) ); void packet_cache_reset_master_address( packet_cache *pcache ); float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ); int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ); @@ -131,7 +131,7 @@ int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); // Function Prototypes -int netjack_poll_deadline (int sockfd, jack_time_t deadline); +int netjack_poll_deadline (int sockfd, jack_time_t deadline, jack_time_t (*get_microseconds)(void)); void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu); diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/oss/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/drivers/oss/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/drivers/oss/Makefile.am 2007-09-08 09:48:06.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/oss/Makefile.am 2011-05-29 00:47:09.000000000 +0000 @@ -8,5 +8,6 @@ jack_oss_la_LDFLAGS = -module -avoid-version jack_oss_la_SOURCES = oss_driver.c oss_driver.h +jack_oss_la_LIBADD = $(top_builddir)/libjack/libjack.la $(top_builddir)/jackd/libjackserver.la noinst_HEADERS = oss_driver.h diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/oss/oss_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/oss/oss_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/oss/oss_driver.c 2010-01-28 15:40:35.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/oss/oss_driver.c 2011-08-18 21:43:01.000000000 +0000 @@ -81,6 +81,7 @@ 'r', JackDriverParamUInt, { .ui = OSS_DRIVER_DEF_FS }, + NULL, "sample rate", "sample rate" }, @@ -88,6 +89,7 @@ 'p', JackDriverParamUInt, { .ui = OSS_DRIVER_DEF_BLKSIZE }, + NULL, "period size", "period size" }, @@ -95,6 +97,7 @@ 'n', JackDriverParamUInt, { .ui = OSS_DRIVER_DEF_NPERIODS }, + NULL, "number of periods in buffer", "number of periods in buffer" }, @@ -102,6 +105,7 @@ 'w', JackDriverParamInt, { .i = OSS_DRIVER_DEF_BITS }, + NULL, "word length", "word length" }, @@ -109,6 +113,7 @@ 'i', JackDriverParamUInt, { .ui = OSS_DRIVER_DEF_INS }, + NULL, "capture channels", "capture channels" }, @@ -116,6 +121,7 @@ 'o', JackDriverParamUInt, { .ui = OSS_DRIVER_DEF_OUTS }, + NULL, "playback channels", "playback channels" }, @@ -123,6 +129,7 @@ 'C', JackDriverParamString, { .str = OSS_DRIVER_DEF_DEV }, + NULL, "input device", "input device" }, @@ -130,6 +137,7 @@ 'P', JackDriverParamString, { .str = OSS_DRIVER_DEF_DEV }, + NULL, "output device", "output device" }, @@ -137,6 +145,7 @@ 'b', JackDriverParamBool, { }, + NULL, "ignore hardware period size", "ignore hardware period size" }, @@ -144,6 +153,7 @@ 'I', JackDriverParamUInt, { .ui = 0 }, + NULL, "system input latency", "system input latency" }, @@ -151,6 +161,7 @@ 'O', JackDriverParamUInt, { .ui = 0 }, + NULL, "system output latency", "system output latency" } @@ -170,7 +181,7 @@ ((double) driver->period_size / (double) driver->sample_rate) * 1e6; driver->last_wait_ust = 0; - driver->last_periodtime = jack_get_microseconds(); + driver->last_periodtime = driver->engine->get_microseconds(); driver->next_periodtime = 0; driver->iodelay = 0.0F; } @@ -178,7 +189,7 @@ static inline void update_times (oss_driver_t *driver) { - driver->last_periodtime = jack_get_microseconds(); + driver->last_periodtime = driver->engine->get_microseconds(); if (driver->next_periodtime > 0) { driver->iodelay = (float) @@ -353,8 +364,10 @@ unsigned int channel; char channel_name[64]; jack_port_t *port; + jack_latency_range_t range; driver->engine = engine; + set_period_size(driver, driver->period_size); if (engine->set_buffer_size(engine, driver->period_size)) { jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size); @@ -375,8 +388,9 @@ channel_name, __FILE__, __LINE__); break; } - jack_port_set_latency(port, - driver->period_size + driver->sys_in_latency); + + range.min = range.max = driver->period_size + driver->sys_in_latency; + jack_port_set_latency_range(port, JackCaptureLatency, &range); driver->capture_ports = jack_slist_append(driver->capture_ports, port); } @@ -394,8 +408,8 @@ channel_name, __FILE__, __LINE__); break; } - jack_port_set_latency(port, - driver->period_size + driver->sys_out_latency); + range.min = range.max = driver->period_size + driver->sys_out_latency; + jack_port_set_latency_range(port, JackPlaybackLatency, &range); driver->playback_ports = jack_slist_append(driver->playback_ports, port); } @@ -746,7 +760,7 @@ if (driver->threads & 1) sem_post(&driver->sem_start); if (driver->threads & 2) sem_post(&driver->sem_start); - driver->last_periodtime = jack_get_microseconds(); + driver->last_periodtime = driver->engine->get_microseconds(); driver->next_periodtime = 0; driver->iodelay = 0.0F; @@ -1158,6 +1172,7 @@ __FILE__, __LINE__, errno); return NULL; } + memset(driver, 0x00, sizeof(oss_driver_t)); jack_driver_init((jack_driver_t *) driver); driver->attach = (JackDriverAttachFunction) oss_driver_attach; @@ -1227,9 +1242,8 @@ driver->playback_channels = playback_channels; driver->sys_in_latency = in_latency; driver->sys_out_latency = out_latency; + /* setting driver->period_usecs & co is delayed until attach */ - set_period_size(driver, period_size); - driver->finish = driver_finish; if (driver->indev == NULL) @@ -1242,7 +1256,7 @@ { # ifndef OSS_ENDIAN # ifdef __GNUC__ -# if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__)) +# if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__) || (defined(__sh__) && !defined(__LITTLE_ENDIAN__))) # define OSS_LITTLE_ENDIAN 1234 # define OSS_ENDIAN OSS_LITTLE_ENDIAN # else diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/portaudio/portaudio_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/portaudio/portaudio_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/portaudio/portaudio_driver.c 2010-01-28 15:40:35.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/portaudio/portaudio_driver.c 2011-05-29 00:46:51.000000000 +0000 @@ -121,7 +121,7 @@ driver->inPortAudio = (float*)inputBuffer; driver->outPortAudio = (float*)outputBuffer; - driver->last_wait_ust = jack_get_microseconds(); + driver->last_wait_ust = driver->engine->get_microseconds(); return driver->engine->run_cycle(driver->engine, framesPerBuffer, 0); } @@ -132,6 +132,7 @@ int port_flags; channel_t chn; char buf[JACK_PORT_NAME_SIZE]; + jack_latency_range_t range; driver->engine = engine; @@ -161,7 +162,8 @@ /* XXX fix this so that it can handle: systemic (external) latency */ - jack_port_set_latency (port, driver->frames_per_cycle); + range.min = range.max = driver->frames_per_cycle; + jack_port_set_latency_range (port, JackCaptureLatency, &range); driver->capture_ports = jack_slist_append (driver->capture_ports, port); } @@ -179,7 +181,8 @@ /* XXX fix this so that it can handle: systemic (external) latency */ - jack_port_set_latency (port, driver->frames_per_cycle); + range.min = range.max = driver->frames_per_cycle; + jack_port_set_latency_range (port, JackPlaybackLatency, &range); driver->playback_ports = jack_slist_append (driver->playback_ports, port); } @@ -244,7 +247,7 @@ } driver->engine->transport_cycle_start (driver->engine, - jack_get_microseconds ()); + driver->engine->get_microseconds ()); return 0; } diff -Nru jack-audio-connection-kit-0.118+svn4104/drivers/sun/sun_driver.c jack-audio-connection-kit-0.121.0+svn4538/drivers/sun/sun_driver.c --- jack-audio-connection-kit-0.118+svn4104/drivers/sun/sun_driver.c 2010-01-28 15:40:35.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/drivers/sun/sun_driver.c 2011-05-29 00:46:51.000000000 +0000 @@ -243,7 +243,7 @@ if (driver->outfd >= 0) need_playback = 1; - poll_enter = jack_get_microseconds(); + poll_enter = driver->engine->get_microseconds(); if (poll_enter > driver->poll_next) { /* late. don't count as wakeup delay. */ @@ -284,7 +284,7 @@ } } - poll_ret = jack_get_microseconds(); + poll_ret = driver->engine->get_microseconds(); if (driver->poll_next && poll_ret > driver->poll_next) *iodelay = poll_ret - driver->poll_next; @@ -425,7 +425,7 @@ return -1; case -5: /* poll() timeout */ - now = jack_get_microseconds(); + now = driver->engine->get_microseconds(); if (now > driver->poll_next) { iodelay = now - driver->poll_next; @@ -564,6 +564,7 @@ int channel; char channel_name[64]; jack_port_t *port; + jack_latency_range_t range; if (driver->engine->set_buffer_size(driver->engine, driver->period_size)) { jack_error ("sun_driver: cannot set engine buffer size to %d (check MIDI)", driver->period_size); @@ -585,8 +586,9 @@ "%s@%i", channel_name, __FILE__, __LINE__); break; } - jack_port_set_latency(port, - driver->period_size + driver->sys_in_latency); + + range.min = range.max = driver->period_size + driver->sys_in_latency; + jack_port_set_latency_range(port, JackCaptureLatency, &range); driver->capture_ports = jack_slist_append(driver->capture_ports, port); } @@ -604,8 +606,8 @@ "%s: %s@%i", channel_name, __FILE__, __LINE__); break; } - jack_port_set_latency(port, - driver->period_size + driver->sys_out_latency); + range.min = range.max = driver->period_size + driver->sys_out_latency; + jack_port_set_latency_range(port, JackPlaybackLatency, &range); driver->playback_ports = jack_slist_append(driver->playback_ports, port); } diff -Nru jack-audio-connection-kit-0.118+svn4104/example-clients/latent_client.c jack-audio-connection-kit-0.121.0+svn4538/example-clients/latent_client.c --- jack-audio-connection-kit-0.118+svn4104/example-clients/latent_client.c 2011-01-12 13:01:21.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/example-clients/latent_client.c 2011-01-12 17:06:23.000000000 +0000 @@ -46,7 +46,7 @@ return 0; } -int +void latency_cb (jack_latency_callback_mode_t mode, void *arg) { jack_latency_range_t range; @@ -61,8 +61,6 @@ range.max += latency; jack_port_set_latency_range (input_port, mode, &range); } - - return 0; } /** diff -Nru jack-audio-connection-kit-0.118+svn4104/example-clients/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/example-clients/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/example-clients/Makefile.am 2011-01-12 01:35:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/example-clients/Makefile.am 2011-05-29 00:46:27.000000000 +0000 @@ -21,6 +21,7 @@ jack_midisine \ jack_midiseq \ jack_latent_client \ + jack_server_control \ $(JACKREC) if HAVE_SNDFILE @@ -67,6 +68,10 @@ jack_latent_client_LDFLAGS = @OS_LDFLAGS@ jack_latent_client_LDADD = $(top_builddir)/libjack/libjack.la +jack_server_control_SOURCES = server_control.c +jack_server_control_LDFLAGS = @OS_LDFLAGS@ +jack_server_control_LDADD = $(top_builddir)/libjack/libjack.la $(top_builddir)/jackd/libjackserver.la + if HAVE_SNDFILE jack_rec_SOURCES = capture_client.c jack_rec_LDFLAGS = @SNDFILE_LIBS@ @OS_LDFLAGS@ diff -Nru jack-audio-connection-kit-0.118+svn4104/example-clients/server_control.c jack-audio-connection-kit-0.121.0+svn4538/example-clients/server_control.c --- jack-audio-connection-kit-0.118+svn4104/example-clients/server_control.c 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/example-clients/server_control.c 2011-05-29 00:46:27.000000000 +0000 @@ -0,0 +1,237 @@ +/* + Copyright (C) 2008 Grame + + 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. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +static jackctl_driver_t * jackctl_server_get_driver(jackctl_server_t *server, const char *driver_name) +{ + const JSList * node_ptr = jackctl_server_get_drivers_list(server); + + while (node_ptr) { + if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0) { + return (jackctl_driver_t *)node_ptr->data; + } + node_ptr = jack_slist_next(node_ptr); + } + + return NULL; +} + +static jackctl_internal_t * jackctl_server_get_internal(jackctl_server_t *server, const char *internal_name) +{ + const JSList * node_ptr = jackctl_server_get_internals_list(server); + + while (node_ptr) { + if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0) { + return (jackctl_internal_t *)node_ptr->data; + } + node_ptr = jack_slist_next(node_ptr); + } + + return NULL; +} + +static jackctl_parameter_t * +jackctl_get_parameter( + const JSList * parameters_list, + const char * parameter_name) +{ + while (parameters_list) + { + if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0) + { + return (jackctl_parameter_t *)parameters_list->data; + } + + parameters_list = jack_slist_next(parameters_list); + } + + return NULL; +} + +static void print_value(union jackctl_parameter_value value, jackctl_param_type_t type) +{ + switch (type) { + + case JackParamInt: + printf("parameter value = %d\n", value.i); + break; + + case JackParamUInt: + printf("parameter value = %u\n", value.ui); + break; + + case JackParamChar: + printf("parameter value = %c\n", value.c); + break; + + case JackParamString: + printf("parameter value = %s\n", value.str); + break; + + case JackParamBool: + printf("parameter value = %d\n", value.b); + break; + } +} + +static void print_parameters(const JSList * node_ptr) +{ + while (node_ptr != NULL) { + jackctl_parameter_t * parameter = (jackctl_parameter_t *)node_ptr->data; + printf("\nparameter name = %s\n", jackctl_parameter_get_name(parameter)); + printf("parameter id = %c\n", jackctl_parameter_get_id(parameter)); + printf("parameter short decs = %s\n", jackctl_parameter_get_short_description(parameter)); + printf("parameter long decs = %s\n", jackctl_parameter_get_long_description(parameter)); + print_value(jackctl_parameter_get_default_value(parameter), jackctl_parameter_get_type(parameter)); + node_ptr = jack_slist_next(node_ptr); + } +} + +static void print_driver(jackctl_driver_t * driver) +{ + printf("\n--------------------------\n"); + printf("driver = %s\n", jackctl_driver_get_name(driver)); + printf("-------------------------- \n"); + print_parameters(jackctl_driver_get_parameters(driver)); +} + +static void print_internal(jackctl_internal_t * internal) +{ + printf("\n-------------------------- \n"); + printf("internal = %s\n", jackctl_internal_get_name(internal)); + printf("-------------------------- \n"); + print_parameters(jackctl_internal_get_parameters(internal)); +} + +static void usage() +{ + fprintf (stderr, "\n" + "usage: jack_server_control \n" + " [ --driver OR -d driver_name ]\n" + " [ --client OR -c client_name ]\n" + ); +} + +int main(int argc, char *argv[]) +{ + jackctl_server_t * server; + const JSList * parameters; + const JSList * drivers; + const JSList * internals; + const JSList * node_ptr; + sigset_t signals; + int opt, option_index; + const char* driver_name = "dummy"; + const char* client_name = "audioadapter"; + + const char *options = "d:c:"; + struct option long_options[] = { + {"driver", 1, 0, 'd'}, + {"client", 1, 0, 'c'}, + }; + + while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { + switch (opt) { + case 'd': + driver_name = optarg; + break; + case 'c': + client_name = optarg; + break; + default: + usage(); + exit(0); + } + } + + server = jackctl_server_create(NULL, NULL); + parameters = jackctl_server_get_parameters(server); + + /* + jackctl_parameter_t* param; + union jackctl_parameter_value value; + param = jackctl_get_parameter(parameters, "verbose"); + if (param != NULL) { + value.b = true; + jackctl_parameter_set_value(param, &value); + } + */ + + printf("\n========================== \n"); + printf("List of server parameters \n"); + printf("========================== \n"); + + print_parameters(parameters); + + printf("\n========================== \n"); + printf("List of drivers \n"); + printf("========================== \n"); + + drivers = jackctl_server_get_drivers_list(server); + node_ptr = drivers; + while (node_ptr != NULL) { + print_driver((jackctl_driver_t *)node_ptr->data); + node_ptr = jack_slist_next(node_ptr); + } + + printf("\n========================== \n"); + printf("List of internal clients \n"); + printf("========================== \n"); + + internals = jackctl_server_get_internals_list(server); + node_ptr = internals; + while (node_ptr != NULL) { + print_internal((jackctl_internal_t *)node_ptr->data); + node_ptr = jack_slist_next(node_ptr); + } + + signals = jackctl_setup_signals(0); + + jackctl_server_start(server, jackctl_server_get_driver(server, driver_name)); + jackctl_server_load_internal(server, jackctl_server_get_internal(server, client_name)); + + /* + // Switch master test + + jackctl_driver_t* master; + + usleep(5000000); + printf("jackctl_server_load_master\n"); + master = jackctl_server_get_driver(server, "coreaudio"); + jackctl_server_switch_master(server, master); + + usleep(5000000); + printf("jackctl_server_load_master\n"); + master = jackctl_server_get_driver(server, "dummy"); + jackctl_server_switch_master(server, master); + + */ + + jackctl_wait_signals(signals); + + jackctl_server_destroy(server); + return 0; +} diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/control.h jack-audio-connection-kit-0.121.0+svn4538/jack/control.h --- jack-audio-connection-kit-0.118+svn4104/jack/control.h 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/control.h 2011-06-23 15:10:03.000000000 +0000 @@ -0,0 +1,565 @@ +/* -*- Mode: C ; c-basic-offset: 4 -*- */ +/* + JACK control API + + Copyright (C) 2008 Nedko Arnaudov + Copyright (C) 2008 GRAME + + 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; version 2 of the License. + + 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. + +*/ +/** + * @file jack/control.h + * @ingroup publicheader + * @brief JACK control API + * + */ + +#ifndef JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED +#define JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED + +#include + +#if !defined (__sun__) +#include +#endif + +/** Parameter types, intentionally similar to jack_driver_param_type_t */ +typedef enum +{ + JackParamInt = 1, /**< @brief value type is a signed integer */ + JackParamUInt, /**< @brief value type is an unsigned integer */ + JackParamChar, /**< @brief value type is a char */ + JackParamString, /**< @brief value type is a string with max size of ::JACK_PARAM_STRING_MAX+1 chars */ + JackParamBool, /**< @brief value type is a boolean */ +} jackctl_param_type_t; + +/** @brief Max value that jackctl_param_type_t type can have */ +#define JACK_PARAM_MAX (JackParamBool + 1) + +/** @brief Max length of string parameter value, excluding terminating null char */ +#define JACK_PARAM_STRING_MAX 127 + +/** @brief Type for parameter value */ +/* intentionally similar to jack_driver_param_value_t */ +union jackctl_parameter_value +{ + uint32_t ui; /**< @brief member used for ::JackParamUInt */ + int32_t i; /**< @brief member used for ::JackParamInt */ + char c; /**< @brief member used for ::JackParamChar */ + char str[JACK_PARAM_STRING_MAX + 1]; /**< @brief member used for ::JackParamString */ + bool b; /**< @brief member used for ::JackParamBool */ +}; + +/** opaque type for server object */ +typedef struct jackctl_server jackctl_server_t; + +/** opaque type for driver object */ +typedef struct jackctl_driver jackctl_driver_t; + +/** opaque type for internal client object */ +typedef struct jackctl_internal jackctl_internal_t; + +/** opaque type for parameter object */ +typedef struct jackctl_parameter jackctl_parameter_t; + +#ifdef __cplusplus +extern "C" { +#endif +#if 0 +} /* Adjust editor indent */ +#endif + +/** + * @defgroup ControlAPI the API for starting and controlling a JACK server + * @{ + */ + +/** + * Call this function to setup process signal handling. As a general + * rule, it is required for proper operation for the server object. + * + * @param flags signals setup flags, use 0 for none. Currently no + * flags are defined + * + * @return the configurated signal set. + */ +sigset_t +jackctl_setup_signals( + unsigned int flags); + +/** + * Call this function to wait on a signal set. + * + * @param signals signals set to wait on + */ +void +jackctl_wait_signals( + sigset_t signals); + +/** + * Call this function to create server object. + * + * @param on_device_acquire - Optional callback to be called before device is acquired. If false is returned, device usage will fail + * @param on_device_release - Optional callback to be called after device is released. + * + * @return server object handle, NULL if creation of server object + * failed. Successfully created server object must be destroyed with + * paired call to ::jackctl_server_destroy + */ +jackctl_server_t * +jackctl_server_create( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name)); + +/** + * Call this function to destroy server object. + * + * @param server server object handle to destroy + */ +void +jackctl_server_destroy( + jackctl_server_t * server); + +/** + * Call this function to start JACK server + * + * @param server server object handle + * @param driver driver to use + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_start( + jackctl_server_t * server, + jackctl_driver_t * driver); + +/** + * Call this function to stop JACK server + * + * @param server server object handle + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_stop( + jackctl_server_t * server); + +/** + * Call this function to get list of available drivers. List node data + * pointers is a driver object handle (::jackctl_driver_t). + * + * @param server server object handle to get drivers for + * + * @return Single linked list of driver object handles. Must not be + * modified. Always same for same server object. + */ +const JSList * +jackctl_server_get_drivers_list( + jackctl_server_t * server); + +/** + * Call this function to get list of server parameters. List node data + * pointers is a parameter object handle (::jackctl_parameter_t). + * + * @param server server object handle to get parameters for + * + * @return Single linked list of parameter object handles. Must not be + * modified. Always same for same server object. + */ +const JSList * +jackctl_server_get_parameters( + jackctl_server_t * server); + +/** + * Call this function to get list of available internal clients. List node data + * pointers is a internal client object handle (::jackctl_internal_t). + * + * @param server server object handle to get internal clients for + * + * @return Single linked list of internal client object handles. Must not be + * modified. Always same for same server object. + */ +const JSList * +jackctl_server_get_internals_list( + jackctl_server_t * server); + +/** + * Call this function to load one internal client. + * + * @param server server object handle + * @param internal internal to use + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_load_internal( + jackctl_server_t * server, + jackctl_internal_t * internal); + +/** + * Call this function to unload one internal client. + * + * @param server server object handle + * @param internal internal to unload + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_unload_internal( + jackctl_server_t * server, + jackctl_internal_t * internal); + +/** + * Call this function to add a slave in the driver slave list. + * + * @param server server object handle + * @param driver driver to add in the driver slave list. + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_add_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + +/** + * Call this function to remove a slave from the driver slave list. + * + * @param server server object handle + * @param driver driver to remove from the driver slave list. + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_remove_slave(jackctl_server_t * server, + jackctl_driver_t * driver); + +/** + * Call this function to switch master driver. + * + * @param server server object handle + * @param driver driver to switch to + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_switch_master(jackctl_server_t * server, + jackctl_driver_t * driver); + + +/** + * Call this function to get name of driver. + * + * @param driver driver object handle to get name of + * + * @return driver name. Must not be modified. Always same for same + * driver object. + */ +const char * +jackctl_driver_get_name( + jackctl_driver_t * driver); + +/** + * Call this function to get list of driver parameters. List node data + * pointers is a parameter object handle (::jackctl_parameter_t). + * + * @param driver driver object handle to get parameters for + * + * @return Single linked list of parameter object handles. Must not be + * modified. Always same for same driver object. + */ +const JSList * +jackctl_driver_get_parameters( + jackctl_driver_t * driver); + +/** + * Call this function to get name of internal client. + * + * @param internal internal object handle to get name of + * + * @return internal name. Must not be modified. Always same for same + * internal object. + */ +const char * +jackctl_internal_get_name( + jackctl_internal_t * internal); + +/** + * Call this function to get list of internal parameters. List node data + * pointers is a parameter object handle (::jackctl_parameter_t). + * + * @param internal internal object handle to get parameters for + * + * @return Single linked list of parameter object handles. Must not be + * modified. Always same for same internal object. + */ +const JSList * +jackctl_internal_get_parameters( + jackctl_internal_t * internal); + +/** + * Call this function to get parameter name. + * + * @param parameter parameter object handle to get name of + * + * @return parameter name. Must not be modified. Always same for same + * parameter object. + */ +const char * +jackctl_parameter_get_name( + jackctl_parameter_t * parameter); + +/** + * Call this function to get parameter short description. + * + * @param parameter parameter object handle to get short description of + * + * @return parameter short description. Must not be modified. Always + * same for same parameter object. + */ +const char * +jackctl_parameter_get_short_description( + jackctl_parameter_t * parameter); + +/** + * Call this function to get parameter long description. + * + * @param parameter parameter object handle to get long description of + * + * @return parameter long description. Must not be modified. Always + * same for same parameter object. + */ +const char * +jackctl_parameter_get_long_description( + jackctl_parameter_t * parameter); + +/** + * Call this function to get parameter type. + * + * @param parameter parameter object handle to get type of + * + * @return parameter type. Always same for same parameter object. + */ +jackctl_param_type_t +jackctl_parameter_get_type( + jackctl_parameter_t * parameter); + +/** + * Call this function to get parameter character. + * + * @param parameter parameter object handle to get character of + * + * @return character. + */ +char +jackctl_parameter_get_id( + jackctl_parameter_t * parameter); + +/** + * Call this function to check whether parameter has been set, or its + * default value is being used. + * + * @param parameter parameter object handle to check + * + * @return true - parameter is set, false - parameter is using default + * value. + */ +bool +jackctl_parameter_is_set( + jackctl_parameter_t * parameter); + +/** + * Call this function to reset parameter to its default value. + * + * @param parameter parameter object handle to reset value of + * + * @return success status: true - success, false - fail + */ +bool +jackctl_parameter_reset( + jackctl_parameter_t * parameter); + +/** + * Call this function to get parameter value. + * + * @param parameter parameter object handle to get value of + * + * @return parameter value. + */ +union jackctl_parameter_value +jackctl_parameter_get_value( + jackctl_parameter_t * parameter); + +/** + * Call this function to set parameter value. + * + * @param parameter parameter object handle to get value of + * @param value_ptr pointer to variable containing parameter value + * + * @return success status: true - success, false - fail + */ +bool +jackctl_parameter_set_value( + jackctl_parameter_t * parameter, + const union jackctl_parameter_value * value_ptr); + +/** + * Call this function to get parameter default value. + * + * @param parameter parameter object handle to get default value of + * + * @return parameter default value. + */ +union jackctl_parameter_value +jackctl_parameter_get_default_value( + jackctl_parameter_t * parameter); + +/** + * Call this function check whether parameter has range constraint. + * + * @param parameter object handle of parameter to check + * + * @return whether parameter has range constraint. + */ +bool +jackctl_parameter_has_range_constraint( + jackctl_parameter_t * parameter); + +/** + * Call this function check whether parameter has enumeration constraint. + * + * @param parameter object handle of parameter to check + * + * @return whether parameter has enumeration constraint. + */ +bool +jackctl_parameter_has_enum_constraint( + jackctl_parameter_t * parameter); + +/** + * Call this function get how many enumeration values parameter has. + * + * @param parameter object handle of parameter + * + * @return number of enumeration values + */ +uint32_t +jackctl_parameter_get_enum_constraints_count( + jackctl_parameter_t * parameter); + +/** + * Call this function to get parameter enumeration value. + * + * @param parameter object handle of parameter + * @param index index of parameter enumeration value + * + * @return enumeration value. + */ +union jackctl_parameter_value +jackctl_parameter_get_enum_constraint_value( + jackctl_parameter_t * parameter, + uint32_t index); + +/** + * Call this function to get parameter enumeration value description. + * + * @param parameter object handle of parameter + * @param index index of parameter enumeration value + * + * @return enumeration value description. + */ +const char * +jackctl_parameter_get_enum_constraint_description( + jackctl_parameter_t * parameter, + uint32_t index); + +/** + * Call this function to get parameter range. + * + * @param parameter object handle of parameter + * @param min_ptr pointer to variable receiving parameter minimum value + * @param max_ptr pointer to variable receiving parameter maximum value + */ +void +jackctl_parameter_get_range_constraint( + jackctl_parameter_t * parameter, + union jackctl_parameter_value * min_ptr, + union jackctl_parameter_value * max_ptr); + +/** + * Call this function to check whether parameter constraint is strict, + * i.e. whether supplying non-matching value will not work for sure. + * + * @param parameter parameter object handle to check + * + * @return whether parameter constraint is strict. + */ +bool +jackctl_parameter_constraint_is_strict( + jackctl_parameter_t * parameter); + +/** + * Call this function to check whether parameter has fake values, + * i.e. values have no user meaningful meaning and only value + * description is meaningful to user. + * + * @param parameter parameter object handle to check + * + * @return whether parameter constraint is strict. + */ +bool +jackctl_parameter_constraint_is_fake_value( + jackctl_parameter_t * parameter); + +/** + * Call this function to log an error message. + * + * @param format string + */ +void +jack_error( + const char *format, + ...); + +/** + * Call this function to log an information message. + * + * @param format string + */ +void +jack_info( + const char *format, + ...); + +/** + * Call this function to log an information message but only when + * verbose mode is enabled. + * + * @param format string + */ +void +jack_log( + const char *format, + ...); + +/* @} */ + +#if 0 +{ /* Adjust editor indent */ +#endif +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* #ifndef JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED */ diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/driver_interface.h jack-audio-connection-kit-0.121.0+svn4538/jack/driver_interface.h --- jack-audio-connection-kit-0.118+svn4104/jack/driver_interface.h 2009-03-29 13:28:57.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/driver_interface.h 2011-05-29 00:46:02.000000000 +0000 @@ -33,6 +33,10 @@ #define JACK_DRIVER_PARAM_NAME_MAX 15 #define JACK_DRIVER_PARAM_STRING_MAX 63 +#define JACK_CONSTRAINT_FLAG_RANGE ((uint32_t)1) /**< if set, constraint is a range (min-max) */ +#define JACK_CONSTRAINT_FLAG_STRICT ((uint32_t)2) /**< if set, constraint is strict, i.e. supplying non-matching value will not work */ +#define JACK_CONSTRAINT_FLAG_FAKE_VALUE ((uint32_t)4) /**< if set, values have no user meaningful meaning */ + /** Driver parameter types */ typedef enum @@ -54,6 +58,27 @@ char str[JACK_DRIVER_PARAM_STRING_MAX+1]; } jack_driver_param_value_t; +typedef struct { + jack_driver_param_value_t value; + char short_desc[64]; /**< A short (~30 chars) description for the user */ +} jack_driver_param_value_enum_t; + +typedef struct { + uint32_t flags; /**< JACK_CONSTRAINT_FLAG_XXX */ + + union { + struct { + jack_driver_param_value_t min; + jack_driver_param_value_t max; + } range; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is set */ + + struct { + uint32_t count; + jack_driver_param_value_enum_t * possible_values_array; + } enumeration; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is not set */ + } constraint; +} jack_driver_param_constraint_desc_t; + /** A driver parameter descriptor */ typedef struct @@ -62,6 +87,7 @@ char character; /**< The parameter's character (for getopt, etc) */ jack_driver_param_type_t type; /**< The parameter's type */ jack_driver_param_value_t value; /**< The parameter's (default) value */ + jack_driver_param_constraint_desc_t * constraint; /**< Pointer to parameter constraint descriptor. NULL if there is no constraint */ char short_desc[64]; /**< A short (~30 chars) description for the user */ char long_desc[1024]; /**< A longer description for the user */ diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/engine.h jack-audio-connection-kit-0.121.0+svn4538/jack/engine.h --- jack-audio-connection-kit-0.118+svn4104/jack/engine.h 2010-11-17 02:24:04.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/engine.h 2011-05-29 00:47:52.000000000 +0000 @@ -68,6 +68,8 @@ jack_driver_desc_t *driver_desc; JSList *driver_params; + JSList *slave_drivers; + /* these are "callbacks" made by the driver backend */ int (*set_buffer_size) (struct _jack_engine *, jack_nframes_t frames); int (*set_sample_rate) (struct _jack_engine *, jack_nframes_t frames); @@ -76,7 +78,7 @@ void (*delay) (struct _jack_engine *, float delayed_usecs); void (*transport_cycle_start) (struct _jack_engine *, jack_time_t time); void (*driver_exit) (struct _jack_engine *); - + jack_time_t (*get_microseconds)(void); /* "private" sections starts here */ /* engine serialization -- use precedence for deadlock avoidance */ @@ -135,7 +137,9 @@ int removing_clients; pid_t wait_pid; int nozombies; + int timeout_count_threshold; volatile int problems; + volatile int timeout_count; volatile int new_clients_allowed; /* these lists are protected by `client_lock' */ @@ -181,6 +185,7 @@ int verbose, int client_timeout, unsigned int port_max, pid_t waitpid, jack_nframes_t frame_time_offset, int nozombies, + int timeout_count_threshold, JSList *drivers); void jack_engine_delete (jack_engine_t *); int jack_run (jack_engine_t *engine); @@ -188,6 +193,9 @@ int jack_engine_load_driver (jack_engine_t *engine, jack_driver_desc_t * driver_desc, JSList * driver_params); +int jack_engine_load_slave_driver (jack_engine_t *engine, + jack_driver_desc_t * driver_desc, + JSList * driver_params); void jack_dump_configuration(jack_engine_t *engine, int take_lock); /* private engine functions */ @@ -250,6 +258,15 @@ jack_client_by_name (jack_engine_t *engine, const char *name); int jack_deliver_event (jack_engine_t *, jack_client_internal_t *, jack_event_t *); +void jack_stop_watchdog (jack_engine_t * ); + void jack_engine_signal_problems (jack_engine_t* engine); +int +jack_use_driver (jack_engine_t *engine, struct _jack_driver *driver); +int +jack_drivers_start (jack_engine_t *engine); +int +jack_add_slave_driver (jack_engine_t *engine, struct _jack_driver *driver); + #endif /* __jack_engine_h__ */ diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/internal.h jack-audio-connection-kit-0.121.0+svn4538/jack/internal.h --- jack-audio-connection-kit-0.118+svn4104/jack/internal.h 2011-01-12 01:35:47.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/internal.h 2011-06-19 22:10:03.000000000 +0000 @@ -256,7 +256,6 @@ volatile jack_client_id_t id; /* w: engine r: engine and client */ volatile jack_client_id_t uid; /* w: engine r: engine and client */ - volatile jack_nframes_t nframes; /* w: engine r: client */ volatile jack_client_state_t state; /* w: engine and client r: engine */ volatile char name[JACK_CLIENT_NAME_SIZE]; volatile char session_command[JACK_PORT_NAME_SIZE]; @@ -383,7 +382,8 @@ SessionNotify = 25, GetClientByUUID = 26, ReserveName = 30, - SessionReply = 31 + SessionReply = 31, + SessionHasCallback = 32 } RequestType; struct _jack_request { @@ -441,6 +441,7 @@ jack_nframes_t nframes; jack_time_t timeout; pid_t cap_pid; + char name[JACK_CLIENT_NAME_SIZE]; } POST_PACKED_STRUCTURE x; int32_t status; } POST_PACKED_STRUCTURE; @@ -539,6 +540,8 @@ */ extern size_t jack_midi_internal_event_size (); +extern int jack_client_handle_latency_callback (jack_client_t *client, jack_event_t *event, int is_driver); + #ifdef __GNUC__ # define likely(x) __builtin_expect((x),1) # define unlikely(x) __builtin_expect((x),0) diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/jack.h jack-audio-connection-kit-0.121.0+svn4538/jack/jack.h --- jack-audio-connection-kit-0.118+svn4104/jack/jack.h 2011-01-12 01:35:47.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/jack.h 2011-02-28 19:00:51.000000000 +0000 @@ -25,8 +25,6 @@ extern "C" { #endif -#include - #include #include @@ -172,7 +170,7 @@ * @return the pthread ID of the thread running the JACK client side * code. */ -pthread_t jack_client_thread_id (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; +jack_native_thread_t jack_client_thread_id (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -408,14 +406,61 @@ JackXRunCallback xrun_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** - * Tell the JACK server to call @a latency_callback whenever the - * port latencies need to be recalculated. + * Tell the Jack server to call @a latency_callback whenever it + * is necessary to recompute the latencies for some or all + * Jack ports. + * + * @a latency_callback will be called twice each time it is + * needed, once being passed JackCaptureLatency and once + * JackPlaybackLatency. See @ref LatencyFunctions for + * the definition of each type of latency and related functions. + * + * IMPORTANT: Most JACK clients do NOT need to register a latency + * callback. + * + * Clients that meet any of the following conditions do NOT + * need to register a latency callback: + * + * - have only input ports + * - have only output ports + * - their output is totally unrelated to their input + * - their output is not delayed relative to their input + * (i.e. data that arrives in a given process() + * callback is processed and output again in the + * same callback) + * + * Clients NOT registering a latency callback MUST also + * satisfy this condition: + * + * - have no multiple distinct internal signal pathways + * + * This means that if your client has more than 1 input and + * output port, and considers them always "correlated" + * (e.g. as a stereo pair), then there is only 1 (e.g. stereo) + * signal pathway through the client. This would be true, + * for example, of a stereo FX rack client that has a + * left/right input pair and a left/right output pair. + * + * However, this is somewhat a matter of perspective. The + * same FX rack client could be connected so that its + * two input ports were connected to entirely separate + * sources. Under these conditions, the fact that the client + * does not register a latency callback MAY result + * in port latency values being incorrect. + * + * Clients that do not meet any of those conditions SHOULD + * register a latency callback. + * + * See the documentation for @ref jack_port_set_latency_range() + * on how the callback should operate. Remember that the @a mode + * argument given to the latency callback will need to be + * passed into @ref jack_port_set_latency_range() * * @return 0 on success, otherwise a non-zero error code */ int jack_set_latency_callback (jack_client_t *, - JackLatencyCallback latency_callback, - void *) JACK_WEAK_EXPORT; + JackLatencyCallback latency_callback, + void *) JACK_WEAK_EXPORT; /*@}*/ /** @@ -668,78 +713,6 @@ */ int jack_port_untie (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; -/** - * @return the time (in frames) between data being available or - * delivered at/to a port, and the time at which it arrived at or is - * delivered to the "other side" of the port. E.g. for a physical - * audio output port, this is the time between writing to the port and - * when the signal will leave the connector. For a physical audio - * input port, this is the time between the sound arriving at the - * connector and the corresponding frames being readable from the - * port. - */ -jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * The maximum of the sum of the latencies in every - * connection path that can be drawn between the port and other - * ports with the @ref JackPortIsTerminal flag set. - */ -jack_nframes_t jack_port_get_total_latency (jack_client_t *, - jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * The port latency is zero by default. Clients that control - * physical hardware with non-zero latency should call this - * to set the latency to its correct value. Note that the value - * should include any systemic latency present "outside" the - * physical hardware controlled by the client. For example, - * for a client controlling a digital audio interface connected - * to an external digital converter, the latency setting should - * include both buffering by the audio interface *and* the converter. - */ -void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * get the new latency, either capture latency or playback latency. - * this is normally used in the LatencyCallback. - * and therefor safe to execute from callbacks. - */ -void jack_port_get_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; - -/** - * set the new latency, either capture latency or playback latency. - */ -void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; - -/** - * Request a complete recomputation of a port's total latency. This - * can be called by a client that has just changed the internal - * latency of its port using jack_port_set_latency - * and wants to ensure that all signal pathways in the graph - * are updated with respect to the values that will be returned - * by jack_port_get_total_latency. - * - * @return zero for successful execution of the request. non-zero - * otherwise. - */ -int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * Request a complete recomputation of all port latencies. This - * can be called by a client that has just changed the internal - * latency of its port using jack_port_set_latency - * and wants to ensure that all signal pathways in the graph - * are updated with respect to the values that will be returned - * by jack_port_get_total_latency. It allows a client - * to change multiple port latencies without triggering a - * recompute for each change. - * - * @return zero for successful execution of the request. non-zero - * otherwise. - */ -int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; - /** * Modify a port's short name. May be called at any time. If the * resulting full name (including the @a "client_name:" prefix) is @@ -876,6 +849,225 @@ * including the final NULL character. This value is a constant. */ int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; + +/** + * @return the buffersize of a port of type @arg port_type. + * + * this function may only be called in a buffer_size callback. + */ +size_t jack_port_type_get_buffer_size (jack_client_t *client, const char *port_type) JACK_WEAK_EXPORT; + +/*@}*/ + +/** + * @defgroup LatencyFunctions Managing and determining latency + * + * The purpose of JACK's latency API is to allow clients to + * easily answer two questions: + * + * - How long has it been since the data read from a port arrived + * at the edge of the JACK graph (either via a physical port + * or being synthesized from scratch)? + * + * - How long will it be before the data written to a port arrives + * at the edge of a JACK graph? + + * To help answering these two questions, all JACK ports have two + * latency values associated with them, both measured in frames: + * + * capture latency: how long since the data read from + * the buffer of a port arrived at at + * a port marked with JackPortIsTerminal. + * The data will have come from the "outside + * world" if the terminal port is also + * marked with JackPortIsPhysical, or + * will have been synthesized by the client + * that owns the terminal port. + * + * playback latency: how long until the data + * written to the buffer of port will reach a port + * marked with JackPortIsTerminal. + * + * Both latencies might potentially have more than one value + * because there may be multiple pathways to/from a given port + * and a terminal port. Latency is therefore generally + * expressed a min/max pair. + * + * In most common setups, the minimum and maximum latency + * are the same, but this design accomodates more complex + * routing, and allows applications (and thus users) to + * detect cases where routing is creating an anomalous + * situation that may either need fixing or more + * sophisticated handling by clients that care about + * latency. + * + * See also @ref jack_set_latency_callback for details on how + * clients that add latency to the signal path should interact + * with JACK to ensure that the correct latency figures are + * used. + * @{ + */ + +/** + * The port latency is zero by default. Clients that control + * physical hardware with non-zero latency should call this + * to set the latency to its correct value. Note that the value + * should include any systemic latency present "outside" the + * physical hardware controlled by the client. For example, + * for a client controlling a digital audio interface connected + * to an external digital converter, the latency setting should + * include both buffering by the audio interface *and* the converter. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by a latency callback that calls @ref + * jack_port_set_latency_range(). + */ +void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * return the latency range defined by @a mode for + * @a port, in frames. + * + * See @ref LatencyFunctions for the definition of each latency value. + * + * This is normally used in the LatencyCallback. + * and therefor safe to execute from callbacks. + */ +void jack_port_get_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; + +/** + * set the minimum and maximum latencies defined by + * @a mode for @a port, in frames. + * + * See @ref LatencyFunctions for the definition of each latency value. + * + * This function should ONLY be used inside a latency + * callback. The client should determine the current + * value of the latency using @ref jack_port_get_latency_range() + * (called using the same mode as @a mode) + * and then add some number of frames to that reflects + * latency added by the client. + * + * How much latency a client adds will vary + * dramatically. For most clients, the answer is zero + * and there is no reason for them to register a latency + * callback and thus they should never call this + * function. + * + * More complex clients that take an input signal, + * transform it in some way and output the result but + * not during the same process() callback will + * generally know a single constant value to add + * to the value returned by @ref jack_port_get_latency_range(). + * + * Such clients would register a latency callback (see + * @ref jack_set_latency_callback) and must know what input + * ports feed which output ports as part of their + * internal state. Their latency callback will update + * the ports' latency values appropriately. + * + * A pseudo-code example will help. The @a mode argument to the latency + * callback will determine whether playback or capture + * latency is being set. The callback will use + * @ref jack_port_set_latency_range() as follows: + * + * \code + * jack_latency_range_t range; + * if (mode == JackPlaybackLatency) { + * foreach input_port in (all self-registered port) { + * jack_port_get_latency_range (port_feeding_input_port, JackPlaybackLatency, &range); + * range.min += min_delay_added_as_signal_flows_from port_feeding to input_port; + * range.max += max_delay_added_as_signal_flows_from port_feeding to input_port; + * jack_port_set_latency_range (input_port, JackPlaybackLatency, &range); + * } + * } else if (mode == JackCaptureLatency) { + * foreach output_port in (all self-registered port) { + * jack_port_get_latency_range (port_fed_by_output_port, JackCaptureLatency, &range); + * range.min += min_delay_added_as_signal_flows_from_output_port_to_fed_by_port; + * range.max += max_delay_added_as_signal_flows_from_output_port_to_fed_by_port; + * jack_port_set_latency_range (output_port, JackCaptureLatency, &range); + * } + * } + * \endcode + * + * In this relatively simple pseudo-code example, it is assumed that + * each input port or output is connected to only 1 output or input + * port respectively. + * + * If a port is connected to more than 1 other port, then the + * range.min and range.max values passed to @ref + * jack_port_set_latency_range() should reflect the minimum and + * maximum values across all connected ports. + * + * See the description of @ref jack_set_latency_callback for more + * information. + */ +void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; + +/** + * Request a complete recomputation of all port latencies. This + * can be called by a client that has just changed the internal + * latency of its port using jack_port_set_latency + * and wants to ensure that all signal pathways in the graph + * are updated with respect to the values that will be returned + * by jack_port_get_total_latency. It allows a client + * to change multiple port latencies without triggering a + * recompute for each change. + * + * @return zero for successful execution of the request. non-zero + * otherwise. + */ +int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; + +/** + * @return the time (in frames) between data being available or + * delivered at/to a port, and the time at which it arrived at or is + * delivered to the "other side" of the port. E.g. for a physical + * audio output port, this is the time between writing to the port and + * when the signal will leave the connector. For a physical audio + * input port, this is the time between the sound arriving at the + * connector and the corresponding frames being readable from the + * port. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_port_get_latency_range() in any existing + * use cases. + */ +jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * The maximum of the sum of the latencies in every + * connection path that can be drawn between the port and other + * ports with the @ref JackPortIsTerminal flag set. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_port_get_latency_range() in any existing + * use cases. + */ +jack_nframes_t jack_port_get_total_latency (jack_client_t *, + jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * Request a complete recomputation of a port's total latency. This + * can be called by a client that has just changed the internal + * latency of its port using jack_port_set_latency + * and wants to ensure that all signal pathways in the graph + * are updated with respect to the values that will be returned + * by jack_port_get_total_latency. + * + * @return zero for successful execution of the request. non-zero + * otherwise. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_recompute_total_latencies() in any existing + * use cases. + */ +int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + /*@}*/ /** diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/jack/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/jack/Makefile.am 2010-03-26 12:25:32.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/Makefile.am 2011-06-29 01:50:30.000000000 +0000 @@ -11,10 +11,11 @@ thread.h \ timestamps.h \ transport.h \ - types.h \ - midiport.h \ - weakmacros.h \ - weakjack.h + types.h \ + midiport.h \ + weakmacros.h \ + weakjack.h \ + control.h noinst_HEADERS = \ atomicity.h \ diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/session.h jack-audio-connection-kit-0.121.0+svn4538/jack/session.h --- jack-audio-connection-kit-0.118+svn4104/jack/session.h 2010-03-26 12:25:37.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/session.h 2011-06-08 23:59:08.000000000 +0000 @@ -14,9 +14,8 @@ 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 + along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ #ifndef __jack_session_h__ @@ -36,79 +35,112 @@ /** - * session event types. + * Session event type. * * if a client cant save templates, i might just do a normal save. * - * the rationale, why there is no quit without save, is that a client - * might refuse to quit when it has unsaved data. - * however some other clients might have already quit. - * this results in too much confusion, so we just dont support that. - * the session manager can check, if the saved state is different from a previous - * save, and just remove the saved stuff. - * - * (an inquiry function, whether a quit is ok, followed by a quit event - * would have a race) + * There is no "quit without saving" event because a client might refuse to + * quit when it has unsaved data, but other clients may have already quit. + * This results in too much confusion, so it is unsupported. */ enum JackSessionEventType { + /** + * Save the session completely. + * + * The client may save references to data outside the provided directory, + * but it must do so by creating a link inside the provided directory and + * referring to that in any save files. The client must not refer to data + * files outside the provided directory directly in save files, because + * this makes it impossible for the session manager to create a session + * archive for distribution or archival. + */ JackSessionSave = 1, + + /** + * Save the session completly, then quit. + * + * The rules for saving are exactly the same as for JackSessionSave. + */ JackSessionSaveAndQuit = 2, + + /** + * Save a session template. + * + * A session template is a "skeleton" of the session, but without any data. + * Clients must save a session that, when restored, will create the same + * ports as a full save would have. However, the actual data contained in + * the session may not be saved (e.g. a DAW would create the necessary + * tracks, but not save the actual recorded data). + */ JackSessionSaveTemplate = 3 }; typedef enum JackSessionEventType jack_session_event_type_t; +/** + * @ref jack_session_flags_t bits + */ enum JackSessionFlags { /** - * an error occured while saving. + * An error occured while saving. */ JackSessionSaveError = 0x01, + /** - * client needs to be run in a terminal. + * Client needs to be run in a terminal. */ JackSessionNeedTerminal = 0x02 }; +/** + * Session flags. + */ typedef enum JackSessionFlags jack_session_flags_t; struct _jack_session_event { /** - * the actual type of this session event. + * The type of this session event. */ jack_session_event_type_t type; /** - * session_directory with trailing separator - * this is per client. so the client can do whatever it likes in here. + * Session directory path, with trailing separator. + * + * This directory is exclusive to the client; when saving the client may + * create any files it likes in this directory. */ const char *session_dir; /** - * client_uuid which must be specified to jack_client_open on session reload. - * client can specify it in the returned commandline as an option, or just save it - * with the state file. + * Client UUID which must be passed to jack_client_open on session load. + * + * The client can specify this in the returned command line, or save it + * in a state file within the session directory. */ const char *client_uuid; /** - * the command_line is the reply of the client. - * it specifies in a platform dependent way, how the client must be restarted upon session reload. + * Reply (set by client): the command line needed to restore the client. * - * it should contain ${SESSION_DIR} instead of the actual session dir. - * this would basically make the session dir moveable. + * This is a platform dependent command line. It must contain + * ${SESSION_DIR} instead of the actual session directory path. More + * generally, just as in session files, clients should not include any + * paths outside the session directory here as this makes + * archival/distribution impossible. * - * memory will be freed along with jack_session_event_free() - * initially set to NULL by jack; + * This field is set to NULL by Jack when the event is delivered to the + * client. The client must set to allocated memory that is safe to + * free(). This memory will be freed by jack_session_event_free. */ char *command_line; /** - * flags to be set by the client. normally left 0. + * Reply (set by client): Session flags. */ jack_session_flags_t flags; /** - * future flags. will be set to zero for now. + * Future flags. Set to zero for now. */ uint32_t future; }; @@ -119,17 +151,16 @@ * Prototype for the client supplied function that is called * whenever a session notification is sent via jack_session_notify(). * - * ownership of the memory of @a event is passed to the application. - * it must be freed using jack_session_event_free when its not used anymore. + * Ownership of the memory of @a event is passed to the application. + * It must be freed using jack_session_event_free when its not used anymore. * - * the client is also required to call jack_session_reply for this event. - * there is no timeout yet. and the only way to get back to a sane state - * would be to kill this client. + * The client must promptly call jack_session_reply for this event. * - * @param event the event_structure. - * @param arg pointer to a client supplied structure + * @param event The event structure. + * @param arg Pointer to a client supplied structure. */ -typedef void (*JackSessionCallback)(jack_session_event_t *event, void *arg); +typedef void (*JackSessionCallback)(jack_session_event_t *event, + void *arg); /** * Tell the JACK server to call @a session_callback when a session event @@ -141,21 +172,21 @@ * * @return 0 on success, otherwise a non-zero error code */ -int jack_set_session_callback(jack_client_t *client, - JackSessionCallback session_callback, - void *arg) JACK_WEAK_EXPORT; +int jack_set_session_callback (jack_client_t *client, + JackSessionCallback session_callback, + void *arg) JACK_WEAK_EXPORT; /** - * reply to a session_event + * Reply to a session event. * - * this can either be called directly from the callback, or later from a different thread. - * so its possible to just stick the event pointer into a pipe and execute the save code - * from the gui thread. + * This can either be called directly from the callback, or later from a + * different thread. For example, it is possible to push the event through a + * queue and execute the save code from the GUI thread. * * @return 0 on success, otherwise a non-zero error code */ - -int jack_session_reply( jack_client_t *client, jack_session_event_t *event ) JACK_WEAK_EXPORT; +int jack_session_reply (jack_client_t *client, + jack_session_event_t *event) JACK_WEAK_EXPORT; /** @@ -163,7 +194,6 @@ * this also frees the memory used by the command_line pointer. * if its non NULL. */ - void jack_session_event_free (jack_session_event_t *event) JACK_WEAK_EXPORT; @@ -175,71 +205,83 @@ char *jack_client_get_uuid (jack_client_t *client) JACK_WEAK_EXPORT; -/*@}*/ - +/** + * @} + */ /** - * @defgroup JackSessionManagerAPI this API is intended for a sessionmanager. - * this API could be server specific. if we dont reach consensus here, - * we can just drop it. - * i know its a bit clumsy. - * but this api isnt required to be as stable as the client api. + * @defgroup JackSessionManagerAPI API for a session manager. + * * @{ */ typedef struct { - const char *uuid; - const char *client_name; - const char *command; - jack_session_flags_t flags; + const char *uuid; + const char *client_name; + const char *command; + jack_session_flags_t flags; } jack_session_command_t; /** - * send a save or quit event, to all clients listening for session - * callbacks. the returned strings of the clients are accumulated and - * returned as an array of jack_session_command_t. - * its terminated by ret[i].uuid == NULL - * target == NULL means send to all interested clients. otherwise a clientname + * Send an event to all clients listening for session callbacks. + * + * The returned strings of the clients are accumulated and returned as an array + * of jack_session_command_t. its terminated by ret[i].uuid == NULL target == + * NULL means send to all interested clients. otherwise a clientname */ - -jack_session_command_t *jack_session_notify (jack_client_t* client, - const char *target, - jack_session_event_type_t type, - const char *path ) JACK_WEAK_EXPORT; +jack_session_command_t *jack_session_notify ( + jack_client_t* client, + const char *target, + jack_session_event_type_t type, + const char *path) JACK_WEAK_EXPORT; /** - * free the memory allocated by a session command. + * Free the memory allocated by a session command. */ - void jack_session_commands_free (jack_session_command_t *cmds) JACK_WEAK_EXPORT; /** - * get the sessionid for a client name. - * the sessionmanager needs this to reassociate a client_name to the session_id. + * Get the session ID for a client name. + * The session manager needs this to reassociate a client name to the session_id. */ - -char *jack_get_uuid_for_client_name( jack_client_t *client, const char *client_name ) JACK_WEAK_EXPORT; +char *jack_get_uuid_for_client_name (jack_client_t *client, + const char *client_name) JACK_WEAK_EXPORT; /** - * get the client name for a session_id. - * in order to snapshot the graph connections, the sessionmanager needs to map + * Get the client name for a session_id. + * + * In order to snapshot the graph connections, the session manager needs to map * session_ids to client names. */ - -char *jack_get_client_name_by_uuid( jack_client_t *client, const char *client_uuid ) JACK_WEAK_EXPORT; +char *jack_get_client_name_by_uuid (jack_client_t *client, + const char *client_uuid ) JACK_WEAK_EXPORT; /** - * reserve a client name and associate it to a uuid. - * when a client later call jack_client_open() and specifies the uuid, - * jackd will assign the reserved name. - * this allows a session manager to know in advance under which client name - * its managed clients will appear. + * Reserve a client name and associate it with a UUID. + * + * When a client later calls jack_client_open() and specifies the UUID, jackd + * will assign the reserved name. This allows a session manager to know in + * advance under which client name its managed clients will appear. * * @return 0 on success, otherwise a non-zero error code */ +int +jack_reserve_client_name (jack_client_t *client, + const char *name, + const char *uuid) JACK_WEAK_EXPORT; +/** + * Find out whether a client has set up a session callback. + * + * @return 0 when the client has no session callback, 1 when it has one. + * -1 on error. + */ int -jack_reserve_client_name( jack_client_t *client, const char *name, const char *uuid ) JACK_WEAK_EXPORT; +jack_client_has_session_callback (jack_client_t *client, const char *client_name) JACK_WEAK_EXPORT; + +/** + * @} + */ #ifdef __cplusplus } diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/thread.h jack-audio-connection-kit-0.121.0+svn4538/jack/thread.h --- jack-audio-connection-kit-0.118+svn4104/jack/thread.h 2010-01-28 14:29:14.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/thread.h 2011-02-28 18:57:45.000000000 +0000 @@ -69,7 +69,7 @@ * @returns 0, if successful; EPERM, if the calling process lacks * required realtime privileges; otherwise some other error number. */ -int jack_acquire_real_time_scheduling (pthread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; +int jack_acquire_real_time_scheduling (jack_native_thread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; /** * Create a thread for JACK or one of its clients. The thread is @@ -88,7 +88,7 @@ * @returns 0, if successful; otherwise some error number. */ int jack_client_create_thread (jack_client_t* client, - pthread_t *thread, + jack_native_thread_t *thread, int priority, int realtime, /* boolean */ void *(*start_routine)(void*), @@ -101,9 +101,9 @@ * * @returns 0, if successful; otherwise an error number. */ -int jack_drop_real_time_scheduling (pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; +int jack_drop_real_time_scheduling (jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; -typedef int (*jack_thread_creator_t)(pthread_t*, +typedef int (*jack_thread_creator_t)(jack_native_thread_t*, const pthread_attr_t*, void* (*function)(void*), void* arg) JACK_OPTIONAL_WEAK_EXPORT; diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/transport.h jack-audio-connection-kit-0.121.0+svn4538/jack/transport.h --- jack-audio-connection-kit-0.118+svn4104/jack/transport.h 2010-01-29 13:50:45.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/transport.h 2011-03-18 17:31:06.000000000 +0000 @@ -80,31 +80,86 @@ */ typedef struct { - /* these four cannot be set from clients: the server sets them */ + /*@{*/ + /** @name Server-set fields + * these cannot be set from clients; the server sets them */ jack_unique_t unique_1; /**< unique ID */ - jack_time_t usecs; /**< monotonic, free-rolling */ - jack_nframes_t frame_rate; /**< current frame rate (per second) */ - jack_nframes_t frame; /**< frame number, always present */ - - jack_position_bits_t valid; /**< which other fields are valid */ - - /* JackPositionBBT fields: */ - int32_t bar; /**< current bar */ - int32_t beat; /**< current beat-within-bar */ - int32_t tick; /**< current tick-within-beat */ - double bar_start_tick; + jack_time_t usecs; /**< microsecond timestamp that is guaranteed to be + monotonic, but not neccessarily + linear. + + The absolute value is + implementation-dependent (i.e. it + could be wall-clock, time since + jack started, uptime, etc). */ + jack_nframes_t frame_rate; /**< current frame rate, in frames per second */ + /*}@*/ + + /*@{*/ + /** @name Mandatory fields + */ + jack_nframes_t frame; /**< frame number, always present/required. + + This is the frame number on the + transport timeline, which is not + the same as what @ref + jack_frame_time returns. */ + jack_position_bits_t valid; /**< which other fields are valid, as a + bitmask constructed from values in + \ref jack_position_bits_t */ + /*}@*/ + + /*@{*/ + /** @name JackPositionBBT fields + * Bar:Beat.Tick-related information. + * + * Applications that support + * JackPositionBBT are encouraged to also fill the JackBBTFrameOffset + */ + int32_t bar; /**< current bar + + Should be >0: the first bar is + bar '1'. */ + int32_t beat; /**< current beat-within-bar + + Should be >0 and <=beats_per_bar: + the first beat is beat '1'. + */ + int32_t tick; /**< current tick-within-beat + + Should be >0 and <=ticks_per_beat: + the first tick is tick '0'. */ + double bar_start_tick; /**< number of ticks that have elapsed + between frame 0 and the first beat + of the current measure. */ float beats_per_bar; /**< time signature "numerator" */ float beat_type; /**< time signature "denominator" */ - double ticks_per_beat; - double beats_per_minute; + double ticks_per_beat; /**< number of ticks within a bar. - /* JackPositionTimecode fields: (EXPERIMENTAL: could change) */ + Usually a moderately large integer + with many denominators, such as + 1920.0 */ + double beats_per_minute; /**< BPM, quantized to block size. This + means when the tempo is not constant + within this block, the BPM value should + adapted to compensate for this. This + is different from most fields in this + struct, which specify the value at + the beginning of the block rather + than an average.*/ + /*}@*/ + + /*@{*/ + /** @name JackPositionTimecode fields + * EXPERIMENTAL: could change */ double frame_time; /**< current time in seconds */ double next_time; /**< next sequential frame_time (unless repositioned) */ + /*}@*/ - /* JackBBTFrameOffset fields: */ + /*@{*/ + /* JackBBTFrameOffset fields */ jack_nframes_t bbt_offset; /**< frame offset for the BBT fields (the given bar, beat, and tick values actually refer to a time @@ -119,9 +174,11 @@ the BBT time refers to a frame that many frames before the start of the cycle. */ + /*}@*/ - /* JACK video positional data (experimental) */ - + /*@{*/ + /* JACK video positional data + * EXPERIMENTAL: could change */ float audio_frames_per_video_frame; /**< number of audio frames per video frame. Should be assumed zero if JackAudioVideoRatio is not @@ -135,11 +192,15 @@ is not set. If JackVideoFrameOffset is set, but the value is zero, there is no video frame within this cycle. */ + /*}@*/ + /*@{*/ + /** @name Other fields */ /* For binary compatibility, new fields should be allocated from * this padding area with new valid bits controlling access, so * the existing structure size and offsets are preserved. */ int32_t padding[7]; + /*}@*/ /* When (unique_1 == unique_2) the contents are consistent. */ jack_unique_t unique_2; /**< unique ID */ @@ -170,12 +231,12 @@ int jack_release_timebase (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** - * Prototype for the @a sync_callback defined by slow-sync clients. - * When the client is active, this callback is invoked just before - * process() in the same thread. This occurs once after registration, - * then subsequently whenever some client requests a new position, or - * the transport enters the ::JackTransportStarting state. This - * realtime function must not wait. + * Prototype for the @a sync_callback defined by @ref slowsyncclients + * "slow-sync clients". When the client is active, this callback is + * invoked just before process() in the same thread. This occurs once + * after registration, then subsequently whenever some client requests + * a new position, or the transport enters the ::JackTransportStarting + * state. This realtime function must not wait. * * The transport @a state will be: * @@ -195,7 +256,7 @@ void *arg); /** - * Register (or unregister) as a slow-sync client, one that cannot + * Register (or unregister) as a @ref slowsyncclients "slow-sync client", that cannot * respond immediately to transport position changes. * * The @a sync_callback will be invoked at the first available @@ -219,7 +280,7 @@ void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** - * Set the timeout value for slow-sync clients. + * Set the timeout value for @ref slowsyncclients "slow-sync clients". * * This timeout prevents unresponsive slow-sync clients from * completely halting the transport mechanism. The default is two @@ -286,6 +347,8 @@ * Taking over the timebase may be done conditionally, so it fails if * there was a master already. * + * The method may be called whether the client has been activated or not. + * * @param client the JACK client structure. * @param conditional non-zero for a conditional request. * @param timebase_callback is a realtime function that returns @@ -307,9 +370,9 @@ * Reposition the transport to a new frame number. * * May be called at any time by any client. The new position takes - * effect in two process cycles. If there are slow-sync clients and - * the transport is already rolling, it will enter the - * ::JackTransportStarting state and begin invoking their @a + * effect in two process cycles. If there are @ref slowsyncclients + * "slow-sync clients" and the transport is already rolling, it will + * enter the ::JackTransportStarting state and begin invoking their @a * sync_callbacks until ready. This function is realtime-safe. * * @see jack_transport_reposition, jack_set_sync_callback @@ -353,15 +416,17 @@ * Request a new transport position. * * May be called at any time by any client. The new position takes - * effect in two process cycles. If there are slow-sync clients and - * the transport is already rolling, it will enter the - * ::JackTransportStarting state and begin invoking their @a + * effect in two process cycles. If there are @ref slowsyncclients + * "slow-sync clients" and the transport is already rolling, it will + * enter the ::JackTransportStarting state and begin invoking their @a * sync_callbacks until ready. This function is realtime-safe. * * @see jack_transport_locate, jack_set_sync_callback * * @param client the JACK client structure. - * @param pos requested new transport position. + * @param pos requested new transport position. Fill pos->valid to specify + * which fields should be taken into account. If you mark a set of fields + * as valid, you are expected to fill them all. * * @return 0 if valid request, EINVAL if position structure rejected. */ @@ -373,7 +438,7 @@ * * Any client can make this request at any time. It takes effect no * sooner than the next process cycle, perhaps later if there are - * slow-sync clients. This function is realtime-safe. + * @ref slowsyncclients "slow-sync clients". This function is realtime-safe. * * @see jack_set_sync_callback * diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/types.h jack-audio-connection-kit-0.121.0+svn4538/jack/types.h --- jack-audio-connection-kit-0.118+svn4104/jack/types.h 2011-01-12 01:35:47.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/types.h 2011-02-28 18:57:45.000000000 +0000 @@ -22,6 +22,7 @@ #define __jack_types_h__ #include +#include typedef int32_t jack_shmsize_t; @@ -73,6 +74,12 @@ */ typedef uint32_t jack_port_id_t; +/** + * to make jack API independent of different thread implementations, + * we define jack_native_thread_t to pthread_t here. + * (all platforms that jack1 runs on, have pthread) + */ +typedef pthread_t jack_native_thread_t; /** * @ref jack_options_t bits @@ -254,7 +261,7 @@ * * @return zero on success, non-zero on error */ -typedef int (*JackLatencyCallback)(jack_latency_callback_mode_t mode, void *arg); +typedef void (*JackLatencyCallback)(jack_latency_callback_mode_t mode, void *arg); /** * the new latency API operates on Ranges. diff -Nru jack-audio-connection-kit-0.118+svn4104/jack/weakjack.h jack-audio-connection-kit-0.121.0+svn4538/jack/weakjack.h --- jack-audio-connection-kit-0.118+svn4104/jack/weakjack.h 2010-01-27 17:34:43.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jack/weakjack.h 2011-03-01 14:46:07.000000000 +0000 @@ -20,6 +20,59 @@ #ifndef __weakjack_h__ #define __weakjack_h__ +/** + * @defgroup WeakLinkage managing support for newer/older versions of JACK + * @{ One challenge faced by developers is that of taking advantage of new features introduced in new versions of [ JACK ] while still + * supporting older versions of the system. Normally, if an application uses a new feature in a library/API, it is unable to run on + * earlier versions of the library/API that do not support that feature. Such applications would either fail to launch or crash when + * an attempt to use the feature was made. This problem cane be solved using weakly-linked symbols. + * + * When a symbol in a framework is defined as weakly linked, the symbol does not have to be present at runtime for a process to + * continue running. The static linker identifies a weakly linked symbol as such in any code module that references the symbol. The + * dynamic linker uses this same information at runtime to determine whether a process can continue running. If a weakly linked symbol + * is not present in the framework, the code module can continue to run as long as it does not reference the symbol. However, if the + * symbol is present, the code can use it normally. + * + * (adapted from: http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html) + * + * A concrete example will help. Suppose that someone uses a version + * of a JACK client we'll call "Jill". Jill was linked against a version + * of JACK that contains a newer part of the API (say, jack_set_latency_callback()) + * and would like to use it if it is available. + * + * When Jill is run on a system that has a suitably "new" version of + * JACK, this function will be available entirely normally. But if Jill + * is run on a system with an old version of JACK, the function isn't + * available. + * + * With normal symbol linkage, this would create a startup error whenever + * someone tries to run Jill with the "old" version of JACK. However, functions + * added to JACK after version 0.116.2 are all declared to have "weak" linkage + * which means that their abscence doesn't cause an error during program + * startup. Instead, Jill can test whether or not the symbol jack_set_latency_callback + * is null or not. If its null, it means that the JACK installed on this machine + * is too old to support this function. If its not null, then Jill can use it + * just like any other function in the API. For example: + * + * \code + * if (jack_set_latency_callback) { + * jack_set_latency_callback (jill_client, jill_latency_callback, arg); + * } + * \endcode + * + * However, there are clients that may want to use this approach to parts of the + * the JACK API that predate 0.116.2. For example, they might want to see if even + * really old basic parts of the API like jack_client_open() exist at runtime. + * + * Such clients should include before any other JACK header. + * This will make the \b entire JACK API be subject to weak linkage, so that any + * and all functions can be checked for existence at runtime. It is important + * to understand that very few clients need to do this - if you use this + * feature you should have a clear reason to do so. + * + * + */ + #ifndef JACK_OPTIONAL_WEAK_EXPORT /* JACK_OPTIONAL_WEAK_EXPORT needs to be a macro which expands into a compiler directive. If non-null, the directive @@ -49,4 +102,6 @@ #endif #endif +/*@}*/ + #endif /* weakjack */ diff -Nru jack-audio-connection-kit-0.118+svn4104/jackd/clientengine.c jack-audio-connection-kit-0.121.0+svn4538/jackd/clientengine.c --- jack-audio-connection-kit-0.118+svn4104/jackd/clientengine.c 2010-11-17 02:24:04.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jackd/clientengine.c 2011-05-29 00:47:20.000000000 +0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -157,7 +158,7 @@ jack_client_do_deactivate (engine, client, FALSE); } -static void +void jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) { JSList *node; @@ -236,7 +237,7 @@ } } -void +int jack_check_clients (jack_engine_t* engine, int with_timeout_check) { /* CALLER MUST HOLD graph read lock */ @@ -269,9 +270,32 @@ if (client->control->awake_at > 0) { if (client->control->finished_at == 0) { - client->control->timed_out++; - client->error++; - VERBOSE (engine, "client %s has timed out", client->control->name); + jack_time_t now = jack_get_microseconds(); + + if ((now - client->control->awake_at) < engine->driver->period_usecs) { + /* we give the client a bit of time, to finish the cycle + * we assume here, that we dont get signals delivered to this thread. + */ + struct timespec wait_time; + wait_time.tv_sec = 0; + wait_time.tv_nsec = (engine->driver->period_usecs - (now - client->control->awake_at)) * 1000; + VERBOSE (engine, "client %s seems to have timed out. we may have mercy of %d ns." , client->control->name, (int) wait_time.tv_nsec ); + nanosleep (&wait_time, NULL); + } + + if (client->control->finished_at == 0) { + client->control->timed_out++; + client->error++; + errs++; + VERBOSE (engine, "client %s has timed out", client->control->name); + } else { + /* + * the client recovered. if this is a single occurence, thats probably fine. + * however, we increase the continuous_stream flag. + */ + + engine->timeout_count += 1; + } } } } @@ -280,6 +304,8 @@ if (errs) { jack_engine_signal_problems (engine); } + + return errs; } void @@ -889,14 +915,14 @@ jack_client_activate (jack_engine_t *engine, jack_client_id_t id) { jack_client_internal_t *client; - JSList *node, *node2; + JSList *node; int ret = -1; int i; jack_event_t event; jack_lock_graph (engine); - if (client = jack_client_internal_by_id (engine, id)) + if ((client = jack_client_internal_by_id (engine, id))) { client->control->active = TRUE; @@ -923,8 +949,8 @@ jack_deliver_event (engine, client, &event); // send delayed notifications for ports. - for (node2 = client->ports; node2; node2 = jack_slist_next (node2)) { - jack_port_internal_t *port = (jack_port_internal_t *) node2->data; + for (node = client->ports; node; node = jack_slist_next (node)) { + jack_port_internal_t *port = (jack_port_internal_t *) node->data; jack_port_registration_notify (engine, port->shared->id, TRUE); } diff -Nru jack-audio-connection-kit-0.118+svn4104/jackd/clientengine.h jack-audio-connection-kit-0.121.0+svn4538/jackd/clientengine.h --- jack-audio-connection-kit-0.118+svn4104/jackd/clientengine.h 2010-01-26 19:28:44.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jackd/clientengine.h 2011-05-29 00:47:16.000000000 +0000 @@ -58,7 +58,8 @@ jack_request_t *req); void jack_intclient_unload_request (jack_engine_t *engine, jack_request_t *req); -void jack_check_clients (jack_engine_t* engine, int with_timeout_check); +int jack_check_clients (jack_engine_t* engine, int with_timeout_check); void jack_remove_clients (jack_engine_t* engine, int* exit_freewheeling); void jack_client_registration_notify (jack_engine_t *engine, const char* name, int yn); +void jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client); diff -Nru jack-audio-connection-kit-0.118+svn4104/jackd/controlapi.c jack-audio-connection-kit-0.121.0+svn4538/jackd/controlapi.c --- jack-audio-connection-kit-0.118+svn4104/jackd/controlapi.c 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jackd/controlapi.c 2011-05-29 00:47:52.000000000 +0000 @@ -0,0 +1,1537 @@ +// u/* -*- Mode: C++ ; c-basic-offset: 4 -*- */ +/* + JACK control API implementation + + Copyright (C) 2008 Nedko Arnaudov + Copyright (C) 2008 Grame + + 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; version 2 of the License. + + 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. + +*/ + +#ifndef WIN32 +#include +#include +#include +#endif + +#include "config.h" + +#include "jack/internal.h" +#include +#include +#include +#include +#include + +#include "jack/jslist.h" +#include "jack/driver_interface.h" +#include "jack/driver.h" + +#include "jack/engine.h" +#include "clientengine.h" +//#include "JackError.h" +//#include "JackServer.h" +//#include "shm.h" +//#include "JackTools.h" +//#include "JackControlAPI.h" +//#include "JackLockedEngine.h" +//#include "JackConstants.h" +//#include "JackDriverLoader.h" +//#include "JackServerGlobals.h" + +#include "jack/control.h" + +/* + * XXX: dont like statics here. + */ +static JSList *drivers = NULL; + +struct jackctl_server +{ + JSList * drivers; + JSList * internals; + JSList * parameters; + + jack_engine_t * engine; + + /* string, server name */ + union jackctl_parameter_value name; + union jackctl_parameter_value default_name; + + /* bool, whether to be "realtime" */ + union jackctl_parameter_value realtime; + union jackctl_parameter_value default_realtime; + + /* int32_t */ + union jackctl_parameter_value realtime_priority; + union jackctl_parameter_value default_realtime_priority; + + /* bool, whether to exit once all clients have closed their connections */ + union jackctl_parameter_value temporary; + union jackctl_parameter_value default_temporary; + + /* bool, whether to be verbose */ + union jackctl_parameter_value verbose; + union jackctl_parameter_value default_verbose; + + /* int32_t, msecs; if zero, use period size. */ + union jackctl_parameter_value client_timeout; + union jackctl_parameter_value default_client_timeout; + + /* uint32_t, clock source type */ + union jackctl_parameter_value clock_source; + union jackctl_parameter_value default_clock_source; + + /* uint32_t, max port number */ + union jackctl_parameter_value port_max; + union jackctl_parameter_value default_port_max; + + /* bool */ + union jackctl_parameter_value replace_registry; + union jackctl_parameter_value default_replace_registry; + + /* bool, use mlock */ + union jackctl_parameter_value do_mlock; + union jackctl_parameter_value default_do_mlock; + + /* bool, munlock gui libraries */ + union jackctl_parameter_value do_unlock; + union jackctl_parameter_value default_do_unlock; + + /* bool, dont zombify... */ + union jackctl_parameter_value nozombies; + union jackctl_parameter_value default_nozombies; + + /* int, timeout thres... */ + union jackctl_parameter_value timothres; + union jackctl_parameter_value default_timothres; +}; + +struct jackctl_driver +{ + jack_driver_desc_t * desc_ptr; + JSList * parameters; + JSList * set_parameters; +}; + +struct jackctl_internal +{ + jack_driver_desc_t * desc_ptr; + JSList * parameters; + JSList * set_parameters; + int refnum; +}; + +struct jackctl_parameter +{ + const char * name; + const char * short_description; + const char * long_description; + jackctl_param_type_t type; + bool is_set; + union jackctl_parameter_value * value_ptr; + union jackctl_parameter_value * default_value_ptr; + + union jackctl_parameter_value value; + union jackctl_parameter_value default_value; + struct jackctl_driver * driver_ptr; + char id; + jack_driver_param_t * driver_parameter_ptr; + jack_driver_param_constraint_desc_t * constraint_ptr; +}; + +static +struct jackctl_parameter * +jackctl_add_parameter( + JSList ** parameters_list_ptr_ptr, + char id, + const char * name, + const char * short_description, + const char * long_description, + jackctl_param_type_t type, + union jackctl_parameter_value * value_ptr, + union jackctl_parameter_value * default_value_ptr, + union jackctl_parameter_value value, + jack_driver_param_constraint_desc_t * constraint_ptr) +{ + struct jackctl_parameter * parameter_ptr; + + parameter_ptr = (struct jackctl_parameter *)malloc(sizeof(struct jackctl_parameter)); + if (parameter_ptr == NULL) + { + jack_error("Cannot allocate memory for jackctl_parameter structure."); + goto fail; + } + + parameter_ptr->name = name; + parameter_ptr->short_description = short_description; + parameter_ptr->long_description = long_description; + parameter_ptr->type = type; + parameter_ptr->is_set = false; + + if (value_ptr == NULL) + { + value_ptr = ¶meter_ptr->value; + } + + if (default_value_ptr == NULL) + { + default_value_ptr = ¶meter_ptr->default_value; + } + + parameter_ptr->value_ptr = value_ptr; + parameter_ptr->default_value_ptr = default_value_ptr; + + *value_ptr = *default_value_ptr = value; + + parameter_ptr->driver_ptr = NULL; + parameter_ptr->driver_parameter_ptr = NULL; + parameter_ptr->id = id; + parameter_ptr->constraint_ptr = constraint_ptr; + + *parameters_list_ptr_ptr = jack_slist_append(*parameters_list_ptr_ptr, parameter_ptr); + + return parameter_ptr; + +fail: + return NULL; +} + +static +void +jackctl_free_driver_parameters( + struct jackctl_driver * driver_ptr) +{ + JSList * next_node_ptr; + + while (driver_ptr->parameters) + { + next_node_ptr = driver_ptr->parameters->next; + free(driver_ptr->parameters->data); + free(driver_ptr->parameters); + driver_ptr->parameters = next_node_ptr; + } + + while (driver_ptr->set_parameters) + { + next_node_ptr = driver_ptr->set_parameters->next; + free(driver_ptr->set_parameters->data); + free(driver_ptr->set_parameters); + driver_ptr->set_parameters = next_node_ptr; + } +} + +static +bool +jackctl_add_driver_parameters( + struct jackctl_driver * driver_ptr) +{ + uint32_t i; + union jackctl_parameter_value jackctl_value; + jackctl_param_type_t jackctl_type; + struct jackctl_parameter * parameter_ptr; + jack_driver_param_desc_t * descriptor_ptr; + + for (i = 0 ; i < driver_ptr->desc_ptr->nparams ; i++) + { + descriptor_ptr = driver_ptr->desc_ptr->params + i; + + switch (descriptor_ptr->type) + { + case JackDriverParamInt: + jackctl_type = JackParamInt; + jackctl_value.i = descriptor_ptr->value.i; + break; + case JackDriverParamUInt: + jackctl_type = JackParamUInt; + jackctl_value.ui = descriptor_ptr->value.ui; + break; + case JackDriverParamChar: + jackctl_type = JackParamChar; + jackctl_value.c = descriptor_ptr->value.c; + break; + case JackDriverParamString: + jackctl_type = JackParamString; + strcpy(jackctl_value.str, descriptor_ptr->value.str); + break; + case JackDriverParamBool: + jackctl_type = JackParamBool; + jackctl_value.b = descriptor_ptr->value.i; + break; + default: + jack_error("unknown driver parameter type %i", (int)descriptor_ptr->type); + assert(0); + goto fail; + } + + parameter_ptr = jackctl_add_parameter( + &driver_ptr->parameters, + descriptor_ptr->character, + descriptor_ptr->name, + descriptor_ptr->short_desc, + descriptor_ptr->long_desc, + jackctl_type, + NULL, + NULL, + jackctl_value, + descriptor_ptr->constraint); + + if (parameter_ptr == NULL) + { + goto fail; + } + + parameter_ptr->driver_ptr = driver_ptr; + } + + return true; + +fail: + jackctl_free_driver_parameters(driver_ptr); + + return false; +} + +static jack_driver_desc_t * +jack_drivers_get_descriptor (JSList * drivers, const char * sofile) +{ + jack_driver_desc_t * descriptor, * other_descriptor; + JackDriverDescFunction so_get_descriptor; + JSList * node; + void * dlhandle; + char * filename; + const char * dlerr; + int err; + char* driver_dir; + + if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { + driver_dir = ADDON_DIR; + } + filename = malloc (strlen (driver_dir) + 1 + strlen (sofile) + 1); + sprintf (filename, "%s/%s", driver_dir, sofile); + +// if (verbose) { +// jack_info ("getting driver descriptor from %s", filename); +// } + + if ((dlhandle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL)) == NULL) { + jack_error ("could not open driver .so '%s': %s\n", filename, dlerror ()); + free (filename); + return NULL; + } + + so_get_descriptor = (JackDriverDescFunction) + dlsym (dlhandle, "driver_get_descriptor"); + + if ((dlerr = dlerror ()) != NULL) { + jack_error("%s", dlerr); + dlclose (dlhandle); + free (filename); + return NULL; + } + + if ((descriptor = so_get_descriptor ()) == NULL) { + jack_error ("driver from '%s' returned NULL descriptor\n", filename); + dlclose (dlhandle); + free (filename); + return NULL; + } + + if ((err = dlclose (dlhandle)) != 0) { + 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; + + if (strcmp (descriptor->name, other_descriptor->name) == 0) { + jack_error ("the drivers in '%s' and '%s' both have the name '%s'; using the first\n", + other_descriptor->file, filename, other_descriptor->name); + /* FIXME: delete the descriptor */ + free (filename); + return NULL; + } + } + + snprintf (descriptor->file, sizeof(descriptor->file), "%s", filename); + free (filename); + + return descriptor; +} + +static JSList * +jack_drivers_load () +{ + struct dirent * dir_entry; + DIR * dir_stream; + const char * ptr; + int err; + JSList * driver_list = NULL; + jack_driver_desc_t * desc; + char* driver_dir; + + if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { + driver_dir = ADDON_DIR; + } + + /* search through the driver_dir and add get descriptors + from the .so files in it */ + dir_stream = opendir (driver_dir); + if (!dir_stream) { + jack_error ("could not open driver directory %s: %s\n", + driver_dir, strerror (errno)); + return NULL; + } + + while ( (dir_entry = readdir (dir_stream)) ) { + /* check the filename is of the right format */ + if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { + continue; + } + + ptr = strrchr (dir_entry->d_name, '.'); + if (!ptr) { + continue; + } + ptr++; + if (strncmp ("so", ptr, 2) != 0) { + continue; + } + + desc = jack_drivers_get_descriptor (drivers, dir_entry->d_name); + if (desc) { + driver_list = jack_slist_append (driver_list, desc); + } + } + + err = closedir (dir_stream); + if (err) { + jack_error ("error closing driver directory %s: %s\n", + driver_dir, strerror (errno)); + } + + if (!driver_list) { + jack_error ("could not find any drivers in %s!\n", driver_dir); + return NULL; + } + + return driver_list; +} + +static void +jack_cleanup_files (const char *server_name) +{ + DIR *dir; + struct dirent *dirent; + char dir_name[PATH_MAX+1] = ""; + jack_server_dir (server_name, dir_name); + + /* On termination, we remove all files that jackd creates so + * subsequent attempts to start jackd will not believe that an + * instance is already running. If the server crashes or is + * terminated with SIGKILL, this is not possible. So, cleanup + * is also attempted when jackd starts. + * + * There are several tricky issues. First, the previous JACK + * server may have run for a different user ID, so its files + * may be inaccessible. This is handled by using a separate + * JACK_TMP_DIR subdirectory for each user. Second, there may + * be other servers running with different names. Each gets + * its own subdirectory within the per-user directory. The + * current process has already registered as `server_name', so + * we know there is no other server actively using that name. + */ + + /* nothing to do if the server directory does not exist */ + if ((dir = opendir (dir_name)) == NULL) { + return; + } + + /* unlink all the files in this directory, they are mine */ + while ((dirent = readdir (dir)) != NULL) { + + char fullpath[PATH_MAX+1]; + + if ((strcmp (dirent->d_name, ".") == 0) + || (strcmp (dirent->d_name, "..") == 0)) { + continue; + } + + snprintf (fullpath, sizeof (fullpath), "%s/%s", + dir_name, dirent->d_name); + + if (unlink (fullpath)) { + jack_error ("cannot unlink `%s' (%s)", fullpath, + strerror (errno)); + } + } + + closedir (dir); + + /* now, delete the per-server subdirectory, itself */ + if (rmdir (dir_name)) { + jack_error ("cannot remove `%s' (%s)", dir_name, + strerror (errno)); + } + + /* finally, delete the per-user subdirectory, if empty */ + if (rmdir (jack_user_dir ())) { + if (errno != ENOTEMPTY) { + jack_error ("cannot remove `%s' (%s)", + jack_user_dir (), strerror (errno)); + } + } +} + +static int +jackctl_drivers_load( + struct jackctl_server * server_ptr) +{ + struct jackctl_driver * driver_ptr; + JSList *node_ptr; + JSList *descriptor_node_ptr; + + descriptor_node_ptr = jack_drivers_load(); + if (descriptor_node_ptr == NULL) + { + jack_error("could not find any drivers in driver directory!"); + return false; + } + + while (descriptor_node_ptr != NULL) + { + driver_ptr = (struct jackctl_driver *)malloc(sizeof(struct jackctl_driver)); + if (driver_ptr == NULL) + { + jack_error("memory allocation of jackctl_driver structure failed."); + goto next; + } + + driver_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; + driver_ptr->parameters = NULL; + driver_ptr->set_parameters = NULL; + + if (!jackctl_add_driver_parameters(driver_ptr)) + { + assert(driver_ptr->parameters == NULL); + free(driver_ptr); + goto next; + } + + server_ptr->drivers = jack_slist_append(server_ptr->drivers, driver_ptr); + + next: + node_ptr = descriptor_node_ptr; + descriptor_node_ptr = descriptor_node_ptr->next; + free(node_ptr); + } + + return true; +} + +static +void +jackctl_server_free_drivers( + struct jackctl_server * server_ptr) +{ + JSList * next_node_ptr; + struct jackctl_driver * driver_ptr; + + while (server_ptr->drivers) + { + next_node_ptr = server_ptr->drivers->next; + driver_ptr = (struct jackctl_driver *)server_ptr->drivers->data; + + jackctl_free_driver_parameters(driver_ptr); + free(driver_ptr->desc_ptr->params); + free(driver_ptr->desc_ptr); + free(driver_ptr); + + free(server_ptr->drivers); + server_ptr->drivers = next_node_ptr; + } +} + +static int +jackctl_internals_load( + struct jackctl_server * server_ptr) +{ + struct jackctl_internal * internal_ptr; + JSList *node_ptr; + JSList *descriptor_node_ptr = NULL; + + //XXX: jack1 doesnt support internals enumeration. + //descriptor_node_ptr = jack_internals_load(NULL); + if (descriptor_node_ptr == NULL) + { + return false; + } + + while (descriptor_node_ptr != NULL) + { + internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal)); + if (internal_ptr == NULL) + { + jack_error("memory allocation of jackctl_driver structure failed."); + goto next; + } + + internal_ptr->desc_ptr = (jack_driver_desc_t *)descriptor_node_ptr->data; + internal_ptr->parameters = NULL; + internal_ptr->set_parameters = NULL; + + if (!jackctl_add_driver_parameters((struct jackctl_driver *)internal_ptr)) + { + assert(internal_ptr->parameters == NULL); + free(internal_ptr); + goto next; + } + + server_ptr->internals = jack_slist_append(server_ptr->internals, internal_ptr); + + next: + node_ptr = descriptor_node_ptr; + descriptor_node_ptr = descriptor_node_ptr->next; + free(node_ptr); + } + + return true; +} + +static +void +jackctl_server_free_internals( + struct jackctl_server * server_ptr) +{ + JSList * next_node_ptr; + struct jackctl_internal * internal_ptr; + + while (server_ptr->internals) + { + next_node_ptr = server_ptr->internals->next; + internal_ptr = (struct jackctl_internal *)server_ptr->internals->data; + + jackctl_free_driver_parameters((struct jackctl_driver *)internal_ptr); + free(internal_ptr->desc_ptr->params); + free(internal_ptr->desc_ptr); + free(internal_ptr); + + free(server_ptr->internals); + server_ptr->internals = next_node_ptr; + } +} + +static +void +jackctl_server_free_parameters( + struct jackctl_server * server_ptr) +{ + JSList * next_node_ptr; + + while (server_ptr->parameters) + { + next_node_ptr = server_ptr->parameters->next; + free(server_ptr->parameters->data); + free(server_ptr->parameters); + server_ptr->parameters = next_node_ptr; + } +} + +#ifdef WIN32 + +static HANDLE waitEvent; + +static void do_nothing_handler(int signum) +{ + printf("jack main caught signal %d\n", signum); + (void) signal(SIGINT, SIG_DFL); + SetEvent(waitEvent); +} + +sigset_t +jackctl_setup_signals( + unsigned int flags) +{ + if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { + jack_error("CreateEvent fails err = %ld", GetLastError()); + return 0; + } + + (void) signal(SIGINT, do_nothing_handler); + (void) signal(SIGABRT, do_nothing_handler); + (void) signal(SIGTERM, do_nothing_handler); + + return (sigset_t)waitEvent; +} + +void jackctl_wait_signals(sigset_t signals) +{ + if (WaitForSingleObject(waitEvent, INFINITE) != WAIT_OBJECT_0) { + jack_error("WaitForSingleObject fails err = %ld", GetLastError()); + } +} + +#else + +static +void +do_nothing_handler(int sig) +{ + /* this is used by the child (active) process, but it never + gets called unless we are already shutting down after + another signal. + */ + char buf[64]; + snprintf (buf, sizeof(buf), "received signal %d during shutdown (ignored)\n", sig); +} + +sigset_t +jackctl_setup_signals( + unsigned int flags) +{ + sigset_t signals; + sigset_t allsignals; + struct sigaction action; + int i; + + /* ensure that we are in our own process group so that + kill (SIG, -pgrp) does the right thing. + */ + + setsid(); + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + /* what's this for? + + POSIX says that signals are delivered like this: + + * if a thread has blocked that signal, it is not + a candidate to receive the signal. + * of all threads not blocking the signal, pick + one at random, and deliver the signal. + + this means that a simple-minded multi-threaded program can + expect to get POSIX signals delivered randomly to any one + of its threads, + + here, we block all signals that we think we might receive + and want to catch. all "child" threads will inherit this + setting. if we create a thread that calls sigwait() on the + same set of signals, implicitly unblocking all those + signals. any of those signals that are delivered to the + process will be delivered to that thread, and that thread + alone. this makes cleanup for a signal-driven exit much + easier, since we know which thread is doing it and more + importantly, we are free to call async-unsafe functions, + because the code is executing in normal thread context + after a return from sigwait(). + */ + + sigemptyset(&signals); + sigaddset(&signals, SIGHUP); + sigaddset(&signals, SIGINT); + sigaddset(&signals, SIGQUIT); + sigaddset(&signals, SIGPIPE); + sigaddset(&signals, SIGTERM); + sigaddset(&signals, SIGUSR1); + sigaddset(&signals, SIGUSR2); + + /* all child threads will inherit this mask unless they + * explicitly reset it + */ + + pthread_sigmask(SIG_BLOCK, &signals, 0); + + /* install a do-nothing handler because otherwise pthreads + behaviour is undefined when we enter sigwait. + */ + + sigfillset(&allsignals); + action.sa_handler = do_nothing_handler; + action.sa_mask = allsignals; + action.sa_flags = SA_RESTART|SA_RESETHAND; + + for (i = 1; i < NSIG; i++) + { + if (sigismember (&signals, i)) + { + sigaction(i, &action, 0); + } + } + + return signals; +} + +void +jackctl_wait_signals(sigset_t signals) +{ + int sig; + bool waiting = true; + + while (waiting) { + #if defined(sun) && !defined(__sun__) // SUN compiler only, to check + sigwait(&signals); + #else + sigwait(&signals, &sig); + #endif + fprintf(stderr, "jack main caught signal %d\n", sig); + + switch (sig) { + case SIGUSR1: + //jack_dump_configuration(engine, 1); + break; + case SIGUSR2: + // driver exit + waiting = false; + break; + case SIGTTOU: + break; + default: + waiting = false; + break; + } + } + + if (sig != SIGSEGV) { + // unblock signals so we can see them during shutdown. + // this will help prod developers not to lose sight of + // bugs that cause segfaults etc. during shutdown. + sigprocmask(SIG_UNBLOCK, &signals, 0); + } +} +#endif + +static sigset_t +jackctl_block_signals() +{ + sigset_t signals; + sigset_t oldsignals; + + sigemptyset(&signals); + sigaddset(&signals, SIGHUP); + sigaddset(&signals, SIGINT); + sigaddset(&signals, SIGQUIT); + sigaddset(&signals, SIGPIPE); + sigaddset(&signals, SIGTERM); + sigaddset(&signals, SIGUSR1); + sigaddset(&signals, SIGUSR2); + + pthread_sigmask(SIG_BLOCK, &signals, &oldsignals); + + return oldsignals; +} + +static void +jackctl_unblock_signals(sigset_t oldsignals) +{ + pthread_sigmask(SIG_SETMASK, &oldsignals, 0); +} + + +static +jack_driver_param_constraint_desc_t * +get_realtime_priority_constraint() +{ +#ifndef __OpenBSD__ + jack_driver_param_constraint_desc_t * constraint_ptr; + + int max = sched_get_priority_max (SCHED_FIFO); + int min = sched_get_priority_min (SCHED_FIFO); + + //jack_info("realtime priority range is (%d,%d)", min, max); + + constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t)); + if (constraint_ptr == NULL) + { + jack_error("Cannot allocate memory for jack_driver_param_constraint_desc_t structure."); + return NULL; + } + constraint_ptr->flags = JACK_CONSTRAINT_FLAG_RANGE; + + constraint_ptr->constraint.range.min.i = min; + constraint_ptr->constraint.range.max.i = max; + + return constraint_ptr; +#else + return NULL +#endif +} + +jackctl_server_t * jackctl_server_create( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name)) +{ + struct jackctl_server * server_ptr; + union jackctl_parameter_value value; + + server_ptr = (struct jackctl_server *)malloc(sizeof(struct jackctl_server)); + if (server_ptr == NULL) + { + jack_error("Cannot allocate memory for jackctl_server structure."); + goto fail; + } + + server_ptr->drivers = NULL; + server_ptr->internals = NULL; + server_ptr->parameters = NULL; + server_ptr->engine = NULL; + + strcpy(value.str, jack_default_server_name() ); + if (jackctl_add_parameter( + &server_ptr->parameters, + 'n', + "name", + "Server name to use.", + "", + JackParamString, + &server_ptr->name, + &server_ptr->default_name, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.b = false; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'R', + "realtime", + "Whether to use realtime mode.", + "Use realtime scheduling. This is needed for reliable low-latency performance. On most systems, it requires JACK to run with special scheduler and memory allocation privileges, which may be obtained in several ways. On Linux you should use PAM.", + JackParamBool, + &server_ptr->realtime, + &server_ptr->default_realtime, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.i = 10; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'P', + "realtime-priority", + "Scheduler priority when running in realtime mode.", + "", + JackParamInt, + &server_ptr->realtime_priority, + &server_ptr->default_realtime_priority, + value, + get_realtime_priority_constraint() + ) == NULL) + { + goto fail_free_parameters; + } + + value.b = false; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'T', + "temporary", + "Exit once all clients have closed their connections.", + "", + JackParamBool, + &server_ptr->temporary, + &server_ptr->default_temporary, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.b = false; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'v', + "verbose", + "Verbose mode.", + "", + JackParamBool, + &server_ptr->verbose, + &server_ptr->default_verbose, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.i = 0; + if (jackctl_add_parameter( + &server_ptr->parameters, + 't', + "client-timeout", + "Client timeout limit in milliseconds.", + "", + JackParamInt, + &server_ptr->client_timeout, + &server_ptr->default_client_timeout, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.ui = 0; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'c', + "clock-source", + "Clocksource type : c(ycle) | h(pet) | s(ystem).", + "", + JackParamUInt, + &server_ptr->clock_source, + &server_ptr->default_clock_source, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.ui = 128; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'p', + "port-max", + "Maximum number of ports.", + "", + JackParamUInt, + &server_ptr->port_max, + &server_ptr->default_port_max, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.b = false; + if (jackctl_add_parameter( + &server_ptr->parameters, + '\0', + "replace-registry", + "Replace shared memory registry.", + "", + JackParamBool, + &server_ptr->replace_registry, + &server_ptr->default_replace_registry, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.b = false; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'm', + "mlock", + "Use mlock.", + "", + JackParamBool, + &server_ptr->do_mlock, + &server_ptr->default_do_mlock, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.b = false; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'u', + "unlock", + "munlock memory for big libraries", + "", + JackParamBool, + &server_ptr->do_unlock, + &server_ptr->default_do_unlock, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.b = false; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'Z', + "nozombies", + "dont zombifiy offending clients", + "", + JackParamBool, + &server_ptr->nozombies, + &server_ptr->default_nozombies, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + value.ui = 0; + if (jackctl_add_parameter( + &server_ptr->parameters, + 'C', + "timeout-threshold", + "threshold for suspending processing", + "", + JackParamUInt, + &server_ptr->timothres, + &server_ptr->default_timothres, + value, NULL) == NULL) + { + goto fail_free_parameters; + } + + //TODO: need + //JackServerGlobals::on_device_acquire = on_device_acquire; + //JackServerGlobals::on_device_release = on_device_release; + + if (!jackctl_drivers_load(server_ptr)) + { + goto fail_free_parameters; + } + + /* Allowed to fail */ + jackctl_internals_load(server_ptr); + + return server_ptr; + +fail_free_parameters: + jackctl_server_free_parameters(server_ptr); + + free(server_ptr); + +fail: + return NULL; +} + +void jackctl_server_destroy(jackctl_server_t *server_ptr) +{ + jackctl_server_free_drivers(server_ptr); + jackctl_server_free_internals(server_ptr); + jackctl_server_free_parameters(server_ptr); + free(server_ptr); +} + +const JSList * jackctl_server_get_drivers_list(jackctl_server_t *server_ptr) +{ + return server_ptr->drivers; +} + +bool jackctl_server_stop(jackctl_server_t *server_ptr) +{ + //jack_engine_driver_exit (server_ptr->engine); + jack_engine_delete (server_ptr->engine); + + /* clean up shared memory and files from this server instance */ + //jack_log("cleaning up shared memory"); + + jack_cleanup_shm(); + + //jack_log("cleaning up files"); + + jack_cleanup_files (server_ptr->name.str); + + //jack_log("unregistering server `%s'", server_ptr->name.str); + + jack_unregister_server(server_ptr->name.str); + + server_ptr->engine = NULL; + + return true; +} + +const JSList * jackctl_server_get_parameters(jackctl_server_t *server_ptr) +{ + return server_ptr->parameters; +} + +bool +jackctl_server_start( + jackctl_server_t *server_ptr, + jackctl_driver_t *driver_ptr) +{ + int rc; + sigset_t oldsignals; + + + // TODO: + int frame_time_offset = 0; + + rc = jack_register_server (server_ptr->name.str, server_ptr->replace_registry.b); + switch (rc) + { + case EEXIST: + jack_error("`%s' server already active", server_ptr->name.str); + goto fail; + case ENOSPC: + jack_error("too many servers already active"); + goto fail; + case ENOMEM: + jack_error("no access to shm registry"); + goto fail; + } + + //jack_log("server `%s' registered", server_ptr->name.str); + + /* clean up shared memory and files from any previous + * instance of this server name */ + jack_cleanup_shm (); + jack_cleanup_files (server_ptr->name.str); + + if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) + server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ + + oldsignals = jackctl_block_signals(); + + if ((server_ptr->engine = jack_engine_new (server_ptr->realtime.b, server_ptr->realtime_priority.i, + server_ptr->do_mlock.b, server_ptr->do_unlock.b, server_ptr->name.str, + server_ptr->temporary.b, server_ptr->verbose.b, server_ptr->client_timeout.i, + server_ptr->port_max.i, getpid(), frame_time_offset, + server_ptr->nozombies.b, server_ptr->timothres.ui, drivers)) == 0) { + jack_error ("cannot create engine"); + goto fail_unregister; + } + + if (jack_engine_load_driver (server_ptr->engine, driver_ptr->desc_ptr, driver_ptr->set_parameters)) + { + jack_error ("cannot load driver module %s", driver_ptr->desc_ptr->name); + goto fail_delete; + } + + if (server_ptr->engine->driver->start (server_ptr->engine->driver) != 0) { + jack_error ("cannot start driver"); + goto fail_close; + } + + jackctl_unblock_signals( oldsignals ); + return true; + +fail_close: + +fail_delete: + jack_engine_delete (server_ptr->engine); + server_ptr->engine = NULL; + +fail_unregister: + //jack_log("cleaning up shared memory"); + + jack_cleanup_shm(); + + //jack_log("cleaning up files"); + + jack_cleanup_files(server_ptr->name.str); + + //jack_log("unregistering server `%s'", server_ptr->name.str); + + jack_unregister_server(server_ptr->name.str); + jackctl_unblock_signals( oldsignals ); + +fail: + return false; +} + +const char * jackctl_driver_get_name(jackctl_driver_t *driver_ptr) +{ + return driver_ptr->desc_ptr->name; +} + +const JSList * jackctl_driver_get_parameters(jackctl_driver_t *driver_ptr) +{ + return driver_ptr->parameters; +} + +jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver_t *driver_ptr) +{ + return driver_ptr->desc_ptr; +} + +const char * jackctl_parameter_get_name(jackctl_parameter_t *parameter_ptr) +{ + return parameter_ptr->name; +} + +const char * jackctl_parameter_get_short_description(jackctl_parameter_t *parameter_ptr) +{ + return parameter_ptr->short_description; +} + +const char * jackctl_parameter_get_long_description(jackctl_parameter_t *parameter_ptr) +{ + return parameter_ptr->long_description; +} + +bool jackctl_parameter_has_range_constraint(jackctl_parameter_t *parameter_ptr) +{ + return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) != 0; +} + +bool jackctl_parameter_has_enum_constraint(jackctl_parameter_t *parameter_ptr) +{ + return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0; +} + +uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter_t *parameter_ptr) +{ + if (!jackctl_parameter_has_enum_constraint(parameter_ptr)) + { + return 0; + } + + return parameter_ptr->constraint_ptr->constraint.enumeration.count; +} + +union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter_t *parameter_ptr, uint32_t index) +{ + jack_driver_param_value_t * value_ptr; + union jackctl_parameter_value jackctl_value; + + value_ptr = ¶meter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].value; + + switch (parameter_ptr->type) + { + case JackParamInt: + jackctl_value.i = value_ptr->i; + break; + case JackParamUInt: + jackctl_value.ui = value_ptr->ui; + break; + case JackParamChar: + jackctl_value.c = value_ptr->c; + break; + case JackParamString: + strcpy(jackctl_value.str, value_ptr->str); + break; + default: + jack_error("bad driver parameter type %i (enum constraint)", (int)parameter_ptr->type); + assert(0); + } + + return jackctl_value; +} + +const char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter_t *parameter_ptr, uint32_t index) +{ + return parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].short_desc; +} + +void jackctl_parameter_get_range_constraint(jackctl_parameter_t *parameter_ptr, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr) +{ + switch (parameter_ptr->type) + { + case JackParamInt: + min_ptr->i = parameter_ptr->constraint_ptr->constraint.range.min.i; + max_ptr->i = parameter_ptr->constraint_ptr->constraint.range.max.i; + return; + case JackParamUInt: + min_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.min.ui; + max_ptr->ui = parameter_ptr->constraint_ptr->constraint.range.max.ui; + return; + default: + jack_error("bad driver parameter type %i (range constraint)", (int)parameter_ptr->type); + assert(0); + } +} + +bool jackctl_parameter_constraint_is_strict(jackctl_parameter_t * parameter_ptr) +{ + return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_STRICT) != 0; +} + +bool jackctl_parameter_constraint_is_fake_value(jackctl_parameter_t * parameter_ptr) +{ + return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0; +} + +jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter_t *parameter_ptr) +{ + return parameter_ptr->type; +} + +char jackctl_parameter_get_id(jackctl_parameter_t * parameter_ptr) +{ + return parameter_ptr->id; +} + +bool jackctl_parameter_is_set(jackctl_parameter_t *parameter_ptr) +{ + return parameter_ptr->is_set; +} + +union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter_t *parameter_ptr) +{ + return *(parameter_ptr->value_ptr); +} + +bool jackctl_parameter_reset(jackctl_parameter_t *parameter_ptr) +{ + if (!parameter_ptr->is_set) + { + return true; + } + + parameter_ptr->is_set = false; + + *parameter_ptr->value_ptr = *parameter_ptr->default_value_ptr; + + return true; +} + +bool jackctl_parameter_set_value(jackctl_parameter_t *parameter_ptr, const union jackctl_parameter_value * value_ptr) +{ + bool new_driver_parameter; + + /* for driver parameters, set the parameter by adding jack_driver_param_t in the set_parameters list */ + if (parameter_ptr->driver_ptr != NULL) + { +/* jack_info("setting driver parameter %p ...", parameter_ptr); */ + new_driver_parameter = parameter_ptr->driver_parameter_ptr == NULL; + if (new_driver_parameter) + { +/* jack_info("new driver parameter..."); */ + parameter_ptr->driver_parameter_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t)); + if (parameter_ptr->driver_parameter_ptr == NULL) + { + jack_error ("Allocation of jack_driver_param_t structure failed"); + return false; + } + + parameter_ptr->driver_parameter_ptr->character = parameter_ptr->id; + parameter_ptr->driver_ptr->set_parameters = jack_slist_append(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr); + } + + switch (parameter_ptr->type) + { + case JackParamInt: + parameter_ptr->driver_parameter_ptr->value.i = value_ptr->i; + break; + case JackParamUInt: + parameter_ptr->driver_parameter_ptr->value.ui = value_ptr->ui; + break; + case JackParamChar: + parameter_ptr->driver_parameter_ptr->value.c = value_ptr->c; + break; + case JackParamString: + strcpy(parameter_ptr->driver_parameter_ptr->value.str, value_ptr->str); + break; + case JackParamBool: + parameter_ptr->driver_parameter_ptr->value.i = value_ptr->b; + break; + default: + jack_error("unknown parameter type %i", (int)parameter_ptr->type); + assert(0); + + if (new_driver_parameter) + { + parameter_ptr->driver_ptr->set_parameters = jack_slist_remove(parameter_ptr->driver_ptr->set_parameters, parameter_ptr->driver_parameter_ptr); + } + + return false; + } + } + + parameter_ptr->is_set = true; + *parameter_ptr->value_ptr = *value_ptr; + + return true; +} + +union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter_t *parameter_ptr) +{ + return *(parameter_ptr->default_value_ptr); +} + +// Internals clients + +const JSList * jackctl_server_get_internals_list(jackctl_server_t *server_ptr) +{ + return server_ptr->internals; +} + +const char * jackctl_internal_get_name(jackctl_internal_t *internal_ptr) +{ + return internal_ptr->desc_ptr->name; +} + +const JSList * jackctl_internal_get_parameters(jackctl_internal_t *internal_ptr) +{ + return internal_ptr->parameters; +} + +bool jackctl_server_load_internal( + jackctl_server_t * server_ptr, + jackctl_internal_t * internal) +{ + return false; +} + +bool jackctl_server_unload_internal( + jackctl_server_t * server_ptr, + jackctl_internal_t * internal) +{ + return false; +} + +bool jackctl_server_add_slave(jackctl_server_t * server_ptr, jackctl_driver_t * driver_ptr) +{ + return false; +} + +bool jackctl_server_remove_slave(jackctl_server_t * server_ptr, jackctl_driver_t * driver_ptr) +{ + return false; +} + +bool jackctl_server_switch_master(jackctl_server_t * server_ptr, jackctl_driver_t * driver_ptr) +{ + jack_driver_t *old_driver; + + if (server_ptr->engine == NULL) + goto fail_nostart; + + old_driver = server_ptr->engine->driver; + + if (old_driver) + { + old_driver->stop (old_driver ); + old_driver->detach (old_driver, server_ptr->engine); + + pthread_mutex_lock (&server_ptr->engine->request_lock); + jack_lock_graph (server_ptr->engine); + jack_remove_client (server_ptr->engine, old_driver->internal_client); + jack_unlock_graph (server_ptr->engine); + pthread_mutex_unlock (&server_ptr->engine->request_lock); + + jack_stop_watchdog (server_ptr->engine); + server_ptr->engine->driver = NULL; + + jack_driver_unload (old_driver); + } + + if (jack_engine_load_driver (server_ptr->engine, driver_ptr->desc_ptr, driver_ptr->set_parameters)) + { + jack_error ("cannot load driver module %s", driver_ptr->desc_ptr->name); + goto fail_nodriver; + } + + + if (server_ptr->engine->driver->start (server_ptr->engine->driver) != 0) { + jack_error ("cannot start driver"); + jack_use_driver(server_ptr->engine, NULL); + goto fail_nodriver; + } + + return true; + +fail_nodriver: + jack_error ("could not initialise new driver, leaving without driver"); + +fail_nostart: + return false; +} + diff -Nru jack-audio-connection-kit-0.118+svn4104/jackd/engine.c jack-audio-connection-kit-0.121.0+svn4538/jackd/engine.c --- jack-audio-connection-kit-0.118+svn4104/jackd/engine.c 2011-01-12 13:01:18.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jackd/engine.c 2011-06-19 22:10:03.000000000 +0000 @@ -115,7 +115,6 @@ jack_port_id_t b, int connect); static void jack_engine_post_process (jack_engine_t *); -static int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver); static int jack_run_cycle (jack_engine_t *engine, jack_nframes_t nframes, float delayed_usecs); static int jack_run_one_cycle (jack_engine_t *engine, jack_nframes_t nframes, @@ -137,6 +136,7 @@ static void jack_do_reserve_name ( jack_engine_t *engine, jack_request_t *req); static void jack_do_session_reply (jack_engine_t *engine, jack_request_t *req ); static void jack_compute_new_latency (jack_engine_t *engine); +static int jack_do_has_session_cb (jack_engine_t *engine, jack_request_t *req); static inline int jack_rolling_interval (jack_time_t period_usecs) @@ -530,14 +530,6 @@ } } - /* update shared client copy of nframes */ - jack_lock_graph (engine); - for (node = engine->clients; node; node = jack_slist_next (node)) { - jack_client_internal_t *client = node->data; - client->control->nframes = nframes; - } - jack_unlock_graph (engine); - event.type = BufferSizeChange; jack_deliver_event_to_all (engine, &event); @@ -798,23 +790,25 @@ ctl->finished_at? (ctl->finished_at - ctl->signalled_at): 0); - jack_check_clients (engine, 1); - - engine->process_errors++; - return NULL; /* will stop the loop */ + if (jack_check_clients (engine, 1)) { + engine->process_errors++; + return NULL; /* will stop the loop */ + } } else { + engine->timeout_count = 0; + } - DEBUG ("reading byte from subgraph_wait_fd==%d", - client->subgraph_wait_fd); - if (read (client->subgraph_wait_fd, &c, sizeof(c)) - != sizeof (c)) { - jack_error ("pp: cannot clean up byte from graph wait " - "fd (%s)", strerror (errno)); - client->error++; - return NULL; /* will stop the loop */ - } + DEBUG ("reading byte from subgraph_wait_fd==%d", + client->subgraph_wait_fd); + + if (read (client->subgraph_wait_fd, &c, sizeof(c)) + != sizeof (c)) { + jack_error ("pp: cannot clean up byte from graph wait " + "fd (%s)", strerror (errno)); + client->error++; + return NULL; /* will stop the loop */ } /* Move to next internal client (or end of client list) */ @@ -845,7 +839,6 @@ jack_client_control_t *ctl = ((jack_client_internal_t *) node->data)->control; ctl->state = NotTriggered; - ctl->nframes = nframes; ctl->timed_out = 0; ctl->awake_at = 0; ctl->finished_at = 0; @@ -949,6 +942,16 @@ return 0; } +void +jack_stop_watchdog (jack_engine_t *engine) +{ + /* Stephane Letz : letz@grame.fr Watch dog thread is + * not needed on MacOSX since CoreAudio drivers + * already contains a similar mechanism. + */ + return; +} + #else static void * @@ -1004,6 +1007,23 @@ return 0; } + +void +jack_stop_watchdog (jack_engine_t *engine) +{ + /* Cancel the watchdog thread and wait for it to terminate. + * + * The watchdog thread is not used on MacOSX since CoreAudio + * drivers already contain a similar mechanism. + */ + if (engine->control->real_time && engine->watchdog_thread) { + VERBOSE (engine, "stopping watchdog thread"); + pthread_cancel (engine->watchdog_thread); + pthread_join (engine->watchdog_thread, NULL); + } + + return; +} #endif /* !JACK_USE_MACH_THREADS */ @@ -1101,7 +1121,7 @@ free (info); if (jack_use_driver (engine, driver) < 0) { - jack_client_delete (engine, client); + jack_remove_client (engine, client); return -1; } @@ -1117,6 +1137,46 @@ return 0; } +int +jack_engine_load_slave_driver (jack_engine_t *engine, + jack_driver_desc_t * driver_desc, + JSList * driver_params) +{ + jack_client_internal_t *client; + jack_driver_t *driver; + jack_driver_info_t *info; + + if ((info = jack_load_driver (engine, driver_desc)) == NULL) { + return -1; + } + + if ((client = jack_create_driver_client (engine, info->client_name) + ) == NULL) { + return -1; + } + + if ((driver = info->initialize (client->private_client, + driver_params)) == NULL) { + free (info); + return -1; + } + + driver->handle = info->handle; + driver->finish = info->finish; + driver->internal_client = client; + free (info); + + if (jack_add_slave_driver (engine, driver) < 0) { + jack_client_delete (engine, client); + return -1; + } + + //engine->driver_desc = driver_desc; + //engine->driver_params = driver_params; + + return 0; +} + #ifdef USE_CAPABILITIES static int check_capabilities (jack_engine_t *engine) @@ -1383,6 +1443,10 @@ } jack_unlock_graph (engine); break; + case SessionHasCallback: + jack_rdlock_graph (engine); + req->status = jack_do_has_session_cb (engine, req); + jack_unlock_graph (engine); default: /* some requests are handled entirely on the client * side, by adjusting the shared memory area(s) */ @@ -1713,7 +1777,7 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int do_unlock, const char *server_name, int temporary, int verbose, int client_timeout, unsigned int port_max, pid_t wait_pid, - jack_nframes_t frame_time_offset, int nozombies, JSList *drivers) + jack_nframes_t frame_time_offset, int nozombies, int timeout_count_threshold, JSList *drivers) { jack_engine_t *engine; unsigned int i; @@ -1761,6 +1825,8 @@ engine->driver_desc = NULL; engine->driver_params = NULL; + engine->slave_drivers = NULL; + engine->set_sample_rate = jack_set_sample_rate; engine->set_buffer_size = jack_driver_buffer_size; engine->run_cycle = jack_run_cycle; @@ -1768,6 +1834,7 @@ engine->driver_exit = jack_engine_driver_exit; engine->transport_cycle_start = jack_transport_cycle_start; engine->client_timeout_msecs = client_timeout; + engine->timeout_count = 0; engine->problems = 0; engine->next_client_id = 1; /* 0 is a NULL client ID */ @@ -1785,6 +1852,7 @@ engine->feedbackcount = 0; engine->wait_pid = wait_pid; engine->nozombies = nozombies; + engine->timeout_count_threshold = timeout_count_threshold; engine->removing_clients = 0; engine->new_clients_allowed = 1; @@ -1931,6 +1999,7 @@ jack_set_clock_source (clock_source); engine->control->clock_source = clock_source; + engine->get_microseconds = jack_get_microseconds_pointer(); VERBOSE (engine, "clock source = %s", jack_clock_source_name (clock_source)); @@ -2073,6 +2142,85 @@ return 0; } +static void +jack_slave_driver_remove(jack_engine_t *engine, jack_driver_t *sdriver) +{ + sdriver->detach (sdriver, engine); + engine->slave_drivers = jack_slist_remove(engine->slave_drivers, sdriver); + + jack_driver_unload(sdriver); +} +int +jack_drivers_start (jack_engine_t *engine) +{ + JSList *node; + JSList *failed_drivers = NULL; + /* first start the slave drivers */ + for (node=engine->slave_drivers; node; node=jack_slist_next(node)) + { + jack_driver_t *sdriver = node->data; + if (sdriver->start( sdriver )) + failed_drivers = jack_slist_append(failed_drivers, sdriver); + } + + // Clean up drivers which failed to start. + for (node=failed_drivers; node; node=jack_slist_next(node)) + { + jack_driver_t *sdriver = node->data; + jack_error( "slave driver %s failed to start, removing it", sdriver->internal_client->control->name ); + jack_slave_driver_remove(engine, sdriver); + } + + /* now the master driver is started */ + return engine->driver->start(engine->driver); +} + +static int +jack_drivers_stop (jack_engine_t *engine) +{ + JSList *node; + /* first stop the master driver */ + int retval = engine->driver->stop(engine->driver); + + /* now the slave drivers are stopped */ + for (node=engine->slave_drivers; node; node=jack_slist_next(node)) + { + jack_driver_t *sdriver = node->data; + sdriver->stop( sdriver ); + } + + return retval; +} + +static int +jack_drivers_read (jack_engine_t *engine, jack_nframes_t nframes) +{ + JSList *node; + /* first read the slave drivers */ + for (node=engine->slave_drivers; node; node=jack_slist_next(node)) + { + jack_driver_t *sdriver = node->data; + sdriver->read (sdriver, nframes); + } + + /* now the master driver is read */ + return engine->driver->read(engine->driver, nframes); +} + +static int +jack_drivers_write (jack_engine_t *engine, jack_nframes_t nframes) +{ + JSList *node; + /* first start the slave drivers */ + for (node=engine->slave_drivers; node; node=jack_slist_next(node)) + { + jack_driver_t *sdriver = node->data; + sdriver->write (sdriver, nframes); + } + + /* now the master driver is written */ + return engine->driver->write(engine->driver, nframes); +} static int jack_start_freewheeling (jack_engine_t* engine, jack_client_id_t client_id) { @@ -2092,7 +2240,7 @@ there are no more process() calls being handled. */ - if (engine->driver->stop (engine->driver)) { + if (jack_drivers_stop (engine)) { jack_error ("could not stop driver for freewheeling"); return -1; } @@ -2159,7 +2307,7 @@ /* restart the driver */ - if (engine->driver->start (engine->driver)) { + if (jack_drivers_start (engine)) { jack_error ("could not restart driver after freewheeling"); return -1; } @@ -2265,7 +2413,7 @@ return 0; } - if (engine->problems) { + if (engine->problems || (engine->timeout_count_threshold && (engine->timeout_count > (1 + engine->timeout_count_threshold*1000/engine->driver->period_usecs) ))) { VERBOSE (engine, "problem-driven null cycle problems=%d", engine->problems); jack_unlock_problems (engine); jack_unlock_graph (engine); @@ -2282,24 +2430,22 @@ if (!engine->freewheeling) { DEBUG("waiting for driver read\n"); - if (driver->read (driver, nframes)) { + if (jack_drivers_read (engine, nframes)) { goto unlock; } } DEBUG("run process\n"); - if (jack_engine_process (engine, nframes) == 0) { - if (!engine->freewheeling) { - if (driver->write (driver, nframes)) { - goto unlock; - } - } - - } else { + if (jack_engine_process (engine, nframes) != 0) { DEBUG ("engine process cycle failed"); jack_check_client_status (engine); + } + if (!engine->freewheeling) { + if (jack_drivers_write (engine, nframes)) { + goto unlock; + } } jack_engine_post_process (engine); @@ -2462,18 +2608,8 @@ pthread_join (engine->server_thread, NULL); #endif -#ifndef JACK_USE_MACH_THREADS - /* Cancel the watchdog thread and wait for it to terminate. - * - * The watchdog thread is not used on MacOSX since CoreAudio - * drivers already contain a similar mechanism. - */ - if (engine->control->real_time && engine->watchdog_thread) { - VERBOSE (engine, "stopping watchdog thread"); - pthread_cancel (engine->watchdog_thread); - pthread_join (engine->watchdog_thread, NULL); - } -#endif + jack_stop_watchdog (engine); + VERBOSE (engine, "last xrun delay: %.3f usecs", engine->control->xrun_delayed_usecs); @@ -2707,6 +2843,21 @@ return -3; } +static int +jack_do_has_session_cb (jack_engine_t *engine, jack_request_t *req) +{ + jack_client_internal_t *client; + int retval = -1; + + client = jack_client_by_name (engine, req->x.name); + if (client == NULL) + goto out; + + retval = client->control->session_cbset ? 1 : 0; +out: + return retval; +} + static void jack_do_session_reply (jack_engine_t *engine, jack_request_t *req ) { jack_client_id_t client_id = req->x.client_id; @@ -2834,6 +2985,10 @@ } break; + case LatencyCallback: + jack_client_handle_latency_callback (client->private_client, event, (client->control->type == ClientDriver)); + break; + default: /* internal clients don't need to know */ break; @@ -3290,6 +3445,8 @@ jack_deliver_event (engine, client, &event); } + jack_deliver_event (engine, engine->driver->internal_client, &event); + /* now issue playback latency callbacks in reverse graphorder */ event.x.n = 1; @@ -3298,6 +3455,8 @@ jack_deliver_event (engine, client, &event); } + jack_deliver_event (engine, engine->driver->internal_client, &event); + jack_slist_free (reverse_list); } @@ -3340,6 +3499,7 @@ jack_compute_all_port_total_latencies (engine); jack_rechain_graph (engine); jack_compute_new_latency (engine); + engine->timeout_count = 0; VERBOSE (engine, "-- jack_sort_graph"); } @@ -4002,7 +4162,7 @@ } } -static int +int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver) { if (engine->driver) { @@ -4025,6 +4185,19 @@ return 0; } +int +jack_add_slave_driver (jack_engine_t *engine, jack_driver_t *driver) +{ + if (driver) { + if (driver->attach (driver, engine)) { + return -1; + } + + engine->slave_drivers = jack_slist_append (engine->slave_drivers, driver); + } + + return 0; +} /* PORT RELATED FUNCTIONS */ @@ -4130,7 +4303,7 @@ } if ((port = jack_get_port_by_name(engine, req->x.port_info.name)) != NULL) { - jack_error ("duplicate port name in port registration request"); + jack_error ("duplicate port name (%s) in port registration request", req->x.port_info.name); jack_unlock_graph (engine); return -1; } diff -Nru jack-audio-connection-kit-0.118+svn4104/jackd/jackd.1.in jack-audio-connection-kit-0.121.0+svn4538/jackd/jackd.1.in --- jack-audio-connection-kit-0.118+svn4104/jackd/jackd.1.in 2010-11-15 15:08:38.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jackd/jackd.1.in 2011-05-29 00:47:31.000000000 +0000 @@ -105,6 +105,12 @@ This cancels the effect any specified timeout value, but JACK and its clients are still subject to the supervision of the watchdog thread or its equivalent. .TP +\fB\-C, \-\-timeout-thres \fItime\fR +.br +Stop processing clients if JACK cannot complete the process cycle in time (typically caused by CPU overloading or misbehaved clients). The optional \fItime\fR +argument specifies the number of miliseconds, during which consectutive process cycles must fail before JACK gives up (if the argument is not given, it defaults to 250). Processing will resume on the next change to the port +graph (i.e. a port is added, removed, connected or disconnected) +.TP \fB\-u, \-\-unlock\fR .br Unlock libraries GTK+, QT, FLTK, Wine. diff -Nru jack-audio-connection-kit-0.118+svn4104/jackd/jackd.c jack-audio-connection-kit-0.121.0+svn4538/jackd/jackd.c --- jack-audio-connection-kit-0.118+svn4104/jackd/jackd.c 2010-11-15 15:00:10.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jackd/jackd.c 2011-05-29 00:47:31.000000000 +0000 @@ -67,9 +67,13 @@ static int do_unlock = 0; static jack_nframes_t frame_time_offset = 0; static int nozombies = 0; +static int timeout_count_threshold = 0; extern int sanitycheck (int, int); +static jack_driver_desc_t * +jack_find_driver_descriptor (const char * name); + static void do_nothing_handler (int sig) { @@ -84,13 +88,14 @@ } static int -jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params) +jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params, JSList * slave_names) { int sig; int i; sigset_t allsignals; struct sigaction action; int waiting; + JSList * node; /* ensure that we are in our own process group so that kill (SIG, -pgrp) does the right thing. @@ -150,7 +155,7 @@ do_mlock, do_unlock, server_name, temporary, verbose, client_timeout, port_max, getpid(), frame_time_offset, - nozombies, drivers)) == 0) { + nozombies, timeout_count_threshold, drivers)) == 0) { jack_error ("cannot create engine"); return -1; } @@ -163,7 +168,16 @@ goto error; } - if (engine->driver->start (engine->driver) != 0) { + for (node=slave_names; node; node=jack_slist_next(node)) { + char *sl_name = node->data; + jack_driver_desc_t *sl_desc = jack_find_driver_descriptor(sl_name); + if (sl_desc) { + jack_engine_load_slave_driver(engine, sl_desc, NULL); + } + } + + + if (jack_drivers_start (engine) != 0) { jack_error ("cannot start driver"); goto error; } @@ -522,7 +536,7 @@ int do_sanity_checks = 1; int show_version = 0; - const char *options = "-d:P:uvshVrRZTFlt:mM:n:Np:c:"; + const char *options = "-d:P:uvshVrRZTFlt:mM:n:Np:c:X:C:"; struct option long_options[] = { /* keep ordered by single-letter option code */ @@ -547,7 +561,9 @@ { "unlock", 0, 0, 'u' }, { "version", 0, 0, 'V' }, { "verbose", 0, 0, 'v' }, + { "slave-driver", 1, 0, 'X' }, { "nozombies", 0, 0, 'Z' }, + { "timeout-thres", 2, 0, 'C' }, { 0, 0, 0, 0 } }; int opt = 0; @@ -556,6 +572,7 @@ char *driver_name = NULL; char **driver_args = NULL; JSList * driver_params; + JSList * slave_drivers = NULL; size_t midi_buffer_size = 0; int driver_nargs = 1; int i; @@ -584,6 +601,13 @@ } break; + case 'C': + if (optarg) + timeout_count_threshold = atoi (optarg); + else + timeout_count_threshold = 250; + break; + case 'd': seen_driver = 1; driver_name = optarg; @@ -659,6 +683,9 @@ show_version = 1; break; + case 'X': + slave_drivers = jack_slist_append(slave_drivers, optarg); + break; case 'Z': nozombies = 1; break; @@ -769,7 +796,7 @@ jack_cleanup_files (server_name); /* run the server engine until it terminates */ - jack_main (desc, driver_params); + jack_main (desc, driver_params, slave_drivers); /* clean up shared memory and files from this server instance */ if (verbose) diff -Nru jack-audio-connection-kit-0.118+svn4104/jackd/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/jackd/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/jackd/Makefile.am 2009-03-13 16:34:09.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/jackd/Makefile.am 2011-05-29 00:46:42.000000000 +0000 @@ -44,14 +44,14 @@ libjackserver_la_CFLAGS = $(AM_CFLAGS) -libjackserver_la_SOURCES = engine.c clientengine.c transengine.c \ +libjackserver_la_SOURCES = engine.c clientengine.c transengine.c controlapi.c \ ../libjack/systemtest.c ../libjack/sanitycheck.c \ ../libjack/client.c ../libjack/driver.c ../libjack/intclient.c \ ../libjack/messagebuffer.c ../libjack/pool.c ../libjack/port.c \ ../libjack/midiport.c ../libjack/ringbuffer.c ../libjack/shm.c \ ../libjack/thread.c ../libjack/time.c ../libjack/transclient.c \ ../libjack/unlock.c -libjackserver_la_LIBADD = simd.lo @OS_LDFLAGS@ +libjackserver_la_LIBADD = simd.lo @OS_LDFLAGS@ $(top_builddir)/libjack/libjack.la libjackserver_la_LDFLAGS = -export-dynamic -version-info @JACK_SO_VERSION@ simd.lo: $(srcdir)/../libjack/simd.c diff -Nru jack-audio-connection-kit-0.118+svn4104/libjack/client.c jack-audio-connection-kit-0.121.0+svn4538/libjack/client.c --- jack-audio-connection-kit-0.118+svn4104/libjack/client.c 2011-01-12 01:35:47.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/libjack/client.c 2011-08-31 14:46:40.000000000 +0000 @@ -90,11 +90,11 @@ { cpu_type = ((have_3dnow() << 8) | have_sse()); if (ARCH_X86_HAVE_3DNOW(cpu_type)) - jack_info("Enhanced3DNow! detected"); + jack_log("Enhanced3DNow! detected"); if (ARCH_X86_HAVE_SSE2(cpu_type)) - jack_info("SSE2 detected"); + jack_log("SSE2 detected"); if ((!ARCH_X86_HAVE_3DNOW(cpu_type)) && (!ARCH_X86_HAVE_SSE2(cpu_type))) - jack_info("No supported SIMD instruction sets detected"); + jack_log("No supported SIMD instruction sets detected"); jack_port_set_funcs(); } @@ -570,7 +570,7 @@ } int -jack_client_handle_latency_callback (jack_client_t *client, jack_event_t *event) +jack_client_handle_latency_callback (jack_client_t *client, jack_event_t *event, int is_driver) { jack_latency_callback_mode_t mode = (event->x.n==0) ? JackCaptureLatency : JackPlaybackLatency; JSList *node; @@ -589,6 +589,12 @@ jack_port_recalculate_latency (port, mode); } } + + /* for a driver invocation, this is enough. + * input and output ports do not depend on each other. + */ + if (is_driver) + return 0; if (! client->control->latency_cbset) { /* @@ -662,7 +668,8 @@ /* we have a latency callback setup by the client, * lets use it... */ - return client->latency_cb ( mode, client->latency_cb_arg); + client->latency_cb ( mode, client->latency_cb_arg); + return 0; } #if JACK_USE_MACH_THREADS @@ -1611,6 +1618,21 @@ return NULL; } +int +jack_client_has_session_callback (jack_client_t *client, const char *client_name) +{ + jack_request_t request; + int retval; + VALGRIND_MEMSET (&request, 0, sizeof (request)); + + request.type = SessionHasCallback; + strncpy (request.x.name, client_name, JACK_CLIENT_NAME_SIZE); + + retval = jack_client_deliver_request(client, &request); + + return retval; +} + void jack_start_freewheel (jack_client_t* client) { @@ -1751,7 +1773,7 @@ jack_client_fix_port_buffers (client); if (control->bufsize_cbset) { status = client->bufsize - (control->nframes, + (client->engine->buffer_size, client->bufsize_arg); } break; @@ -1759,7 +1781,7 @@ case SampleRateChange: if (control->srate_cbset) { status = client->srate - (control->nframes, + (client->engine->current_time.frame_rate, client->srate_arg); } break; @@ -1786,7 +1808,7 @@ status = jack_client_handle_session_callback (client, &event ); break; case LatencyCallback: - status = jack_client_handle_latency_callback (client, &event ); + status = jack_client_handle_latency_callback (client, &event, 0 ); break; } @@ -1804,11 +1826,105 @@ return 0; } + +static int +jack_wake_next_client (jack_client_t* client) +{ +#ifndef JACK_USE_MACH_THREADS + struct pollfd pfds[1]; + int pret = 0; + char c = 0; + + if (write (client->graph_next_fd, &c, sizeof (c)) + != sizeof (c)) { + DEBUG("cannot write byte to fd %d", client->graph_next_fd); + jack_error ("cannot continue execution of the " + "processing graph (%s)", + strerror(errno)); + return -1; + } + + DEBUG ("client sent message to next stage by %" PRIu64 "", + jack_get_microseconds()); + + DEBUG("reading cleanup byte from pipe %d\n", client->graph_wait_fd); + + /* "upstream client went away? readability is checked in + * jack_client_core_wait(), but that's almost a whole cycle + * before we get here. + */ + + if (client->graph_wait_fd >= 0) { + pfds[0].fd = client->graph_wait_fd; + pfds[0].events = POLLIN; + + /* 0 timeout, don't actually wait */ + pret = poll(pfds, 1, 0); + } + + if (pret > 0 && (pfds[0].revents & POLLIN)) { + if (read (client->graph_wait_fd, &c, sizeof (c)) + != sizeof (c)) { + jack_error ("cannot complete execution of the " + "processing graph (%s)", strerror(errno)); + return -1; + } + } else { + DEBUG("cleanup byte from pipe %d not available?\n", + client->graph_wait_fd); + } +#endif + return 0; +} + +#ifdef JACK_USE_MACH_THREADS + static int jack_client_core_wait (jack_client_t* client) { jack_client_control_t *control = client->control; + /* this is OS X - we're only waiting on events */ + + DEBUG ("client polling on %s", client->pollmax == 2 ? + "event_fd and graph_wait_fd..." : + "event_fd only"); + + while (1) { + if (poll (client->pollfd, client->pollmax, 1000) < 0) { + if (errno == EINTR) { + continue; + } + jack_error ("poll failed in client (%s)", + strerror (errno)); + return -1; + } + + pthread_testcancel(); + + if (jack_client_process_events (client)) { + DEBUG ("event processing failed\n"); + return 0; + } + } + + if (control->dead || client->pollfd[EVENT_POLL_INDEX].revents & ~POLLIN) { + DEBUG ("client appears dead or event pollfd has error status\n"); + return -1; + } + + return 0; +} + +#else /* !JACK_USE_MACH_THREADS */ + +static int +jack_client_core_wait (jack_client_t* client) +{ + jack_client_control_t *control = client->control; + + /* this is not OS X - we're waiting on events & process wakeups */ + DEBUG ("client polling on %s", client->pollmax == 2 ? "event_fd and graph_wait_fd..." : "event_fd only"); @@ -1825,8 +1941,6 @@ pthread_testcancel(); -#ifndef JACK_USE_MACH_THREADS - /* get an accurate timestamp on waking from poll for a * process() cycle. */ @@ -1872,20 +1986,17 @@ client->pollmax = 1; } } -#endif if (jack_client_process_events (client)) { DEBUG ("event processing failed\n"); return 0; } -#ifndef JACK_USE_MACH_THREADS if (client->graph_wait_fd >= 0 && (client->pollfd[WAIT_POLL_INDEX].revents & POLLIN)) { DEBUG ("time to run process()\n"); break; } -#endif } if (control->dead || client->pollfd[EVENT_POLL_INDEX].revents & ~POLLIN) { @@ -1896,70 +2007,134 @@ return 0; } -static int -jack_wake_next_client (jack_client_t* client) -{ - struct pollfd pfds[1]; - int pret = 0; - char c = 0; +#endif - if (write (client->graph_next_fd, &c, sizeof (c)) - != sizeof (c)) { - DEBUG("cannot write byte to fd %d", client->graph_next_fd); - jack_error ("cannot continue execution of the " - "processing graph (%s)", - strerror(errno)); - return -1; +static jack_nframes_t +jack_thread_first_wait (jack_client_t* client) +{ + if (jack_client_core_wait (client)) { + return 0; } - - DEBUG ("client sent message to next stage by %" PRIu64 "", - jack_get_microseconds()); - - DEBUG("reading cleanup byte from pipe %d\n", client->graph_wait_fd); + return client->engine->buffer_size; +} + +static void +jack_client_thread_aux (void *arg) +{ + jack_client_t *client = (jack_client_t *) arg; + jack_client_control_t *control = client->control; - /* "upstream client went away? readability is checked in - * jack_client_core_wait(), but that's almost a whole cycle - * before we get here. - */ + pthread_mutex_lock (&client_lock); + client->thread_ok = TRUE; + client->thread_id = pthread_self(); + pthread_cond_signal (&client_ready); + pthread_mutex_unlock (&client_lock); - if (client->graph_wait_fd >= 0) { - pfds[0].fd = client->graph_wait_fd; - pfds[0].events = POLLIN; + control->pid = getpid(); + control->pgrp = getpgrp(); - /* 0 timeout, don't actually wait */ - pret = poll(pfds, 1, 0); + DEBUG ("client thread is now running"); + + if (control->thread_init_cbset) { + DEBUG ("calling client thread init callback"); + client->thread_init (client->thread_init_arg); } - if (pret > 0 && (pfds[0].revents & POLLIN)) { - if (read (client->graph_wait_fd, &c, sizeof (c)) - != sizeof (c)) { - jack_error ("cannot complete execution of the " - "processing graph (%s)", strerror(errno)); - return -1; + /* wait for first wakeup from server */ + + if (jack_thread_first_wait (client) == client->engine->buffer_size) { + + /* now run till we're done */ + + if (control->process_cbset) { + + /* run process callback, then wait... ad-infinitum */ + + while (1) { + DEBUG("client calls process()"); + int status = (client->process (client->engine->buffer_size, + client->process_arg) == + client->engine->buffer_size); + control->state = Finished; + DEBUG("client leaves process(), re-enters wait"); + if (!jack_thread_wait (client, status)) { + break; + } + DEBUG("client done with wait"); + } + + } else { + /* no process handling but still need to process events */ + while (jack_thread_wait (client, 0) == client->engine->buffer_size) + ; } - } else { - DEBUG("cleanup byte from pipe %d not available?\n", - client->graph_wait_fd); } - - return 0; + + jack_client_thread_suicide (client); } -static jack_nframes_t -jack_thread_first_wait (jack_client_t* client) +static void +jack_run_client_provided_process_thread (jack_client_t* client) { - if (jack_client_core_wait (client)) { - return 0; + jack_client_control_t *control = client->control; + + pthread_mutex_lock (&client_lock); + client->thread_ok = TRUE; + client->thread_id = pthread_self(); + pthread_cond_signal (&client_ready); + pthread_mutex_unlock (&client_lock); + + control->pid = getpid(); + control->pgrp = getpgrp(); + + client->thread_cb(client->thread_cb_arg); + jack_client_thread_suicide(client); +} + +#ifdef JACK_USE_MACH_THREADS + +static void* +jack_client_thread (void *arg) +{ + /* On OS X, the secondary client thread that we create will + always just handle server events, whether or not the + client has called jack_set_process_thread(). + */ + jack_client_thread_aux(arg); + /*NOTREACHED*/ + return (void *) 0; +} + +#else /* !JACK_USE_MACH_THREADS */ + +static void* +jack_client_thread (void *arg) +{ + jack_client_t *client = (jack_client_t *) arg; + + /* On non-OSX systems, the client thread should run the supplied + callback if jack_set_process_thread() was called, otherwise + it will just wait in a loop for events and/or process wakeups. + */ + + if (client->control->thread_cb_cbset) { + jack_run_client_provided_process_thread (client); + } else { + jack_client_thread_aux (arg); } - return client->control->nframes; + + /*NOTREACHED*/ + return (void *) 0; } - + +#endif + jack_nframes_t jack_thread_wait (jack_client_t* client, int status) { client->control->last_status = status; - /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */ + /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */ /* housekeeping/cleanup after data processing */ @@ -1986,13 +2161,13 @@ return 0; } - /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */ - + /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */ + if (jack_client_core_wait (client)) { return 0; } - - /* SECTION THREE: START NEXT DATA PROCESSING TIME */ + + /* SECTION THREE: START NEXT DATA PROCESSING TIME */ /* Time to do data processing */ @@ -2004,40 +2179,57 @@ if (client->control->sync_cb_cbset) jack_call_sync_client (client); - return client->control->nframes; + return client->engine->buffer_size; } jack_nframes_t jack_cycle_wait (jack_client_t* client) { - /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */ + jack_client_control_t *control = client->control; + /* SECTION TWO: WAIT FOR NEXT DATA PROCESSING TIME */ + +#ifdef JACK_USE_MACH_THREADS + /* on OS X systems, this thread is running a callback provided + by the client that has called this function in order to wait + for the next process callback. This is how we do that ... + */ + jack_client_suspend (client); +#else + /* on non-OSX systems, this thread is running a callback provided + by the client that has called this function in order to wait + for the next process() callback or the next event from the + server. + */ if (jack_client_core_wait (client)) { return 0; } - - /* SECTION THREE: START NEXT DATA PROCESSING TIME */ - +#endif + + /* SECTION THREE: START NEXT DATA PROCESSING TIME */ + /* Time to do data processing */ - + + control->awake_at = jack_get_microseconds(); client->control->state = Running; /* begin preemption checking */ CHECK_PREEMPTION (client->engine, TRUE); - if (client->control->sync_cb_cbset) + if (client->control->sync_cb_cbset) { jack_call_sync_client (client); - - return client->control->nframes; + } + + return client->engine->buffer_size; } -void jack_cycle_signal(jack_client_t* client, int status) +void jack_cycle_signal (jack_client_t* client, int status) { client->control->last_status = status; - /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */ - + /* SECTION ONE: HOUSEKEEPING/CLEANUP FROM LAST DATA PROCESSING */ + /* housekeeping/cleanup after data processing */ - + if (status == 0 && client->control->timebase_cb_cbset) { jack_call_timebase_master (client); } @@ -2046,6 +2238,7 @@ CHECK_PREEMPTION (client->engine, FALSE); client->control->finished_at = jack_get_microseconds(); + client->control->state = Finished; /* wake the next client in the chain (could be the server), and check if we were killed during the process @@ -2057,132 +2250,40 @@ jack_client_thread_suicide (client); /*NOTREACHED*/ } - + if (status || client->control->dead || !client->engine->engine_ok) { jack_client_thread_suicide (client); /*NOTREACHED*/ } } -static void -jack_client_thread_aux (void *arg) -{ - jack_client_t *client = (jack_client_t *) arg; - jack_client_control_t *control = client->control; - - pthread_mutex_lock (&client_lock); - client->thread_ok = TRUE; - client->thread_id = pthread_self(); - pthread_cond_signal (&client_ready); - pthread_mutex_unlock (&client_lock); - - control->pid = getpid(); - control->pgrp = getpgrp(); - - DEBUG ("client thread is now running"); - - if (control->thread_init_cbset) { - DEBUG ("calling client thread init callback"); - client->thread_init (client->thread_init_arg); - } - - /* wait for first wakeup from server */ - - if (jack_thread_first_wait (client) == control->nframes) { - - /* now run till we're done */ - - if (control->process_cbset) { - - /* run process callback, then wait... ad-infinitum */ - - while (1) { - DEBUG("client calls process()"); - int status = (client->process (control->nframes, - client->process_arg) == - control->nframes); - control->state = Finished; - DEBUG("client leaves process(), re-enters wait"); - if (!jack_thread_wait (client, status)) { - break; - } - DEBUG("client done with wait"); - } - - } else { - /* no process handling but still need to process events */ - while (jack_thread_wait (client, 0) == control->nframes) - ; - } - } - - jack_client_thread_suicide (client); -} - -static void* -jack_client_thread (void *arg) -{ - jack_client_t *client = (jack_client_t *) arg; - jack_client_control_t *control = client->control; - - if (client->control->thread_cb_cbset) { - - pthread_mutex_lock (&client_lock); - client->thread_ok = TRUE; - client->thread_id = pthread_self(); - pthread_cond_signal (&client_ready); - pthread_mutex_unlock (&client_lock); - - control->pid = getpid(); - control->pgrp = getpgrp(); - - client->thread_cb(client->thread_cb_arg); - jack_client_thread_suicide(client); - } else { - jack_client_thread_aux(arg); - } - - /*NOTREACHED*/ - return (void *) 0; -} - #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 */ -static void * -jack_client_process_thread (void *arg) +static void +jack_osx_process_thread (jack_client_t* client) { - jack_client_t *client = (jack_client_t *) arg; - jack_client_control_t *control = client->control; + jack_client_control_t *control = client->control; int err = 0; - if (client->control->thread_init_cbset) { - /* this means that the init callback will be called twice -taybin*/ - DEBUG ("calling client thread init callback"); - client->thread_init (client->thread_init_arg); - } - - client->control->pid = getpid(); - DEBUG ("client process thread is now running"); - - client->rt_thread_ok = TRUE; - while (err == 0) { if (jack_client_suspend(client) < 0) { - jack_error ("jack_client_process_thread :resume error"); - goto zombie; + jack_error ("jack_client_process_thread :resume error"); + goto zombie; } control->awake_at = jack_get_microseconds(); DEBUG ("client resumed"); - + control->state = Running; - if (control->sync_cb_cbset) + if (control->sync_cb_cbset) { jack_call_sync_client (client); + } if (control->process_cbset) { if (client->process (control->nframes, @@ -2193,9 +2294,10 @@ control->state = Finished; } - if (control->timebase_cb_cbset) + if (control->timebase_cb_cbset) { jack_call_timebase_master (client); - + } + control->finished_at = jack_get_microseconds(); DEBUG ("client finished processing at %Lu (elapsed = %f usecs)", @@ -2206,16 +2308,15 @@ * (or whatever) */ if (client->control->dead) { - jack_error ("jack_client_process_thread: " - "client->control->dead"); - goto zombie; + jack_error ("jack_client_process_thread: " + "client->control->dead"); + goto zombie; } - + DEBUG("process cycle fully complete\n"); - } - - return (void *) ((intptr_t)err); + + return; zombie: @@ -2235,11 +2336,36 @@ * zombified without shutdown handler */ jack_client_close_aux (client); } +} + +static void * +jack_client_process_thread (void *arg) +{ + jack_client_t *client = (jack_client_t *) arg; + jack_client_control_t *control = client->control; + + if (client->control->thread_init_cbset) { + /* this means that the init callback will be called twice -taybin*/ + DEBUG ("calling client thread init callback"); + client->thread_init (client->thread_init_arg); + } + + client->control->pid = getpid(); + DEBUG ("client process thread is now running"); + + client->rt_thread_ok = TRUE; + + if (client->control->thread_cb_cbset) { + jack_run_client_provided_process_thread (client); + } else { + jack_osx_process_thread (client); + } pthread_exit (0); /*NOTREACHED*/ return 0; } + #endif /* JACK_USE_MACH_THREADS */ static int @@ -2525,6 +2651,10 @@ VALGRIND_MEMSET (&req, 0, sizeof (req)); + if (nframes < 1 || nframes > 16384) { + return ERANGE; + } + req.type = SetBufferSize; req.x.nframes = nframes; @@ -2892,7 +3022,7 @@ psp = engine->ports; match_cnt = 0; - if ((matching_ports = (const char **) malloc (sizeof (char *) * engine->port_max)) == NULL) { + if ((matching_ports = (const char **) malloc (sizeof (char *) * (engine->port_max + 1))) == NULL) { return NULL; } @@ -2935,12 +3065,12 @@ regfree (&type_regex); } - matching_ports[match_cnt] = 0; - if (match_cnt == 0) { free (matching_ports); matching_ports = 0; - } + } else { + matching_ports[match_cnt] = 0; + } return matching_ports; } diff -Nru jack-audio-connection-kit-0.118+svn4104/libjack/port.c jack-audio-connection-kit-0.121.0+svn4538/libjack/port.c --- jack-audio-connection-kit-0.118+svn4104/libjack/port.c 2011-01-12 01:35:47.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/libjack/port.c 2011-06-19 22:10:03.000000000 +0000 @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -216,6 +217,22 @@ return port; } +size_t +jack_port_type_get_buffer_size (jack_client_t *client, const char *port_type) +{ + int i; + + for (i=0; iengine->n_port_types; i++) { + if (!strcmp(port_type, client->engine->port_types[i].type_name)) + break; + } + + if (i==client->engine->n_port_types) + return 0; + + return jack_port_type_buffer_size (&(client->engine->port_types[i]), client->engine->buffer_size); +} + jack_port_t * jack_port_register (jack_client_t *client, const char *port_name, @@ -548,6 +565,10 @@ if (port->tied) { return jack_port_get_buffer (port->tied, nframes); } + + if (port->client_segment_base == NULL || *port->client_segment_base == MAP_FAILED) { + return NULL; + } return jack_output_port_buffer (port); } @@ -559,6 +580,10 @@ */ if ((node = port->connections) == NULL) { + if (port->client_segment_base == NULL || *port->client_segment_base == MAP_FAILED) { + return NULL; + } + /* no connections; return a zero-filled buffer */ return (void *) (*(port->client_segment_base) + port->type_info->zero_buffer_offset); } @@ -809,10 +834,24 @@ void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) { - if (mode == JackCaptureLatency) + if (mode == JackCaptureLatency) { port->shared->capture_latency = *range; - else + + /* hack to set port->shared->latency up for + * backend ports + */ + if ((port->shared->flags & JackPortIsOutput) && (port->shared->flags & JackPortIsPhysical)) + port->shared->latency = (range->min + range->max) / 2; + } else { port->shared->playback_latency = *range; + + /* hack to set port->shared->latency up for + * backend ports + */ + if ((port->shared->flags & JackPortIsInput) && (port->shared->flags & JackPortIsPhysical)) + port->shared->latency = (range->min + range->max) / 2; + + } } void diff -Nru jack-audio-connection-kit-0.118+svn4104/libjack/thread.c jack-audio-connection-kit-0.121.0+svn4538/libjack/thread.c --- jack-audio-connection-kit-0.118+svn4104/libjack/thread.c 2010-09-26 15:54:09.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/libjack/thread.c 2011-03-15 13:10:34.000000000 +0000 @@ -99,6 +99,21 @@ #endif /* USE_CAPABILITIES */ } +static void +jack_thread_touch_stack() +{ + char buf[JACK_THREAD_STACK_TOUCH]; + int i; + volatile char *buf_ptr = buf; + + for (i = 0; i < JACK_THREAD_STACK_TOUCH; i++) { + buf_ptr[i] = (char) (i & 0xff); + } +} + +typedef void (* stack_touch_t)(); +static volatile stack_touch_t ptr_jack_thread_touch_stack = jack_thread_touch_stack; + static void* jack_thread_proxy (void* varg) { @@ -107,14 +122,8 @@ void* warg; jack_client_t* client = arg->client; - char buf[JACK_THREAD_STACK_TOUCH]; - int i; - - for (i = 0; i < JACK_THREAD_STACK_TOUCH; i++) { - buf[i] = (char) (i & 0xff); - } - if (arg->realtime) { + ptr_jack_thread_touch_stack(); maybe_get_capabilities (client); jack_acquire_real_time_scheduling (pthread_self(), arg->priority); } diff -Nru jack-audio-connection-kit-0.118+svn4104/libjack/transclient.c jack-audio-connection-kit-0.121.0+svn4538/libjack/transclient.c --- jack-audio-connection-kit-0.118+svn4104/libjack/transclient.c 2010-09-26 15:54:09.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/libjack/transclient.c 2011-06-19 22:10:03.000000000 +0000 @@ -170,7 +170,7 @@ new_pos) { client->timebase_cb (ectl->transport_state, - control->nframes, + ectl->buffer_size, &ectl->pending_time, new_pos, client->timebase_arg); diff -Nru jack-audio-connection-kit-0.118+svn4104/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/Makefile.am 2009-11-12 11:50:55.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/Makefile.am 2011-06-29 01:50:30.000000000 +0000 @@ -13,8 +13,8 @@ @false endif -SUBDIRS = jack libjack jackd drivers example-clients tools config $(DOC_DIR) man -DIST_SUBDIRS = config jack libjack jackd drivers example-clients tools doc man +SUBDIRS = jack libjack jackd drivers example-clients tools config $(DOC_DIR) man python +DIST_SUBDIRS = config jack libjack jackd drivers example-clients tools doc man python pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = jack.pc diff -Nru jack-audio-connection-kit-0.118+svn4104/man/jack_iodelay.0 jack-audio-connection-kit-0.121.0+svn4538/man/jack_iodelay.0 --- jack-audio-connection-kit-0.118+svn4104/man/jack_iodelay.0 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/man/jack_iodelay.0 2011-03-01 18:00:07.000000000 +0000 @@ -0,0 +1,53 @@ +.TH JACK_IODELAY "1" "!DATE!" "!VERSION!" +.SH NAME +jack_iodelay \- JACK toolkit client to measure roundtrip latency +.SH SYNOPSIS +.B jack_iodelay +.SH DESCRIPTION +.B jack_iodelay +will create one input and one output port, and then +measures the latency (signal delay) between them. For this to work, +the output port must be connected to its input port. The measurement +is accurate to a resolution of greater than 1 sample. +.PP +The expected use is to connect jack_iodelay's output port to a +hardware playback port, then use a physical loopback cable from the +corresponding hardware output connector to an input connector, and to +connect that corresponding hardware capture port to jack_iodelay's +input port. This creates a roundtrip that goes through any +analog-to-digital or digital-converters that are present in the audio +hardware. +.PP +Although the hardware loopback latency is the expected use, it is also +possible to use jack_iodelay to measure the latency along any fully +connected signal path, such as those involving other JACK clients. +.PP +Once jack_iodelay completes its measurement it will print the total +latency it has detected. This will include the JACK period length in +addition to any other latency in the signal path. It will continue to +print the value every 0.5 seconds or so so that if you wish you can +vary aspects of the signal path to see their effect on the measured +latency. +.PP +If no incoming signal is detected from the input port, jack_iodelay +will print +.PP +\fT Signal below threshold... .\fR +.PP +every second until this changes (e.g. until you establish the correct connections). +.PP +To use the value measured by jack_iodelay with the -I and -O arguments +of a JACK backend (also called Input Latency and Output Latency in the +setup dialog of qjackctl), you must subtract the JACK period size from +the result. Then, if you believe that the latency is equally +distributed between the input and output parts of your audio hardware +(extremely likely), divide the result by two and use that for input +and/or output latency value. Doing this measurement will enable JACK +clients that use the JACK latency API to accurately position/delay +audio to keep signals synchronized even when there are inherent delays +in the end-to-end signal pathways. +.SH AUTHOR +Originally written in C++ by Fons Adriensen, ported to C by Torben Hohn. + + + diff -Nru jack-audio-connection-kit-0.118+svn4104/man/jack_load_test.0 jack-audio-connection-kit-0.121.0+svn4538/man/jack_load_test.0 --- jack-audio-connection-kit-0.118+svn4104/man/jack_load_test.0 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/man/jack_load_test.0 2011-05-29 00:47:26.000000000 +0000 @@ -0,0 +1,11 @@ +.TH JACK_LOAD_TEST "1" "!DATE!" "!VERSION!" +.SH NAME +jack_load_test \- JACK toolkit client which occupies the cpu for some time in process. +.SH SYNOPSIS +.B jack_load_test -t \fItime\fR +.SH DESCRIPTION +.B jack_load_test +jack_load_test is a client without ports, which just occupies the cpu for \fItime\fR +miliseconds. It is quite useful to test jackd behaviour under load. + + diff -Nru jack-audio-connection-kit-0.118+svn4104/python/jackctl.py jack-audio-connection-kit-0.121.0+svn4538/python/jackctl.py --- jack-audio-connection-kit-0.118+svn4104/python/jackctl.py 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/python/jackctl.py 2011-06-27 20:25:06.000000000 +0000 @@ -0,0 +1,242 @@ + +from ctypes import * + +libj = cdll.LoadLibrary( "libjack.so" ) +libjs = cdll.LoadLibrary( "libjackserver.so" ) + + +class jackctl_parameter_value( Union ): + _fields_ = [ ( "ui", c_uint ), + ( "i", c_int ), + ( "c", c_char ), + ( "ss", c_char * 128 ), + ( "b", c_bool ) ] + + def get_str( self ): + return buffer(self.ss) + + def set_str( self, sss ): + self.ss = sss + + str = property( get_str, set_str ) + +class jackctl_server_t( Structure ): + pass + +class jackctl_driver_t( Structure ): + pass + +class jackctl_internal_t( Structure ): + pass + +class jackctl_parameter_t( Structure ): + pass + +class JSList( Structure ): + pass + +JSList._fields_ = [ ("data", c_void_p), ("next", POINTER(JSList)) ] + +class JSIter: + def __init__(self, ptr, typ=c_void_p): + self.ptr = ptr + self.typ = typ + + def __iter__(self): + return self + + def next( self ): + if not self.ptr: + raise StopIteration + + retval = self.ptr.contents.data + self.ptr = self.ptr.contents.next + + return cast( retval, self.typ ) + +DeviceAcquireFunc = CFUNCTYPE( c_int, c_char_p ) +DeviceReleaseFunc = CFUNCTYPE( None, c_char_p ) + +jackctl_server_start = libjs.jackctl_server_start +jackctl_server_start.argtypes = [ POINTER(jackctl_server_t), POINTER(jackctl_driver_t) ] +jackctl_server_start.restype = c_bool + +jackctl_server_stop = libjs.jackctl_server_stop +jackctl_server_stop.argtypes = [ POINTER(jackctl_server_t) ] +jackctl_server_stop.restype = c_bool + +jackctl_server_create = libjs.jackctl_server_create +jackctl_server_create.argtypes = [ DeviceAcquireFunc, DeviceReleaseFunc ] +jackctl_server_create.restype = POINTER(jackctl_server_t) + +jackctl_server_get_drivers_list = libjs.jackctl_server_get_drivers_list +jackctl_server_get_drivers_list.argtypes = [ POINTER(jackctl_server_t) ] +jackctl_server_get_drivers_list.restype = POINTER(JSList) + +jackctl_server_get_parameters = libjs.jackctl_server_get_parameters +jackctl_server_get_parameters.argtypes = [ POINTER(jackctl_server_t) ] +jackctl_server_get_parameters.restype = POINTER(JSList) + +jackctl_driver_get_parameters = libjs.jackctl_driver_get_parameters +jackctl_driver_get_parameters.argtypes = [ POINTER(jackctl_driver_t) ] +jackctl_driver_get_parameters.restype = POINTER(JSList) + +jackctl_driver_get_name = libjs.jackctl_driver_get_name +jackctl_driver_get_name.argtypes = [ POINTER(jackctl_driver_t) ] +jackctl_driver_get_name.restype = c_char_p + +jackctl_parameter_get_name = libjs.jackctl_parameter_get_name +jackctl_parameter_get_name.argtypes = [ POINTER(jackctl_parameter_t) ] +jackctl_parameter_get_name.restype = c_char_p + +jackctl_parameter_get_short_description = libjs.jackctl_parameter_get_short_description +jackctl_parameter_get_short_description.argtypes = [ POINTER(jackctl_parameter_t) ] +jackctl_parameter_get_short_description.restype = c_char_p + +jackctl_parameter_get_type = libjs.jackctl_parameter_get_type +jackctl_parameter_get_type.argtypes = [ POINTER(jackctl_parameter_t) ] +jackctl_parameter_get_type.restype = c_uint + +jackctl_parameter_set_value = libjs.jackctl_parameter_set_value +jackctl_parameter_set_value.argtypes = [ POINTER(jackctl_parameter_t), POINTER(jackctl_parameter_value) ] +jackctl_parameter_set_value.restype = c_bool + +jackctl_parameter_get_value = libjs.jackctl_parameter_get_value +jackctl_parameter_get_value.argtypes = [ POINTER(jackctl_parameter_t) ] +jackctl_parameter_get_value.restype = jackctl_parameter_value + +jackctl_parameter_get_id = libjs.jackctl_parameter_get_id +jackctl_parameter_get_id.argtypes = [ POINTER(jackctl_parameter_t) ] +jackctl_parameter_get_id.restype = c_char + +jackctl_server_switch_master = libjs.jackctl_server_switch_master +jackctl_server_switch_master.argtypes = [ POINTER(jackctl_server_t), POINTER(jackctl_driver_t) ] +jackctl_server_switch_master.restype = c_bool + + +class Parameter(object): + def __init__( self, param_ptr ): + self.param_ptr = param_ptr + self.param_type = jackctl_parameter_get_type( self.param_ptr ) + + def get_short_desc( self ): + return jackctl_parameter_get_short_description( self.param_ptr ) + + short_desc = property( get_short_desc ) + + def get_name( self ): + return jackctl_parameter_get_name( self.param_ptr ) + + name = property( get_name ) + + def get_id( self ): + return jackctl_parameter_get_id( self.param_ptr ) + + id = property( get_id ) + + def set_value( self, val ): + param_v = jackctl_parameter_value() + if self.param_type == 1: + # int + param_v.i = int(val) + elif self.param_type == 2: + # uint + param_v.ui = int(val) + elif self.param_type == 3: + # char + assert( (type(val) == str) and len(val)==1 ) + param_v.c = val + elif self.param_type == 4: + # string + assert( type(val) == str ) + param_v.ss = val + elif self.param_type == 5: + # bool + assert( type(val) == bool ) + param_v.b = val + + jackctl_parameter_set_value( self.param_ptr, pointer(param_v) ) + + def get_value( self ): + param_v = jackctl_parameter_get_value( self.param_ptr ) + + if self.param_type == 1: + # int + return param_v.i + elif self.param_type == 2: + # uint + return param_v.ui + elif self.param_type == 3: + # char + return param_v.c + elif self.param_type == 4: + # string + return param_v.ss + elif self.param_type == 5: + # bool + return param_v.b + + value = property( get_value, set_value ) + +class Driver(object): + def __init__( self, drv_ptr ): + self.drv_ptr = drv_ptr + + params_jslist = jackctl_driver_get_parameters( self.drv_ptr ) + + self.params = {} + for i in JSIter( params_jslist, POINTER(jackctl_parameter_t) ): + self.params[ jackctl_parameter_get_name( i ) ] = Parameter(i) + + def get_name( self ): + return jackctl_driver_get_name( self.drv_ptr ) + + name = property( get_name ) + + +class Server(object): + def __init__( self ): + self.dacqd = DeviceAcquireFunc(self.acquire_card) + self.reled = DeviceReleaseFunc(self.release_card) + self.srv_ptr = jackctl_server_create( self.dacqd, self.reled ) + + self.acquire_card_cb = None + self.release_card_cb = None + + driver_jslist = jackctl_server_get_drivers_list( self.srv_ptr ) + + self.drivers = {} + for i in JSIter( driver_jslist, POINTER(jackctl_driver_t) ): + self.drivers[ jackctl_driver_get_name( i ) ] = Driver(i) + + params_jslist = jackctl_server_get_parameters( self.srv_ptr ) + + self.params = {} + for i in JSIter( params_jslist, POINTER(jackctl_parameter_t) ): + self.params[ jackctl_parameter_get_name( i ) ] = Parameter(i) + + def __del__( self ): + pass + + def start( self, driver ): + return jackctl_server_start( self.srv_ptr, driver.drv_ptr ) + + def switch_master( self, driver ): + return jackctl_server_switch_master( self.srv_ptr, driver.drv_ptr ) + + def stop( self ): + return jackctl_server_stop( self.srv_ptr ) + + + def acquire_card( self, cardname ): + if self.acquire_card_cb: + return self.acquire_card_cb(cardname) + else: + return True + + def release_card( self, cardname ): + if self.release_card_cb: + self.release_card_cb(cardname) + + + diff -Nru jack-audio-connection-kit-0.118+svn4104/python/jackd.py jack-audio-connection-kit-0.121.0+svn4538/python/jackd.py --- jack-audio-connection-kit-0.118+svn4104/python/jackd.py 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/python/jackd.py 2011-06-27 20:25:06.000000000 +0000 @@ -0,0 +1,137 @@ +#!/usr/bin/env python + +import sys +from pyjackd.mygetopt import my_getopt +from pyjackd import jackctl +import readline +import time + +import reserve_audio + +argv = sys.argv[1:] + + + +def server_parse_ags( srv, argv ): + shortopts = "" + longopts = [] + shortmap = {} + driver = None + + for param in srv.params: + p = srv.params[param] + shortopts += p.id + if p.param_type != 5: + shortopts += ":" + longopts.append (p.name + "=") + else: + longopts.append (p.name) + + shortmap[p.id] = p + + while not driver: + opts, argv = my_getopt( argv, shortopts+"d:" ) + if not opts: + break + for opt,optarg in opts: + if opt == "-d": + driver = srv.drivers[optarg] + elif opt.startswith("--"): + pass + elif opt.startswith("-"): + p = shortmap[opt[1]] + if p.param_type == 5: + p.value = True + else: + p.value = optarg + + return driver, argv + +def driver_parse_args( drv, argv ): + shortopts = "" + longopts = [] + shortmap = {} + + for param in drv.params: + p = drv.params[param] + shortopts += p.id + if p.param_type != 5: + shortopts += ":" + longopts.append (p.name + "=") + else: + longopts.append (p.name) + + shortmap[p.id] = p + + while True: + opts, argv = my_getopt( argv, shortopts+"d:" ) + if not opts: + break + for opt,optarg in opts: + if opt.startswith("--"): + pass + elif opt.startswith("-"): + p = shortmap[opt[1]] + if p.param_type == 5: + p.value = True + else: + p.value = optarg + +def acquire_dev(cardname): + reserve_audio.reserve_dev(cardname,20,None) + time.sleep(0.1) + return True + +def release_dev(cardname): + reserve_audio.rr.unreserve() + reserve_audio.rr = None + +srv = jackctl.Server() +srv.acquire_card_cb = acquire_dev +srv.release_card_cb = release_dev + +drv, argv = server_parse_ags( srv, argv ) +driver_parse_args( drv, argv ) + +#for p in srv.params.values(): +# print p.name, "-> ", p.value +# +#print "----------------" +#print "driver ", drv.name +# +#for p in drv.params.values(): +# print p.name, "-> ", p.value + +started = srv.start( drv ) + +if not started: + print "failed to start with driver " + drv.name + print "trying to start with dummy driver, switch to the right master yourself" + + started = srv.start( srv.drivers["dummy"] ) + + if not started: + sys.exit(20) + +quit = False +while not quit: + try: + cmd = raw_input("jack> ") + except EOFError: + break + + cmdv = cmd.split() + + if len(cmdv) == 0: + continue + + if cmdv[0] == "quit": + quit = True + elif cmdv[0] == "switch": + if len(cmdv) > 1: + drv = srv.drivers[cmdv[1]] + driver_parse_args( drv, cmdv[2:] ) + srv.switch_master( drv ) + +print "\nshutting down" +srv.stop() diff -Nru jack-audio-connection-kit-0.118+svn4104/python/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/python/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/python/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/python/Makefile.am 2011-06-29 01:50:30.000000000 +0000 @@ -0,0 +1,3 @@ +noinst_SCRIPTS = jackd.py +EXTRA_DIST = jackd.py jackctl.pyc mygetopt.pyc reserve_audio.py + diff -Nru jack-audio-connection-kit-0.118+svn4104/python/mygetopt.py jack-audio-connection-kit-0.121.0+svn4538/python/mygetopt.py --- jack-audio-connection-kit-0.118+svn4104/python/mygetopt.py 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/python/mygetopt.py 2011-05-29 00:47:39.000000000 +0000 @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +import getopt + +def my_getopt(args, shortopts, longopts = []): + """getopt(args, options[, long_options]) -> opts, args + + Parses command line options and parameter list. args is the + argument list to be parsed, without the leading reference to the + running program. Typically, this means "sys.argv[1:]". shortopts + is the string of option letters that the script wants to + recognize, with options that require an argument followed by a + colon (i.e., the same format that Unix getopt() uses). If + specified, longopts is a list of strings with the names of the + long options which should be supported. The leading '--' + characters should not be included in the option name. Options + which require an argument should be followed by an equal sign + ('='). + + The return value consists of two elements: the first is a list of + (option, value) pairs; the second is the list of program arguments + left after the option list was stripped (this is a trailing slice + of the first argument). Each option-and-value pair returned has + the option as its first element, prefixed with a hyphen (e.g., + '-x'), and the option argument as its second element, or an empty + string if the option has no argument. The options occur in the + list in the same order in which they were found, thus allowing + multiple occurrences. Long and short options may be mixed. + + """ + + opts = [] + if type(longopts) == type(""): + longopts = [longopts] + else: + longopts = list(longopts) + if args and args[0].startswith('-') and args[0] != '-': + if args[0] == '--': + args = args[1:] + if args[0].startswith('--'): + opts, args = getopt.do_longs(opts, args[0][2:], longopts, args[1:]) + else: + opts, args = getopt.do_shorts(opts, args[0][1:], shortopts, args[1:]) + + return opts, args + else: + return None, args + diff -Nru jack-audio-connection-kit-0.118+svn4104/python/reserve_audio.py jack-audio-connection-kit-0.121.0+svn4538/python/reserve_audio.py --- jack-audio-connection-kit-0.118+svn4104/python/reserve_audio.py 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/python/reserve_audio.py 2011-06-27 20:25:06.000000000 +0000 @@ -0,0 +1,68 @@ + +import dbus.service +import gobject +import dbus.mainloop.glib + +rr = None + +class reservation_t( dbus.service.Object ): + def __init__( self, device_name, prio, override_cb=None ): + + self.dev_name = device_name + self.prio = prio + self.override_cb = override_cb + + self.bus = dbus.SessionBus() + + dbus.service.Object.__init__( self, None, + "/org/freedesktop/ReserveDevice1/" + self.dev_name, + dbus.service.BusName( "org.freedesktop.ReserveDevice1." + self.dev_name, bus=self.bus, allow_replacement=True, replace_existing=True, do_not_queue=True ) ) + + @dbus.service.method( dbus_interface="org.freedesktop.ReserveDevice1", in_signature="i", out_signature="b" ) + def RequestRelease( self, prio ): + if prio < self.prio: + return False + + if self.override_cb: + if self.override_cb( self.device_name ): + self.connection.release_name( 'org.freedesktop.ReserveDevice1.' + self.dev_name ) + return True + + return False + + + def unreserve (self): + self.connection.release_name( 'org.freedesktop.ReserveDevice1.' + self.dev_name ) + rr.remove_from_connection() + + +def reserve_dev( dev_name, prio, override_cb ): + global rr + try: + session_bus = dbus.SessionBus() + except Exception: + return + + try: + r_proxy = session_bus.get_object( "org.freedesktop.ReserveDevice1." + dev_name, "/org/freedesktop/ReserveDevice1/" + dev_name ) + r_iface = dbus.Interface( r_proxy, "org.freedesktop.ReserveDevice1" ) + except Exception: + print "no other reservation exists. taking the name" + rr = reservation_t( dev_name, prio, override_cb ) + return + + if not r_iface.RequestRelease( prio ): + raise Exception + + rr = reservation_t( dev_name, prio, override_cb ) + + + +dbus.mainloop.glib.threads_init() +dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + +def run_main(): + loop = gobject.MainLoop() + loop.run() + + diff -Nru jack-audio-connection-kit-0.118+svn4104/README jack-audio-connection-kit-0.121.0+svn4538/README --- jack-audio-connection-kit-0.118+svn4104/README 2003-05-16 02:18:51.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/README 2011-02-09 13:03:17.000000000 +0000 @@ -1,38 +1,3 @@ Welcome to JACK, the Jack Audio Connection Kit. -Please see the website (http://jackit.sf.net/) for more information. - -NOTE: If you are using reiserfs or ext3fs or anything except ext2fs -for the directory where JACK puts its temporary files (/tmp by -default), then the JACK team recommends that you do *one* of the -following: - ----------------------------- - -Mount a tmpfs on /tmp. You should have a lot of swap space available -in case some programs try to write very large files there. -In your /etc/fstab add a line: - - none /tmp tmpfs defaults 0 0 - - You'll probably want to reboot here, or kill X then 'mount /tmp'. - ----- OR ---- - -Alternatively, you can do this without affecting your /tmp: - -# mkdir /mnt/ramfs - -[edit /etc/fstab and add the following line] - none /mnt/ramfs tmpfs defaults 0 0 - -Then add --with-default-tmpdir=/mnt/ramfs to the JACK configure -line when you build it. No clients need to be recompiled. - ------------------------------- - -Failure to do one of these could lead to extremely poor performance from JACK, -since its normal operation will cause bursts of disk I/O that are -completely unnecessary. This suggestion can also be used by ext2fs -users if they wish. - +Please see the website (http://jackaudio.org/) for more information. diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/alsa_in.c jack-audio-connection-kit-0.121.0+svn4538/tools/alsa_in.c --- jack-audio-connection-kit-0.118+svn4104/tools/alsa_in.c 2011-01-12 13:01:23.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/alsa_in.c 2011-03-01 01:30:56.000000000 +0000 @@ -76,6 +76,12 @@ snd_pcm_uframes_t real_buffer_size; snd_pcm_uframes_t real_period_size; +// buffers + +char *tmpbuf; +char *outbuf; +float *resampbuf; + // format selection, and corresponding functions from memops in a nice set of structs. typedef struct alsa_format { @@ -306,8 +312,6 @@ */ int process (jack_nframes_t nframes, void *arg) { - char *outbuf; - float *resampbuf; int rlen; int err; snd_pcm_sframes_t delay = target_delay; @@ -321,10 +325,15 @@ // this is for compensating xruns etc... if( delay > (target_delay+max_diff) ) { - char *tmp = alloca( (delay-target_delay) * formats[format].sample_size * num_channels ); - snd_pcm_readi( alsa_handle, tmp, delay-target_delay ); + output_new_delay = (int) delay; + while ((delay-target_delay) > 0) { + snd_pcm_uframes_t to_read = ((delay-target_delay) > 512) ? 512 : (delay-target_delay); + snd_pcm_readi( alsa_handle, tmpbuf, to_read ); + delay -= to_read; + } + delay = target_delay; // Set the resample_rate... we need to adjust the offset integral, to do this. @@ -398,13 +407,6 @@ // Calculate resample_mean so we can init ourselves to saner values. resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; - /* - * now this should do it... - */ - - outbuf = alloca( rlen * formats[format].sample_size * num_channels ); - - resampbuf = alloca( rlen * sizeof( float ) ); // get the data... again: @@ -469,7 +471,7 @@ * sets up the latencies on the ports. */ -int +void latency_cb (jack_latency_callback_mode_t mode, void *arg) { jack_latency_range_t range; @@ -488,8 +490,6 @@ jack_port_set_latency_range (port, mode, &range); } } - - return 0; } @@ -745,6 +745,17 @@ // alloc input ports, which are blasted out to alsa... alloc_ports( num_channels, 0 ); + outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); + resampbuf = malloc( num_periods * period_size * sizeof( float ) ); + tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); + + if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) + { + fprintf( stderr, "no memory for buffers.\n" ); + exit(20); + } + + memset( tmpbuf, 0, 512 * formats[format].sample_size * num_channels); /* tell the JACK server that we are ready to roll */ diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/alsa_out.c jack-audio-connection-kit-0.121.0+svn4538/tools/alsa_out.c --- jack-audio-connection-kit-0.118+svn4104/tools/alsa_out.c 2011-01-12 13:01:23.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/alsa_out.c 2011-03-01 01:31:05.000000000 +0000 @@ -34,6 +34,7 @@ int jack_sample_rate; int jack_buffer_size; +int quit = 0; double resample_mean = 1.0; double static_resample_factor = 1.0; double resample_lower_limit = 0.25; @@ -44,7 +45,6 @@ int offset_differential_index = 0; double offset_integral = 0; -int quit = 0; // ------------------------------------------------------ commandline parameters @@ -76,6 +76,12 @@ snd_pcm_uframes_t real_buffer_size; snd_pcm_uframes_t real_period_size; +// buffers + +char *tmpbuf; +char *outbuf; +float *resampbuf; + // format selection, and corresponding functions from memops in a nice set of structs. typedef struct alsa_format { @@ -89,6 +95,7 @@ alsa_format_t formats[] = { { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, + { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } }; @@ -310,8 +317,6 @@ */ int process (jack_nframes_t nframes, void *arg) { - char *outbuf; - float *resampbuf; int rlen; int err; snd_pcm_sframes_t delay = target_delay; @@ -320,7 +325,6 @@ delay = (num_periods*period_size)-snd_pcm_avail( alsa_handle ) ; delay -= jack_frames_since_cycle_start( client ); - delay += jack_get_buffer_size( client ) / 2; // Do it the hard way. // this is for compensating xruns etc... @@ -339,12 +343,15 @@ offset_array[i] = 0.0; } if( delay < (target_delay-max_diff) ) { - char *tmp = alloca( (target_delay-delay) * formats[format].sample_size * num_channels ); - memset( tmp, 0, formats[format].sample_size * num_channels * (target_delay-delay) ); - snd_pcm_writei( alsa_handle, tmp, target_delay-delay ); output_new_delay = (int) delay; + while ((target_delay-delay) > 0) { + snd_pcm_uframes_t to_write = ((target_delay-delay) > 512) ? 512 : (target_delay-delay); + snd_pcm_writei( alsa_handle, tmpbuf, to_write ); + delay += to_write; + } + delay = target_delay; // Set the resample_rate... we need to adjust the offset integral, to do this. @@ -467,7 +474,7 @@ * sets up the latencies on the ports. */ -int +void latency_cb (jack_latency_callback_mode_t mode, void *arg) { jack_latency_range_t range; @@ -486,8 +493,6 @@ jack_port_set_latency_range (port, mode, &range); } } - - return 0; } @@ -743,6 +748,16 @@ // alloc input ports, which are blasted out to alsa... alloc_ports( 0, num_channels ); + outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); + resampbuf = malloc( num_periods * period_size * sizeof( float ) ); + tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); + + if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) + { + fprintf( stderr, "no memory for buffers.\n" ); + exit(20); + } + /* tell the JACK server that we are ready to roll */ diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/bufsize.c jack-audio-connection-kit-0.121.0+svn4538/tools/bufsize.c --- jack-audio-connection-kit-0.118+svn4104/tools/bufsize.c 2010-05-19 22:00:31.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/bufsize.c 2011-02-22 15:11:44.000000000 +0000 @@ -64,12 +64,23 @@ exit(9); } + if (strspn (argv[1], "0123456789") != strlen (argv[1])) { + fprintf(stderr, "usage: %s \n", package); + exit(8); + } + nframes = strtoul(argv[1], NULL, 0); if (errno == ERANGE) { - fprintf(stderr, "%s: invalid buffer size: %s\n", + fprintf(stderr, "%s: invalid buffer size: %s (range is 1-16384)\n", package, argv[1]); exit(2); } + if (nframes < 1 || nframes > 16384) { + fprintf(stderr, "%s: invalid buffer size: %s (range is 1-16384)\n", + package, argv[1]); + exit(3); + } + } void silent_function( const char *ignore ) diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/iodelay.c jack-audio-connection-kit-0.121.0+svn4538/tools/iodelay.c --- jack-audio-connection-kit-0.118+svn4104/tools/iodelay.c 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/iodelay.c 2011-07-13 12:52:41.000000000 +0000 @@ -0,0 +1,260 @@ +/* + Copyright (C) 2003-2008 Fons Adriaensen + + 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. +*/ + +// -------------------------------------------------------------------------------- + +#include +#include +#include +#include +#include + +struct Freq +{ + int p; + int f; + float a; + float xa; + float ya; + float xf; + float yf; +}; + +struct MTDM +{ + double _del; + double _err; + int _cnt; + int _inv; + struct Freq _freq [5]; +}; + +struct MTDM * mtdm_new (void) +{ + int i; + struct Freq *F; + + struct MTDM *retval = malloc( sizeof(struct MTDM) ); + + if (retval==NULL) + return NULL; + + retval->_cnt = 0; + retval->_inv = 0; + + retval->_freq [0].f = 4096; + retval->_freq [1].f = 512; + retval->_freq [2].f = 1088; + retval->_freq [3].f = 1544; + retval->_freq [4].f = 2049; + + retval->_freq [0].a = 0.2f; + retval->_freq [1].a = 0.1f; + retval->_freq [2].a = 0.1f; + retval->_freq [3].a = 0.1f; + retval->_freq [4].a = 0.1f; + + for (i = 0, F = retval->_freq; i < 5; i++, F++) + { + F->p = 128; + F->xa = F->ya = 0.0f; + F->xf = F->yf = 0.0f; + } + + return retval; +} + +int mtdm_process (struct MTDM *self, size_t len, float *ip, float *op) +{ + int i; + float vip, vop, a, c, s; + struct Freq *F; + + while (len--) + { + vop = 0.0f; + vip = *ip++; + for (i = 0, F = self->_freq; i < 5; i++, F++) + { + a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; + F->p += F->f; + c = cosf (a); + s = -sinf (a); + vop += F->a * s; + F->xa += s * vip; + F->ya += c * vip; + } + *op++ = vop; + if (++(self->_cnt) == 16) + { + for (i = 0, F = self->_freq; i < 5; i++, F++) + { + F->xf += 1e-3f * (F->xa - F->xf + 1e-20); + F->yf += 1e-3f * (F->ya - F->yf + 1e-20); + F->xa = F->ya = 0.0f; + } + self->_cnt = 0; + } + } + + return 0; +} + +int mtdm_resolve (struct MTDM *self) +{ + int i, k, m; + double d, e, f0, p; + struct Freq *F = self->_freq; + + if (hypot (F->xf, F->yf) < 0.01) return -1; + d = atan2 (F->yf, F->xf) / (2 * M_PI); + if (self->_inv) d += 0.5f; + if (d > 0.5f) d -= 1.0f; + f0 = self->_freq [0].f; + m = 1; + self->_err = 0.0; + for (i = 0; i < 4; i++) + { + F++; + p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0; + if (self->_inv) p += 0.5f; + p -= floor (p); + p *= 8; + k = (int)(floor (p + 0.5)); + e = fabs (p - k); + if (e > self->_err) self->_err = e; + if (e > 0.4) return 1; + d += m * (k & 7); + m *= 8; + } + self->_del = 16 * d; + + return 0; +} + +void mtdm_invert (struct MTDM *self) +{ + self->_inv ^= 1; +} +// -------------------------------------------------------------------------------- + +static struct MTDM *mtdm; +static jack_client_t *jack_handle; +static jack_port_t *jack_capt; +static jack_port_t *jack_play; + +jack_latency_range_t capture_latency = {-1, -1}; +jack_latency_range_t playback_latency = {-1, -1}; + +void +latency_cb (jack_latency_callback_mode_t mode, void *arg) +{ + jack_latency_range_t range; + + range.min = range.max = 0; + + if (mode == JackCaptureLatency) { + jack_port_set_latency_range (jack_play, mode, &range); + jack_port_get_latency_range (jack_capt, mode, &range); + if ((range.min != capture_latency.min) || (range.max != capture_latency.max)) { + capture_latency = range; + printf ("new capture latency: [%d, %d]\n", range.min, range.max); + } + } else { + jack_port_set_latency_range (jack_capt, mode, &range); + jack_port_get_latency_range (jack_play, mode, &range); + if ((range.min != playback_latency.min) || (range.max != playback_latency.max)) { + playback_latency = range; + printf ("new playback latency: [%d, %d]\n", range.min, range.max); + } + } + +} + +int jack_callback (jack_nframes_t nframes, void *arg) +{ + float *ip, *op; + + ip = (float *)(jack_port_get_buffer (jack_capt, nframes)); + op = (float *)(jack_port_get_buffer (jack_play, nframes)); + mtdm_process (mtdm, nframes, ip, op); + return 0; +} + +int main (int ac, char *av []) +{ + float t; + jack_status_t s; + + mtdm = mtdm_new(); + + jack_handle = jack_client_open ("jack_delay", JackNoStartServer, &s); + if (jack_handle == 0) + { + fprintf (stderr, "Can't connect to Jack, is the server running ?\n"); + exit (1); + } + + jack_set_process_callback (jack_handle, jack_callback, 0); + + if (jack_set_latency_callback) + jack_set_latency_callback (jack_handle, latency_cb, 0); + + jack_capt = jack_port_register (jack_handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + + t = 1000.0f / jack_get_sample_rate (jack_handle); + + if (jack_activate (jack_handle)) + { + fprintf(stderr, "Can't activate Jack"); + return 1; + } + + while (1) + { + + #ifdef WIN32 + Sleep (250); + #else + usleep (250000); + #endif + if (mtdm_resolve (mtdm) < 0) printf ("Signal below threshold...\n"); + else + { + jack_nframes_t systemic_latency; + + if (mtdm->_err > 0.3) + { + mtdm_invert ( mtdm ); + mtdm_resolve ( mtdm ); + } + systemic_latency = (jack_nframes_t) floor (mtdm->_del - (capture_latency.max + playback_latency.max)); + + printf ("%10.3lf frames %10.3lf ms total roundtrip latency\n\textra loopback latency: %u frames\n\tuse %u for the backend arguments -I and -O", mtdm->_del, mtdm->_del * t, + systemic_latency, systemic_latency/2); + if (mtdm->_err > 0.2) printf (" ??"); + if (mtdm->_inv) printf (" Inv"); + printf ("\n"); + } + } + + return 0; +} + +// -------------------------------------------------------------------------------- diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/load_test.c jack-audio-connection-kit-0.121.0+svn4538/tools/load_test.c --- jack-audio-connection-kit-0.118+svn4104/tools/load_test.c 1970-01-01 00:00:00.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/load_test.c 2011-05-29 00:47:22.000000000 +0000 @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +char * my_name; +jack_client_t *client; +unsigned int wait_timeout = 1000; + +void +show_version (void) +{ + fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n", + my_name); +} + +void +show_usage (void) +{ + show_version (); + fprintf (stderr, "\nUsage: %s [options]\n", my_name); + fprintf (stderr, "this is a test client, which just sleeps in its process_cb to simulate cpu load\n"); + fprintf (stderr, "options:\n"); + fprintf (stderr, " -t, --timeout Wait timeout in seconds\n"); + fprintf (stderr, " -h, --help Display this help message\n"); + fprintf (stderr, " --version Output version information and exit\n\n"); + fprintf (stderr, "For more information see http://jackaudio.org/\n"); +} + +void jack_shutdown(void *arg) +{ + fprintf(stderr, "JACK shut down, exiting ...\n"); + exit(1); +} + +void signal_handler(int sig) +{ + jack_client_close(client); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +int +process_cb (jack_nframes_t nframes, void *arg) +{ + jack_time_t now = jack_get_time(); + jack_time_t wait = now + wait_timeout; + + while (jack_get_time() < wait) ; + + return 0; +} + +int +main (int argc, char *argv[]) +{ + int c; + int option_index; + + struct option long_options[] = { + { "timeout", 1, 0, 't' }, + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'v' }, + { 0, 0, 0, 0 } + }; + + my_name = strrchr(argv[0], '/'); + if (my_name == 0) { + my_name = argv[0]; + } else { + my_name ++; + } + + while ((c = getopt_long (argc, argv, "t:hv", long_options, &option_index)) >= 0) { + switch (c) { + case 't': + wait_timeout = atoi(optarg); + break; + case 'h': + show_usage (); + return 1; + break; + case 'v': + show_version (); + return 1; + break; + default: + show_usage (); + return 1; + break; + } + } + + /* try to open server in a loop. breaking under certein conditions */ + + client = jack_client_open( "load_test", JackNullOption, NULL ); + + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + + jack_on_shutdown(client, jack_shutdown, 0); + + jack_set_process_callback( client, process_cb, NULL ); + + jack_activate (client); + + sleep( -1 ); + + exit (0); +} diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/Makefile.am jack-audio-connection-kit-0.121.0+svn4538/tools/Makefile.am --- jack-audio-connection-kit-0.118+svn4104/tools/Makefile.am 2010-07-25 19:53:48.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/Makefile.am 2011-05-29 00:47:18.000000000 +0000 @@ -41,6 +41,8 @@ jack_session_notify \ jack_wait \ jack_midi_dump \ + jack_iodelay \ + jack_load_test \ $(JACK_TRANSPORT) \ $(NETJACK_TOOLS) @@ -106,12 +108,19 @@ jack_midi_dump_LDFLAGS = @OS_LDFLAGS@ jack_midi_dump_LDADD = $(top_builddir)/libjack/libjack.la +jack_iodelay_SOURCES = iodelay.c +jack_iodelay_LDFLAGS = @OS_LDFLAGS@ +jack_iodelay_LDADD = $(top_builddir)/libjack/libjack.la + if HAVE_READLINE jack_transport_SOURCES = transport.c jack_transport_LDFLAGS = -lreadline @READLINE_DEPS@ @OS_LDFLAGS@ jack_transport_LDADD = $(top_builddir)/libjack/libjack.la endif +jack_load_test_SOURCES = load_test.c +jack_load_test_LDFLAGS = @OS_LDFLAGS@ +jack_load_test_LDADD = $(top_builddir)/libjack/libjack.la # # General purpose in-process loader/unloader # diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/midi_dump.c jack-audio-connection-kit-0.121.0+svn4538/tools/midi_dump.c --- jack-audio-connection-kit-0.118+svn4104/tools/midi_dump.c 2010-07-25 19:53:48.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/midi_dump.c 2011-01-12 17:10:52.000000000 +0000 @@ -1,4 +1,5 @@ #include +#include #include #include #include diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/netsource.c jack-audio-connection-kit-0.121.0+svn4538/tools/netsource.c --- jack-audio-connection-kit-0.118+svn4104/tools/netsource.c 2010-10-06 14:21:19.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/netsource.c 2011-05-29 00:47:47.000000000 +0000 @@ -352,10 +352,10 @@ // Now loop until we get the right packet. while(1) { jack_nframes_t got_frame; - if ( ! netjack_poll_deadline( input_fd, deadline ) ) + if ( ! netjack_poll_deadline( input_fd, deadline, jack_get_time ) ) break; - packet_cache_drain_socket(packcache, input_fd); + packet_cache_drain_socket(packcache, input_fd, jack_get_time); if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame )) if( got_frame == (framecnt - latency) ) @@ -364,7 +364,7 @@ } else { // normally: // only drain socket. - packet_cache_drain_socket(packcache, input_fd); + packet_cache_drain_socket(packcache, input_fd, jack_get_time); } size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); diff -Nru jack-audio-connection-kit-0.118+svn4104/tools/samplerate.c jack-audio-connection-kit-0.121.0+svn4538/tools/samplerate.c --- jack-audio-connection-kit-0.118+svn4104/tools/samplerate.c 2010-03-02 18:39:52.000000000 +0000 +++ jack-audio-connection-kit-0.121.0+svn4538/tools/samplerate.c 2011-04-18 17:40:37.000000000 +0000 @@ -56,7 +56,7 @@ if (argc==1) { return; } - fprintf(stderr, "usage: %s [bufsize]\n", package); + fprintf(stderr, "usage: %s\n", package); exit(9); }