From d172d3d493ad4f9c30f04abf9eb5c6a6dd4fb602 Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 6 Dec 2007 15:08:56 +0000 Subject: [PATCH] Pieter Palmers FFADO driver and scons based build. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1725 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 7 +- SConstruct | 528 ++++++++++++++++++++++++++++ admin/doxygen.py | 456 ++++++++++++++++++++++++ admin/pkgconfig.py | 274 +++++++++++++++ admin/scanreplace.py | 80 +++++ common/JackDriverLoader.cpp | 2 + common/JackGlobalsClient.cpp | 4 +- common/JackGlobalsServer.cpp | 4 +- common/JackServerLaunch.cpp | 2 + linux/Makefile | 18 +- linux/freebob/JackFreebobDriver.cpp | 29 +- 11 files changed, 1376 insertions(+), 28 deletions(-) create mode 100644 SConstruct create mode 100644 admin/doxygen.py create mode 100644 admin/pkgconfig.py create mode 100644 admin/scanreplace.py diff --git a/ChangeLog b/ChangeLog index d7dae1d3..8c106d25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,12 +9,17 @@ Thibault LeMeur Pieter Palmers Tom Szilagyi Andrzej Szombierski -Kjetil S.Matheussen +Kjetil S.Matheussen +Pieter Palmers --------------------------- Jackdmp changes log --------------------------- +2007-12-06 Stephane Letz + + * Pieter Palmers FFADO driver and scons based build. + 2007-12-05 Stephane Letz * Correct sample_rate management in JackCoreAudioDriver::Open. Better handling in sample_rate change listener. diff --git a/SConstruct b/SConstruct new file mode 100644 index 00000000..5bf4e5c2 --- /dev/null +++ b/SConstruct @@ -0,0 +1,528 @@ +# +# Copyright (C) 2007 Arnold Krille +# Copyright (C) 2007 Pieter Palmers +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +from string import Template + +build_dir = ARGUMENTS.get('BUILDDIR', "") +if build_dir: + build_base=build_dir+'/' + if not os.path.isdir( build_base ): + os.makedirs( build_base ) + print "Building into: " + build_base +else: + build_base='' + +if not os.path.isdir( "cache" ): + os.makedirs( "cache" ) + +opts = Options( "cache/"+build_base+"options.cache" ) + +# make this into a command line option and/or a detected value +build_for_linux = True + +# +# If this is just to display a help-text for the variable used via ARGUMENTS, then its wrong... +opts.Add( "BUILDDIR", "Path to place the built files in", "") + +opts.AddOptions( +# BoolOption( "DEBUG", """\ +#Toggle debug-build. DEBUG means \"-g -Wall\" and more, otherwise we will use +# \"-O2\" to optimise.""", True ), + PathOption( "PREFIX", "The prefix where jackdmp will be installed to.", "/usr/local", PathOption.PathAccept ), + PathOption( "BINDIR", "Overwrite the directory where apps are installed to.", "$PREFIX/bin", PathOption.PathAccept ), + PathOption( "LIBDIR", "Overwrite the directory where libs are installed to.", "$PREFIX/lib", PathOption.PathAccept ), + PathOption( "INCLUDEDIR", "Overwrite the directory where headers are installed to.", "$PREFIX/include", PathOption.PathAccept ), + PathOption( "SHAREDIR", "Overwrite the directory where misc shared files are installed to.", "$PREFIX/share/libffado", PathOption.PathAccept ), + BoolOption( "ENABLE_ALSA", "Enable/Disable the ALSA backend.", True ), + BoolOption( "ENABLE_FREEBOB", "Enable/Disable the FreeBoB backend.", True ), + BoolOption( "ENABLE_FIREWIRE", "Enable/Disable the FireWire backend.", True ), + BoolOption( "DEBUG", """Do a debug build.""", True ), + BoolOption( "BUILD_TESTS", """Build tests where applicable.""", True ), + BoolOption( "BUILD_EXAMPLES", """Build the example clients in their directory.""", True ), + BoolOption( "INSTALL_EXAMPLES", """Install the example clients in the BINDIR directory.""", True ), + BoolOption( "BUILD_DOXYGEN_DOCS", """Build doxygen documentation.""", True ), + ) + +## Load the builders in config +buildenv={} +if os.environ.has_key('PATH'): + buildenv['PATH']=os.environ['PATH'] +else: + buildenv['PATH']='' + +if os.environ.has_key('PKG_CONFIG_PATH'): + buildenv['PKG_CONFIG_PATH']=os.environ['PKG_CONFIG_PATH'] +else: + buildenv['PKG_CONFIG_PATH']='' + +if os.environ.has_key('LD_LIBRARY_PATH'): + buildenv['LD_LIBRARY_PATH']=os.environ['LD_LIBRARY_PATH'] +else: + buildenv['LD_LIBRARY_PATH']='' + + +env = Environment( tools=['default','scanreplace','pkgconfig', 'doxygen'], toolpath=['admin'], ENV=buildenv, options=opts ) + +Help( """ +For building jackdmp you can set different options as listed below. You have to +specify them only once, scons will save the last value you used and re-use +that. +To really undo your settings and return to the factory defaults, remove the +"cache"-folder and the file ".sconsign.dblite" from this directory. +For example with: "rm -Rf .sconsign.dblite cache" + +""" ) +Help( opts.GenerateHelpText( env ) ) + +# make sure the necessary dirs exist +if not os.path.isdir( "cache/" + build_base ): + os.makedirs( "cache/" + build_base ) +if not os.path.isdir( 'cache/objects' ): + os.makedirs( 'cache/objects' ) + +if build_base: + env['build_base']="#/"+build_base +else: + env['build_base']="#/" + + +CacheDir( 'cache/objects' ) +opts.Save( 'cache/' + build_base + "options.cache", env ) + +tests = {} +tests.update( env['PKGCONFIG_TESTS'] ) + +if not env.GetOption('clean'): + conf = Configure( env, + custom_tests = tests, + conf_dir = "cache/" + build_base, + log_file = "cache/" + build_base + 'config.log' ) + + # + # Check if the environment can actually compile c-files by checking for a + # header shipped with gcc. + # + if not conf.CheckHeader( "stdio.h" ): + print "It seems as if stdio.h is missing. This probably means that your build environment is broken, please make sure you have a working c-compiler and libstdc installed and usable." + Exit( 1 ) + + # + # The following checks are for headers and libs and packages we need. + # + allpresent = 1; + + if build_for_linux: + allpresent &= conf.CheckForPKGConfig(); + +# example on how to check for additional libs +# pkgs = { +# 'alsa' : '1.0.0', +# } +# for pkg in pkgs: +# name2 = pkg.replace("+","").replace(".","").replace("-","").upper() +# env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] ) +# if env['%s_FLAGS'%name2] == 0: +# allpresent &= 0 + + if not allpresent: + print """ +(At least) One of the dependencies is missing. I can't go on without it, please +install the needed packages (remember to also install the *-devel packages) +""" + Exit( 1 ) + + # jack doesn't have to be present, but it would be nice to know if it is + env['JACK_FLAGS'] = conf.GetPKGFlags( 'jack', '0.100.0' ) + if env['JACK_FLAGS']: + env['JACK_PREFIX'] = conf.GetPKGPrefix( 'jack' ) + env['JACK_EXEC_PREFIX'] = conf.GetPKGExecPrefix( 'jack' ) + env['JACK_LIBDIR'] = conf.GetPKGLibdir( 'jack' ) + env['JACK_INCLUDEDIR'] = conf.GetPKGIncludedir( 'jack' ) + + # + # Optional checks follow: + # + if build_for_linux and env['ENABLE_ALSA']: + env['ALSA_FLAGS'] = conf.GetPKGFlags( 'ALSA', '1.0.0' ) + if env['ALSA_FLAGS'] == 0: + print " Disabling 'alsa' backend since no useful ALSA installation found." + env['ENABLE_ALSA'] = False + + if build_for_linux and env['ENABLE_FREEBOB']: + env['FREEBOB_FLAGS'] = conf.GetPKGFlags( 'libfreebob', '1.0.0' ) + if env['FREEBOB_FLAGS'] == 0: + print " Disabling 'freebob' backend since no useful FreeBoB installation found." + env['ENABLE_FREEBOB'] = False + + if build_for_linux and env['ENABLE_FIREWIRE']: + env['FFADO_FLAGS'] = conf.GetPKGFlags( 'libffado', '1.999.7' ) + if env['FFADO_FLAGS'] == 0: + print " Disabling 'firewire' backend since no useful FFADO installation found." + env['ENABLE_FIREWIRE'] = False + + env = conf.Finish() + +if env['DEBUG']: + print "Doing a DEBUG build" + # -Werror could be added to, which would force the devs to really remove all the warnings :-) + env.AppendUnique( CCFLAGS=["-DDEBUG","-Wall","-g"] ) + env.AppendUnique( CFLAGS=["-DDEBUG","-Wall","-g"] ) +else: + env.AppendUnique( CCFLAGS=["-O2","-DNDEBUG"] ) + env.AppendUnique( CFLAGS=["-O2","-DNDEBUG"] ) + +env.AppendUnique( CCFLAGS=["-fPIC", "-DSOCKET_RPC_FIFO_SEMA", "-D__SMP__"] ) +env.AppendUnique( CFLAGS=["-fPIC", "-DUSE_POSIX_SHM"] ) + +# +# XXX: Maybe we can even drop these lower-case variables and only use the uppercase ones? +# +env['prefix'] = Template( os.path.join( env['PREFIX'] ) ).safe_substitute( env ) +env['bindir'] = Template( os.path.join( env['BINDIR'] ) ).safe_substitute( env ) +env['libdir'] = Template( os.path.join( env['LIBDIR'] ) ).safe_substitute( env ) +env['includedir'] = Template( os.path.join( env['INCLUDEDIR'] ) ).safe_substitute( env ) +env['sharedir'] = Template( os.path.join( env['SHAREDIR'] ) ).safe_substitute( env ) + +env.Alias( "install", env['libdir'] ) +env.Alias( "install", env['includedir'] ) +env.Alias( "install", env['sharedir'] ) +env.Alias( "install", env['bindir'] ) + +# for config.h.in +env['ADDON_DIR']='%s' % env['prefix'] +env['LIB_DIR']='lib' +env['JACK_LOCATION']='%s' % env['bindir'] + +# +# To have the top_srcdir as the doxygen-script is used from auto* +# +env['top_srcdir'] = env.Dir( "." ).abspath + +#subprojects = env.Split('common common/jack tests example-clients linux/alsa linux/freebob linux/firewire') + +#for subproject in subprojects: + #env.AppendUnique( CCFLAGS=["-I%s" % subproject] ) + #env.AppendUnique( CFLAGS=["-I%s" % subproject] ) + +env.ScanReplace( "config.h.in" ) +# ensure that the config.h is always updated, since it +# sometimes fails to pick up the changes +# note: this still doesn't seem to cause dependent files to be rebuilt. +NoCache("config.h") +AlwaysBuild("config.h") + +# +# Start building +# +if env['BUILD_DOXYGEN_DOCS']: + env.Doxygen("doxyfile") + +subdirs=['common'] +if build_for_linux: + subdirs.append('linux') + +if env['BUILD_EXAMPLES']: + subdirs.append('example-clients') + +if env['BUILD_TESTS']: + subdirs.append('tests') + +if build_base: + env.SConscript( dirs=subdirs, exports="env", build_dir=build_base+subdir ) +else: + env.SConscript( dirs=subdirs, exports="env" ) + +# +# Copyright (C) 2007 Arnold Krille +# Copyright (C) 2007 Pieter Palmers +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +from string import Template + +build_dir = ARGUMENTS.get('BUILDDIR', "") +if build_dir: + build_base=build_dir+'/' + if not os.path.isdir( build_base ): + os.makedirs( build_base ) + print "Building into: " + build_base +else: + build_base='' + +if not os.path.isdir( "cache" ): + os.makedirs( "cache" ) + +opts = Options( "cache/"+build_base+"options.cache" ) + +# make this into a command line option and/or a detected value +build_for_linux = True + +# +# If this is just to display a help-text for the variable used via ARGUMENTS, then its wrong... +opts.Add( "BUILDDIR", "Path to place the built files in", "") + +opts.AddOptions( +# BoolOption( "DEBUG", """\ +#Toggle debug-build. DEBUG means \"-g -Wall\" and more, otherwise we will use +# \"-O2\" to optimise.""", True ), + PathOption( "PREFIX", "The prefix where jackdmp will be installed to.", "/usr/local", PathOption.PathAccept ), + PathOption( "BINDIR", "Overwrite the directory where apps are installed to.", "$PREFIX/bin", PathOption.PathAccept ), + PathOption( "LIBDIR", "Overwrite the directory where libs are installed to.", "$PREFIX/lib", PathOption.PathAccept ), + PathOption( "INCLUDEDIR", "Overwrite the directory where headers are installed to.", "$PREFIX/include", PathOption.PathAccept ), + PathOption( "SHAREDIR", "Overwrite the directory where misc shared files are installed to.", "$PREFIX/share/libffado", PathOption.PathAccept ), + BoolOption( "ENABLE_ALSA", "Enable/Disable the ALSA backend.", True ), + BoolOption( "ENABLE_FREEBOB", "Enable/Disable the FreeBoB backend.", True ), + BoolOption( "ENABLE_FIREWIRE", "Enable/Disable the FireWire backend.", True ), + BoolOption( "DEBUG", """Do a debug build.""", True ), + BoolOption( "BUILD_TESTS", """Build tests where applicable.""", True ), + BoolOption( "BUILD_EXAMPLES", """Build the example clients in their directory.""", True ), + BoolOption( "INSTALL_EXAMPLES", """Install the example clients in the BINDIR directory.""", True ), + BoolOption( "BUILD_DOXYGEN_DOCS", """Build doxygen documentation.""", True ), + ) + +## Load the builders in config +buildenv={} +if os.environ.has_key('PATH'): + buildenv['PATH']=os.environ['PATH'] +else: + buildenv['PATH']='' + +if os.environ.has_key('PKG_CONFIG_PATH'): + buildenv['PKG_CONFIG_PATH']=os.environ['PKG_CONFIG_PATH'] +else: + buildenv['PKG_CONFIG_PATH']='' + +if os.environ.has_key('LD_LIBRARY_PATH'): + buildenv['LD_LIBRARY_PATH']=os.environ['LD_LIBRARY_PATH'] +else: + buildenv['LD_LIBRARY_PATH']='' + + +env = Environment( tools=['default','scanreplace','pkgconfig', 'doxygen'], toolpath=['admin'], ENV=buildenv, options=opts ) + +Help( """ +For building jackdmp you can set different options as listed below. You have to +specify them only once, scons will save the last value you used and re-use +that. +To really undo your settings and return to the factory defaults, remove the +"cache"-folder and the file ".sconsign.dblite" from this directory. +For example with: "rm -Rf .sconsign.dblite cache" + +""" ) +Help( opts.GenerateHelpText( env ) ) + +# make sure the necessary dirs exist +if not os.path.isdir( "cache/" + build_base ): + os.makedirs( "cache/" + build_base ) +if not os.path.isdir( 'cache/objects' ): + os.makedirs( 'cache/objects' ) + +if build_base: + env['build_base']="#/"+build_base +else: + env['build_base']="#/" + + +CacheDir( 'cache/objects' ) +opts.Save( 'cache/' + build_base + "options.cache", env ) + +tests = {} +tests.update( env['PKGCONFIG_TESTS'] ) + +if not env.GetOption('clean'): + conf = Configure( env, + custom_tests = tests, + conf_dir = "cache/" + build_base, + log_file = "cache/" + build_base + 'config.log' ) + + # + # Check if the environment can actually compile c-files by checking for a + # header shipped with gcc. + # + if not conf.CheckHeader( "stdio.h" ): + print "It seems as if stdio.h is missing. This probably means that your build environment is broken, please make sure you have a working c-compiler and libstdc installed and usable." + Exit( 1 ) + + # + # The following checks are for headers and libs and packages we need. + # + allpresent = 1; + + if build_for_linux: + allpresent &= conf.CheckForPKGConfig(); + +# example on how to check for additional libs +# pkgs = { +# 'alsa' : '1.0.0', +# } +# for pkg in pkgs: +# name2 = pkg.replace("+","").replace(".","").replace("-","").upper() +# env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] ) +# if env['%s_FLAGS'%name2] == 0: +# allpresent &= 0 + + if not allpresent: + print """ +(At least) One of the dependencies is missing. I can't go on without it, please +install the needed packages (remember to also install the *-devel packages) +""" + Exit( 1 ) + + # jack doesn't have to be present, but it would be nice to know if it is + env['JACK_FLAGS'] = conf.GetPKGFlags( 'jack', '0.100.0' ) + if env['JACK_FLAGS']: + env['JACK_PREFIX'] = conf.GetPKGPrefix( 'jack' ) + env['JACK_EXEC_PREFIX'] = conf.GetPKGExecPrefix( 'jack' ) + env['JACK_LIBDIR'] = conf.GetPKGLibdir( 'jack' ) + env['JACK_INCLUDEDIR'] = conf.GetPKGIncludedir( 'jack' ) + + # + # Optional checks follow: + # + if build_for_linux and env['ENABLE_ALSA']: + env['ALSA_FLAGS'] = conf.GetPKGFlags( 'ALSA', '1.0.0' ) + if env['ALSA_FLAGS'] == 0: + print " Disabling 'alsa' backend since no useful ALSA installation found." + env['ENABLE_ALSA'] = False + + if build_for_linux and env['ENABLE_FREEBOB']: + env['FREEBOB_FLAGS'] = conf.GetPKGFlags( 'libfreebob', '1.0.0' ) + if env['FREEBOB_FLAGS'] == 0: + print " Disabling 'freebob' backend since no useful FreeBoB installation found." + env['ENABLE_FREEBOB'] = False + + if build_for_linux and env['ENABLE_FIREWIRE']: + env['FFADO_FLAGS'] = conf.GetPKGFlags( 'libffado', '1.999.7' ) + if env['FFADO_FLAGS'] == 0: + print " Disabling 'firewire' backend since no useful FFADO installation found." + env['ENABLE_FIREWIRE'] = False + + env = conf.Finish() + +if env['DEBUG']: + print "Doing a DEBUG build" + # -Werror could be added to, which would force the devs to really remove all the warnings :-) + env.AppendUnique( CCFLAGS=["-DDEBUG","-Wall","-g"] ) + env.AppendUnique( CFLAGS=["-DDEBUG","-Wall","-g"] ) +else: + env.AppendUnique( CCFLAGS=["-O2","-DNDEBUG"] ) + env.AppendUnique( CFLAGS=["-O2","-DNDEBUG"] ) + +env.AppendUnique( CCFLAGS=["-fPIC", "-DSOCKET_RPC_FIFO_SEMA", "-D__SMP__"] ) +env.AppendUnique( CFLAGS=["-fPIC", "-DUSE_POSIX_SHM"] ) + +# +# XXX: Maybe we can even drop these lower-case variables and only use the uppercase ones? +# +env['prefix'] = Template( os.path.join( env['PREFIX'] ) ).safe_substitute( env ) +env['bindir'] = Template( os.path.join( env['BINDIR'] ) ).safe_substitute( env ) +env['libdir'] = Template( os.path.join( env['LIBDIR'] ) ).safe_substitute( env ) +env['includedir'] = Template( os.path.join( env['INCLUDEDIR'] ) ).safe_substitute( env ) +env['sharedir'] = Template( os.path.join( env['SHAREDIR'] ) ).safe_substitute( env ) + +env.Alias( "install", env['libdir'] ) +env.Alias( "install", env['includedir'] ) +env.Alias( "install", env['sharedir'] ) +env.Alias( "install", env['bindir'] ) + +# for config.h.in +env['ADDON_DIR']='%s' % env['prefix'] +env['LIB_DIR']='lib' +env['JACK_LOCATION']='%s' % env['bindir'] + +# +# To have the top_srcdir as the doxygen-script is used from auto* +# +env['top_srcdir'] = env.Dir( "." ).abspath + +#subprojects = env.Split('common common/jack tests example-clients linux/alsa linux/freebob linux/firewire') + +#for subproject in subprojects: + #env.AppendUnique( CCFLAGS=["-I%s" % subproject] ) + #env.AppendUnique( CFLAGS=["-I%s" % subproject] ) + +env.ScanReplace( "config.h.in" ) +# ensure that the config.h is always updated, since it +# sometimes fails to pick up the changes +# note: this still doesn't seem to cause dependent files to be rebuilt. +NoCache("config.h") +AlwaysBuild("config.h") + +# +# Start building +# +if env['BUILD_DOXYGEN_DOCS']: + env.Doxygen("doxyfile") + +subdirs=['common'] +if build_for_linux: + subdirs.append('linux') + +if env['BUILD_EXAMPLES']: + subdirs.append('example-clients') + +if env['BUILD_TESTS']: + subdirs.append('tests') + +if build_base: + env.SConscript( dirs=subdirs, exports="env", build_dir=build_base+subdir ) +else: + env.SConscript( dirs=subdirs, exports="env" ) + +# -*- python -*- + +import os +import sys +import re +import shutil +import glob +import errno +import time +import platform +import string +import commands + +platform = ARGUMENTS.get('OS', Platform()) + +env = Environment(PLATFORM = platform, + CPPPATH = ['macosx', 'common']) + +Export('env') + +print platform + +env.SConscript(['common/SConscript']) + \ No newline at end of file diff --git a/admin/doxygen.py b/admin/doxygen.py new file mode 100644 index 00000000..4b20dc25 --- /dev/null +++ b/admin/doxygen.py @@ -0,0 +1,456 @@ +#!/usr/bin/python +# +# Copyright (C) 2007 Arnold Krille +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Astxx, the Asterisk C++ API and Utility Library. +# Copyright (C) 2005, 2006 Matthew A. Nicholson +# Copyright (C) 2006 Tim Blechmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os +import os.path +import glob +from fnmatch import fnmatch + +def DoxyfileParse(file_contents): + """ + Parse a Doxygen source file and return a dictionary of all the values. + Values will be strings and lists of strings. + """ + data = {} + + import shlex + lex = shlex.shlex(instream = file_contents, posix = True) + lex.wordchars += "*+./-:" + lex.whitespace = lex.whitespace.replace("\n", "") + lex.escape = "" + + lineno = lex.lineno + token = lex.get_token() + key = token # the first token should be a key + last_token = "" + key_token = False + next_key = False + new_data = True + + def append_data(data, key, new_data, token): + if new_data or len(data[key]) == 0: + data[key].append(token) + else: + data[key][-1] += token + + while token: + if token in ['\n']: + if last_token not in ['\\']: + key_token = True + elif token in ['\\']: + pass + elif key_token: + key = token + key_token = False + else: + if token == "+=": + if not data.has_key(key): + data[key] = list() + elif token == "=": + data[key] = list() + else: + append_data( data, key, new_data, token ) + new_data = True + + last_token = token + token = lex.get_token() + + if last_token == '\\' and token != '\n': + new_data = False + append_data( data, key, new_data, '\\' ) + + # compress lists of len 1 into single strings + for (k, v) in data.items(): + if len(v) == 0: + data.pop(k) + + # items in the following list will be kept as lists and not converted to strings + if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]: + continue + + if len(v) == 1: + data[k] = v[0] + + return data + +def DoxySourceScan(node, env, path): + """ + Doxygen Doxyfile source scanner. This should scan the Doxygen file and add + any files used to generate docs to the list of source files. + """ + default_file_patterns = [ + '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx', + '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++', + '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm', + '*.py', + ] + + default_exclude_patterns = [ + '*~', + ] + + sources = [] + + data = DoxyfileParse(node.get_contents()) + + if data.get("RECURSIVE", "NO") == "YES": + recursive = True + else: + recursive = False + + file_patterns = data.get("FILE_PATTERNS", default_file_patterns) + exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) + + for node in data.get("INPUT", []): + if os.path.isfile(node): + sources.append(node) + elif os.path.isdir(node): + if recursive: + for root, dirs, files in os.walk(node): + for f in files: + filename = os.path.join(root, f) + + pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False) + exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True) + + if pattern_check and not exclude_check: + sources.append(filename) + else: + for pattern in file_patterns: + sources.extend(glob.glob("/".join([node, pattern]))) + + sources = map( lambda path: env.File(path), sources ) + return sources + + +def DoxySourceScanCheck(node, env): + """Check if we should scan this file""" + return os.path.isfile(node.path) + +def DoxyEmitter(source, target, env): + """Doxygen Doxyfile emitter""" + # possible output formats and their default values and output locations + output_formats = { + "HTML": ("YES", "html"), + "LATEX": ("YES", "latex"), + "RTF": ("NO", "rtf"), + "MAN": ("YES", "man"), + "XML": ("NO", "xml"), + } + + data = DoxyfileParse(source[0].get_contents()) + + targets = [] + out_dir = data.get("OUTPUT_DIRECTORY", ".") + + # add our output locations + for (k, v) in output_formats.items(): + if data.get("GENERATE_" + k, v[0]) == "YES": + targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) + + # don't clobber targets + for node in targets: + env.Precious(node) + + # set up cleaning stuff + for node in targets: + env.Clean(node, node) + + return (targets, source) + +def generate(env): + """ + Add builders and construction variables for the + Doxygen tool. This is currently for Doxygen 1.4.6. + """ + doxyfile_scanner = env.Scanner( + DoxySourceScan, + "DoxySourceScan", + scan_check = DoxySourceScanCheck, + ) + + import SCons.Builder + doxyfile_builder = SCons.Builder.Builder( + action = "cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}", + emitter = DoxyEmitter, + target_factory = env.fs.Entry, + single_source = True, + source_scanner = doxyfile_scanner, + ) + + env.Append(BUILDERS = { + 'Doxygen': doxyfile_builder, + }) + + env.AppendUnique( + DOXYGEN = 'doxygen', + ) + +def exists(env): + """ + Make sure doxygen exists. + """ + return env.Detect("doxygen") +#!/usr/bin/python +# +# Copyright (C) 2007 Arnold Krille +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Astxx, the Asterisk C++ API and Utility Library. +# Copyright (C) 2005, 2006 Matthew A. Nicholson +# Copyright (C) 2006 Tim Blechmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os +import os.path +import glob +from fnmatch import fnmatch + +def DoxyfileParse(file_contents): + """ + Parse a Doxygen source file and return a dictionary of all the values. + Values will be strings and lists of strings. + """ + data = {} + + import shlex + lex = shlex.shlex(instream = file_contents, posix = True) + lex.wordchars += "*+./-:" + lex.whitespace = lex.whitespace.replace("\n", "") + lex.escape = "" + + lineno = lex.lineno + token = lex.get_token() + key = token # the first token should be a key + last_token = "" + key_token = False + next_key = False + new_data = True + + def append_data(data, key, new_data, token): + if new_data or len(data[key]) == 0: + data[key].append(token) + else: + data[key][-1] += token + + while token: + if token in ['\n']: + if last_token not in ['\\']: + key_token = True + elif token in ['\\']: + pass + elif key_token: + key = token + key_token = False + else: + if token == "+=": + if not data.has_key(key): + data[key] = list() + elif token == "=": + data[key] = list() + else: + append_data( data, key, new_data, token ) + new_data = True + + last_token = token + token = lex.get_token() + + if last_token == '\\' and token != '\n': + new_data = False + append_data( data, key, new_data, '\\' ) + + # compress lists of len 1 into single strings + for (k, v) in data.items(): + if len(v) == 0: + data.pop(k) + + # items in the following list will be kept as lists and not converted to strings + if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]: + continue + + if len(v) == 1: + data[k] = v[0] + + return data + +def DoxySourceScan(node, env, path): + """ + Doxygen Doxyfile source scanner. This should scan the Doxygen file and add + any files used to generate docs to the list of source files. + """ + default_file_patterns = [ + '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx', + '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++', + '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm', + '*.py', + ] + + default_exclude_patterns = [ + '*~', + ] + + sources = [] + + data = DoxyfileParse(node.get_contents()) + + if data.get("RECURSIVE", "NO") == "YES": + recursive = True + else: + recursive = False + + file_patterns = data.get("FILE_PATTERNS", default_file_patterns) + exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) + + for node in data.get("INPUT", []): + if os.path.isfile(node): + sources.append(node) + elif os.path.isdir(node): + if recursive: + for root, dirs, files in os.walk(node): + for f in files: + filename = os.path.join(root, f) + + pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False) + exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True) + + if pattern_check and not exclude_check: + sources.append(filename) + else: + for pattern in file_patterns: + sources.extend(glob.glob("/".join([node, pattern]))) + + sources = map( lambda path: env.File(path), sources ) + return sources + + +def DoxySourceScanCheck(node, env): + """Check if we should scan this file""" + return os.path.isfile(node.path) + +def DoxyEmitter(source, target, env): + """Doxygen Doxyfile emitter""" + # possible output formats and their default values and output locations + output_formats = { + "HTML": ("YES", "html"), + "LATEX": ("YES", "latex"), + "RTF": ("NO", "rtf"), + "MAN": ("YES", "man"), + "XML": ("NO", "xml"), + } + + data = DoxyfileParse(source[0].get_contents()) + + targets = [] + out_dir = data.get("OUTPUT_DIRECTORY", ".") + + # add our output locations + for (k, v) in output_formats.items(): + if data.get("GENERATE_" + k, v[0]) == "YES": + targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) + + # don't clobber targets + for node in targets: + env.Precious(node) + + # set up cleaning stuff + for node in targets: + env.Clean(node, node) + + return (targets, source) + +def generate(env): + """ + Add builders and construction variables for the + Doxygen tool. This is currently for Doxygen 1.4.6. + """ + doxyfile_scanner = env.Scanner( + DoxySourceScan, + "DoxySourceScan", + scan_check = DoxySourceScanCheck, + ) + + import SCons.Builder + doxyfile_builder = SCons.Builder.Builder( + action = "cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}", + emitter = DoxyEmitter, + target_factory = env.fs.Entry, + single_source = True, + source_scanner = doxyfile_scanner, + ) + + env.Append(BUILDERS = { + 'Doxygen': doxyfile_builder, + }) + + env.AppendUnique( + DOXYGEN = 'doxygen', + ) + +def exists(env): + """ + Make sure doxygen exists. + """ + return env.Detect("doxygen") \ No newline at end of file diff --git a/admin/pkgconfig.py b/admin/pkgconfig.py new file mode 100644 index 00000000..c980f187 --- /dev/null +++ b/admin/pkgconfig.py @@ -0,0 +1,274 @@ +#!/usr/bin/python +# +# Copyright (C) 2007 Arnold Krille +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Taken from http://www.scons.org/wiki/UsingPkgConfig +# and heavily modified +# + +# +# Checks for pkg-config +# +def CheckForPKGConfig( context, version='0.0.0' ): + context.Message( "Checking for pkg-config (at least version %s)... " % version ) + ret = context.TryAction( "pkg-config --atleast-pkgconfig-version=%s" %version )[0] + context.Result( ret ) + return ret + +# +# Checks for the given package with an optional version-requirement +# +# The flags (which can be imported into the environment by env.MergeFlags(...) +# are exported as env['NAME_FLAGS'] where name is built by removing all +,-,. +# and upper-casing. +# +def CheckForPKG( context, name, version="" ): + name2 = name.replace("+","").replace(".","").replace("-","") + + if version == "": + context.Message( "Checking for %s... \t" % name ) + ret = context.TryAction( "pkg-config --exists '%s'" % name )[0] + else: + context.Message( "Checking for %s (%s or higher)... \t" % (name,version) ) + ret = context.TryAction( "pkg-config --atleast-version=%s '%s'" % (version,name) )[0] + + if ret: + context.env['%s_FLAGS' % name2.upper()] = context.env.ParseFlags("!pkg-config --cflags --libs %s" % name) + + context.Result( ret ) + return ret + +# +# Checks for the existance of the package and returns the packages flags. +# +# This should allow caching of the flags so that pkg-config is called only once. +# +def GetPKGFlags( context, name, version="" ): + import os + + if version == "": + context.Message( "Checking for %s... \t" % name ) + ret = context.TryAction( "pkg-config --exists '%s'" % name )[0] + else: + context.Message( "Checking for %s (%s or higher)... \t" % (name,version) ) + ret = context.TryAction( "pkg-config --atleast-version=%s '%s'" % (version,name) )[0] + + if not ret: + context.Result( ret ) + return ret + + out = os.popen2( "pkg-config --cflags --libs %s" % name )[1] + ret = out.read() + + context.Result( True ) + return ret + +def GetPKGPrefix( context, name ): + import os + + out = os.popen2( "pkg-config --variable=prefix %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting prefix... \t" ) + context.Result( True ) + return ret + +def GetPKGExecPrefix( context, name ): + import os + + out = os.popen2( "pkg-config --variable=exec_prefix %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting exec prefix... \t" ) + context.Result( True ) + return ret + +def GetPKGIncludedir( context, name ): + import os + + out = os.popen2( "pkg-config --variable=includedir %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting include dir... \t" ) + context.Result( True ) + return ret + +def GetPKGLibdir( context, name ): + import os + + out = os.popen2( "pkg-config --variable=libdir %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting lib dir... \t" ) + context.Result( True ) + return ret + +def generate( env, **kw ): + env['PKGCONFIG_TESTS' ] = { + 'CheckForPKGConfig' : CheckForPKGConfig, + 'CheckForPKG' : CheckForPKG, + 'GetPKGFlags' : GetPKGFlags, + 'GetPKGPrefix' : GetPKGPrefix, + 'GetPKGExecPrefix' : GetPKGExecPrefix, + 'GetPKGIncludedir' : GetPKGIncludedir, + 'GetPKGLibdir' : GetPKGLibdir, + } + +def exists( env ): + return 1 + + +#!/usr/bin/python +# +# Copyright (C) 2007 Arnold Krille +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Taken from http://www.scons.org/wiki/UsingPkgConfig +# and heavily modified +# + +# +# Checks for pkg-config +# +def CheckForPKGConfig( context, version='0.0.0' ): + context.Message( "Checking for pkg-config (at least version %s)... " % version ) + ret = context.TryAction( "pkg-config --atleast-pkgconfig-version=%s" %version )[0] + context.Result( ret ) + return ret + +# +# Checks for the given package with an optional version-requirement +# +# The flags (which can be imported into the environment by env.MergeFlags(...) +# are exported as env['NAME_FLAGS'] where name is built by removing all +,-,. +# and upper-casing. +# +def CheckForPKG( context, name, version="" ): + name2 = name.replace("+","").replace(".","").replace("-","") + + if version == "": + context.Message( "Checking for %s... \t" % name ) + ret = context.TryAction( "pkg-config --exists '%s'" % name )[0] + else: + context.Message( "Checking for %s (%s or higher)... \t" % (name,version) ) + ret = context.TryAction( "pkg-config --atleast-version=%s '%s'" % (version,name) )[0] + + if ret: + context.env['%s_FLAGS' % name2.upper()] = context.env.ParseFlags("!pkg-config --cflags --libs %s" % name) + + context.Result( ret ) + return ret + +# +# Checks for the existance of the package and returns the packages flags. +# +# This should allow caching of the flags so that pkg-config is called only once. +# +def GetPKGFlags( context, name, version="" ): + import os + + if version == "": + context.Message( "Checking for %s... \t" % name ) + ret = context.TryAction( "pkg-config --exists '%s'" % name )[0] + else: + context.Message( "Checking for %s (%s or higher)... \t" % (name,version) ) + ret = context.TryAction( "pkg-config --atleast-version=%s '%s'" % (version,name) )[0] + + if not ret: + context.Result( ret ) + return ret + + out = os.popen2( "pkg-config --cflags --libs %s" % name )[1] + ret = out.read() + + context.Result( True ) + return ret + +def GetPKGPrefix( context, name ): + import os + + out = os.popen2( "pkg-config --variable=prefix %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting prefix... \t" ) + context.Result( True ) + return ret + +def GetPKGExecPrefix( context, name ): + import os + + out = os.popen2( "pkg-config --variable=exec_prefix %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting exec prefix... \t" ) + context.Result( True ) + return ret + +def GetPKGIncludedir( context, name ): + import os + + out = os.popen2( "pkg-config --variable=includedir %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting include dir... \t" ) + context.Result( True ) + return ret + +def GetPKGLibdir( context, name ): + import os + + out = os.popen2( "pkg-config --variable=libdir %s" % name )[1] + ret = out.read() + ret = ret.replace ( "\n", "" ) + context.Message( " getting lib dir... \t" ) + context.Result( True ) + return ret + +def generate( env, **kw ): + env['PKGCONFIG_TESTS' ] = { + 'CheckForPKGConfig' : CheckForPKGConfig, + 'CheckForPKG' : CheckForPKG, + 'GetPKGFlags' : GetPKGFlags, + 'GetPKGPrefix' : GetPKGPrefix, + 'GetPKGExecPrefix' : GetPKGExecPrefix, + 'GetPKGIncludedir' : GetPKGIncludedir, + 'GetPKGLibdir' : GetPKGLibdir, + } + +def exists( env ): + return 1 + + diff --git a/admin/scanreplace.py b/admin/scanreplace.py new file mode 100644 index 00000000..fb621392 --- /dev/null +++ b/admin/scanreplace.py @@ -0,0 +1,80 @@ +#!/usr/bin/python +# +# Copyright (C) 2007 Arnold Krille +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Taken from http://www.scons.org/wiki/ReplacementBuilder +# + +from string import Template + +def replace_action(target, source, env): + open( str(target[0]), 'w' ).write( Template( open( str(source[0]), 'r' ).read() ).safe_substitute( env ) ) + return 0 + +def replace_string(target, source, env): + return "building '%s' from '%s'" % ( str(target[0]), str(source[0]) ) + +def generate(env, **kw): + action = env.Action( replace_action, replace_string ) + env['BUILDERS']['ScanReplace'] = env.Builder( action=action, src_suffix='.in', single_source=True ) + +def exists(env): + return 1 + +#!/usr/bin/python +# +# Copyright (C) 2007 Arnold Krille +# +# This file originates from FFADO (www.ffado.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Taken from http://www.scons.org/wiki/ReplacementBuilder +# + +from string import Template + +def replace_action(target, source, env): + open( str(target[0]), 'w' ).write( Template( open( str(source[0]), 'r' ).read() ).safe_substitute( env ) ) + return 0 + +def replace_string(target, source, env): + return "building '%s' from '%s'" % ( str(target[0]), str(source[0]) ) + +def generate(env, **kw): + action = env.Action( replace_action, replace_string ) + env['BUILDERS']['ScanReplace'] = env.Builder( action=action, src_suffix='.in', single_source=True ) + +def exists(env): + return 1 + diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 0b243a32..f2144ffe 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -22,6 +22,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #pragma warning (disable : 4786) #endif +#include "config.h" + #include "JackDriverLoader.h" #include "JackError.h" #include diff --git a/common/JackGlobalsClient.cpp b/common/JackGlobalsClient.cpp index fc1bcf3b..2a336a64 100644 --- a/common/JackGlobalsClient.cpp +++ b/common/JackGlobalsClient.cpp @@ -42,14 +42,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifdef WIN32 #include "JackWinProcessSync.h" #include "JackWinNamedPipeClientChannel.h" -#include "JackWinEvent.h" +#include "JackWinEvent.h" #include "JackWinSemaphore.h" #include "JackWinThread.h" #endif // LINUX #ifdef __linux__ -#include "JackAlsaDriver.h" +#include "linux/alsa/JackAlsaDriver.h" #include "JackProcessSync.h" #include "JackSocketServerNotifyChannel.h" #include "JackSocketNotifyChannel.h" diff --git a/common/JackGlobalsServer.cpp b/common/JackGlobalsServer.cpp index 8d76a733..46f37f93 100644 --- a/common/JackGlobalsServer.cpp +++ b/common/JackGlobalsServer.cpp @@ -50,14 +50,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackWinNamedPipeNotifyChannel.h" #include "JackWinNamedPipeServerChannel.h" #include "JackWinNamedPipeClientChannel.h" -#include "JackWinEvent.h" +#include "JackWinEvent.h" #include "JackWinSemaphore.h" #include "JackWinThread.h" #endif // LINUX #ifdef __linux__ -#include "JackAlsaDriver.h" +#include "linux/alsa/JackAlsaDriver.h" #include "JackProcessSync.h" #include "JackSocketServerNotifyChannel.h" #include "JackSocketNotifyChannel.h" diff --git a/common/JackServerLaunch.cpp b/common/JackServerLaunch.cpp index b7d97521..cbfa35c0 100644 --- a/common/JackServerLaunch.cpp +++ b/common/JackServerLaunch.cpp @@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "config.h" + #include "JackChannel.h" #include "JackLibGlobals.h" #include "JackServerLaunch.h" diff --git a/linux/Makefile b/linux/Makefile index 98566863..5b4306a2 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -1,11 +1,11 @@ # Type "make" or "make all" to compile ALSA driver, and "make freebob" to compile FREEBOB driver. # Choose the installation location -prefix := /usr/local +prefix := /usr prefix := ${DESTDIR}${prefix} libdir := lib -subprojects := ../common ../common/jack ../tests ../example-clients alsa freebob +subprojects := ../common ../common/jack ../tests ../example-clients alsa freebob firewire sources := $(wildcard *.cpp) $(wildcard */*.cpp) $(wildcard ../common/*.cpp) $(wildcard ../tests/*.cpp) @@ -21,6 +21,8 @@ TARGET_LINUX_ALSA := jack_alsa.so TARGET_LINUX_FREEBOB := jack_freebob.so +TARGET_LINUX_FIREWIRE := jack_firewire.so + TARGET_LINUX_DUMMY := jack_dummy.so VPATH := $(subprojects) @@ -46,6 +48,8 @@ objects_linux_alsa := JackAlsaDriver.o memops.o generic_hw.o hdsp.o hammerfall.o objects_linux_freebob := JackFreebobDriver.o +objects_linux_firewire := JackFFADODriver.o + objects_linux_dummy := JackDummyDriver.o CFLAGS := -g -fPIC -DUSE_POSIX_SHM $(addprefix -I, $(subprojects)) $(CFLAGS) @@ -65,6 +69,10 @@ freebob : $(TARGET_LINUX_SERVER_LIB) $(TARGET_LINUX_CLIENT_LIB) $(TARGET_LINUX_W $(TARGET_LINUX_SERVER) $(TARGET_LINUX_ALSA) $(TARGET_LINUX_FREEBOB) $(TARGET_LINUX_DUMMY) \ synchroClient synchroServer synchroServerClient testSem jack_test inprocess jack_load jack_unload +firewire : $(TARGET_LINUX_SERVER_LIB) $(TARGET_LINUX_CLIENT_LIB) $(TARGET_LINUX_WRAPPER_LIB) \ + $(TARGET_LINUX_SERVER) $(TARGET_LINUX_ALSA) $(TARGET_LINUX_FIREWIRE) $(TARGET_LINUX_DUMMY) \ + synchroClient synchroServer synchroServerClient testSem jack_test + synchroClient: JackPosixSemaphore.o testSynchroClient.o JackPosixThread.o JackError.o JackFifo.o $(CXX) $(CXXFLAGS) JackPosixSemaphore.o testSynchroClient.o JackPosixThread.o JackError.o JackFifo.o $(LIB_LINUX) -o synchroClient @@ -107,6 +115,9 @@ $(TARGET_LINUX_ALSA) : $(objects_linux_alsa) $(TARGET_LINUX_FREEBOB) : $(objects_linux_freebob) $(CXX) $(CXXFLAGS) -shared $(objects_linux_freebob) $(LIB_LINUX) -lfreebob libjackdmp.so -o $(TARGET_LINUX_FREEBOB) +$(TARGET_LINUX_FIREWIRE) : $(objects_linux_firewire) + $(CXX) $(CXXFLAGS) -shared $(objects_linux_firewire) $(LIB_LINUX) -lffado libjackdmp.so -o $(TARGET_LINUX_FIREWIRE) + $(TARGET_LINUX_DUMMY) : $(objects_linux_dummy) $(CXX) $(CXXFLAGS) -shared $(objects_linux_dummy) $(LIB_LINUX) libjackdmp.so -o $(TARGET_LINUX_DUMMY) @@ -120,6 +131,7 @@ install: cp jack_alsa.so $(prefix)/$(libdir)/jackmp cp jack_dummy.so $(prefix)/$(libdir)/jackmp [ -f jack_freebob.so ] && cp jack_freebob.so $(prefix)/$(libdir)/jackmp || echo "freebob driver not installed" + [ -f jack_firewire.so ] && cp jack_firewire.so $(prefix)/$(libdir)/jackmp || echo "firewire driver not installed" cd $(prefix)/bin && [ -f jackd ] && mv -f jackd tmp_jackd || echo "jackd server not found, continue..." cd $(prefix)/$(libdir) && [ -f libjack.so.0.0.23 ] && mv -f libjack.so.0.0.23 tmp_libjack.so.0.0.23 || echo "libjack not found, continue..." cd $(prefix)/include && [ -d jack ] && mv -f jack tmp_jack || echo "jack headers not found, continue..." @@ -149,7 +161,7 @@ remove: clean : rm -f *.o - rm -f $(TARGET_LINUX_SERVER) $(TARGET_LINUX_SERVER_LIB) $(TARGET_LINUX_CLIENT_LIB) $(TARGET_LINUX_WRAPPER_LIB) $(TARGET_LINUX_ALSA) $(TARGET_LINUX_FREEBOB) $(TARGET_LINUX_DUMMY) \ + rm -f $(TARGET_LINUX_SERVER) $(TARGET_LINUX_SERVER_LIB) $(TARGET_LINUX_CLIENT_LIB) $(TARGET_LINUX_WRAPPER_LIB) $(TARGET_LINUX_ALSA) $(TARGET_LINUX_FREEBOB) $(TARGET_LINUX_FIREWIRE) $(TARGET_LINUX_DUMMY) \ synchroClient synchroServer synchroServerClient testSem jack_test jack_load jack_unload inprocess.so depend : #makedepend -w120 -Y -- $(CXXFLAGS) -- $(sources) diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index b09b8782..902b11f0 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -61,7 +61,7 @@ JackFreebobDriver::freebob_driver_read (freebob_driver_t * driver, jack_nframes_ printEnter(); // make sure all buffers have a valid buffer if not connected - for (int i = 0; i < driver->capture_nchannels; i++) { + for (unsigned int i = 0; i < driver->capture_nchannels; i++) { stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i); if (stream_type == freebob_stream_type_audio) { freebob_streaming_set_playback_stream_buffer(driver->dev, i, @@ -104,10 +104,7 @@ JackFreebobDriver::freebob_driver_read (freebob_driver_t * driver, jack_nframes_ int JackFreebobDriver::freebob_driver_write (freebob_driver_t * driver, jack_nframes_t nframes) { - channel_t chn; - JSList *node; jack_default_audio_sample_t* buf = NULL; - jack_port_t *port; freebob_streaming_stream_type stream_type; @@ -121,7 +118,7 @@ JackFreebobDriver::freebob_driver_write (freebob_driver_t * driver, jack_nframes assert(driver->dev); // make sure all buffers output silence if not connected - for (int i = 0; i < driver->playback_nchannels; i++) { + for (unsigned int i = 0; i < driver->playback_nchannels; i++) { stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i); if (stream_type == freebob_stream_type_audio) { freebob_streaming_set_playback_stream_buffer(driver->dev, i, @@ -736,7 +733,9 @@ int JackFreebobDriver::Attach() } else { printMessage ("Registering capture port %s", buf); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, + JACK_DEFAULT_AUDIO_TYPE, + (JackPortFlags)port_flags)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; } @@ -754,7 +753,7 @@ int JackFreebobDriver::Attach() driver->playback_nchannels = freebob_streaming_get_nb_playback_streams(driver->dev); driver->playback_nchannels_audio = 0; - for (int i = 0; i < driver->playback_nchannels; i++) { + for (unsigned int i = 0; i < driver->playback_nchannels; i++) { freebob_streaming_get_playback_stream_name(driver->dev, i, portname, sizeof(portname) - 1); snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl->fName, portname); @@ -763,7 +762,9 @@ int JackFreebobDriver::Attach() printMessage ("Don't register playback port %s", buf); } else { printMessage ("Registering playback port %s", buf); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, + JACK_DEFAULT_AUDIO_TYPE, + (JackPortFlags)port_flags)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; } @@ -888,17 +889,7 @@ int JackFreebobDriver::Read() int JackFreebobDriver::Write() { printEnter(); - - //JackLog("write\n"); int res = freebob_driver_write((freebob_driver_t *)fDriver, fEngineControl->fBufferSize); - jack_time_t write_time = GetMicroSeconds(); - - /* - if (write_time > (fLastWaitUst - fDelayedUst) + fEngineControl->fPeriodUsecs) { - JackLog("FreeBoB write XRun \n"); - NotifyXRun(write_time); - } - */ printExit(); return res; } @@ -1052,8 +1043,6 @@ extern "C" } Jack::JackDriverClientInterface* driver_initialize(Jack::JackEngine* engine, Jack::JackSynchro** table, const JSList* params) { - jack_driver_t *driver; - unsigned int port = 0; unsigned int node_id = -1; int nbitems;