libffado-2.4.7/ 0000755 0001750 0000144 00000000000 14340644632 012670 5 ustar jwoithe users libffado-2.4.7/SConstruct 0000644 0001750 0000144 00000115333 14340644414 014726 0 ustar jwoithe users # -*- coding: utf-8 -*-
#
# Copyright (C) 2007, 2008, 2010 Arnold Krille
# Copyright (C) 2007, 2008 Pieter Palmers
# Copyright (C) 2008, 2012 Jonathan Woithe
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
from __future__ import print_function
FFADO_API_VERSION = "9"
FFADO_VERSION="2.4.7"
from subprocess import Popen, PIPE, check_output
import os
import re
import sys
from string import Template
import distutils.sysconfig
if not os.path.isdir( "cache" ):
os.makedirs( "cache" )
opts = Variables( "cache/options.cache" )
opts.AddVariables(
BoolVariable( "DEBUG", """\
Build with \"-g -Wall\" rather than \"-O2\", and include extra debugging
checks in the code.""", True ),
BoolVariable( "DEBUG_MESSAGES", "Enable support for debug messages", True ),
BoolVariable( "PROFILE", "Build with symbols, warnings and other profiling info", False ),
PathVariable( "PREFIX", "The prefix where ffado will be installed to.", "/usr/local", PathVariable.PathAccept ),
PathVariable( "BINDIR", "Overwrite the directory where apps are installed to.", "$PREFIX/bin", PathVariable.PathAccept ),
PathVariable( "LIBDIR", "Overwrite the directory where libs are installed to.", "$PREFIX/lib", PathVariable.PathAccept ),
PathVariable( "INCLUDEDIR", "Overwrite the directory where headers are installed to.", "$PREFIX/include", PathVariable.PathAccept ),
PathVariable( "SHAREDIR", "Overwrite the directory where misc shared files are installed to.", "$PREFIX/share/libffado", PathVariable.PathAccept ),
PathVariable( "LIBDATADIR", "Location for architecture-dependent data.", "$LIBDIR/libffado", PathVariable.PathAccept ),
PathVariable( "MANDIR", "Overwrite the directory where manpages are installed", "$PREFIX/man", PathVariable.PathAccept ),
PathVariable( "PYPKGDIR", "The directory where the python modules get installed.",
distutils.sysconfig.get_python_lib( prefix="$PREFIX" ), PathVariable.PathAccept ),
PathVariable( "UDEVDIR", "Overwrite the directory where udev rules are installed to.", "/lib/udev/rules.d/", PathVariable.PathAccept ),
BoolVariable( "ENABLE_BEBOB", "Enable/Disable support for the BeBoB platform.", True ),
BoolVariable( "ENABLE_FIREWORKS", "Enable/Disable support for the ECHO Audio FireWorks platform.", True ),
BoolVariable( "ENABLE_OXFORD", "Enable/Disable support for the Oxford Semiconductor FW platform.", True ),
BoolVariable( "ENABLE_MOTU", "Enable/Disable support for the MOTU platform.", True ),
BoolVariable( "ENABLE_DICE", "Enable/Disable support for the TCAT DICE platform.", True ),
BoolVariable( "ENABLE_METRIC_HALO", "Enable/Disable support for the Metric Halo platform.", False ),
BoolVariable( "ENABLE_RME", "Enable/Disable support for the RME platform.", True ),
BoolVariable( "ENABLE_DIGIDESIGN", "Enable/Disable support for Digidesign interfaces.", False ),
BoolVariable( "ENABLE_BOUNCE", "Enable/Disable the BOUNCE device.", False ),
BoolVariable( "ENABLE_GENERICAVC", """\
Enable/Disable the the generic avc part (mainly used by apple).
Note that disabling this option might be overwritten by other devices needing
this code.""", False ),
BoolVariable( "ENABLE_ALL", "Enable/Disable support for all devices.", False ),
BoolVariable( "SERIALIZE_USE_EXPAT", "Use libexpat for XML serialization.", False ),
EnumVariable( "BUILD_DOC", "Build API documentation", 'none', allowed_values=('all', 'user', 'none'), ignorecase=2),
EnumVariable( "BUILD_MIXER", "Build the ffado-mixer", 'auto', allowed_values=('auto', 'true', 'false'), ignorecase=2),
BoolVariable( "BUILD_TESTS", """\
Build the tests in their directory. As some contain quite some functionality,
this is on by default.
If you just want to use ffado with jack without the tools, you can disable this.\
""", True ),
BoolVariable( "BUILD_STATIC_TOOLS", "Build a statically linked version of the FFADO tools.", False ),
EnumVariable('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'powerpc64', 'none' ), ignorecase=2),
BoolVariable( "ENABLE_OPTIMIZATIONS", "Enable optimizations and the use of processor specific extentions (MMX/SSE/...).", False ),
BoolVariable( "DETECT_USERSPACE_ENV", "Try to detect the user space environment and add necessary 32/64 bit machine flags.", True ),
BoolVariable( "PEDANTIC", "Enable -Werror and more pedantic options during compile.", False ),
BoolVariable( "CUSTOM_ENV", "Respect CC, CXX, CFLAGS, CXXFLAGS and LDFLAGS.\nOnly meant for distributors and gentoo-users who want to over-optimize their build.\n Using this is not supported by the ffado-devs!", False ),
( "COMPILE_FLAGS", "Deprecated (use CFLAGS and CXXFLAGS with CUSTOM_ENV=True instead). Add additional flags to the environment.\nOnly meant for distributors and gentoo-users who want to over-optimize their build.\n Using this is not supported by the ffado-devs!" ),
EnumVariable( "ENABLE_SETBUFFERSIZE_API_VER", "Report API version at runtime which includes support for dynamic buffer resizing (requires recent jack).", 'auto', allowed_values=('auto', 'true', 'false', 'force'), ignorecase=2),
("PYTHON_INTERPRETER", "Python interpreter to be used by FFADO installation.", "/usr/bin/python"),
)
## Load the builders in config
buildenv=os.environ
env = Environment( tools=['default','scanreplace','pyuic','pyuic4','pyuic5','dbus','doxygen','pkgconfig'], toolpath=['admin'], ENV = buildenv, options=opts )
custom_flags = False
if 'COMPILE_FLAGS' in env and len(env['COMPILE_FLAGS']) > 0:
print("The COMPILE_FLAGS option is deprecated. Use CFLAGS and CXXFLAGS with CUSTOM_ENV=True instead")
custom_flags = True
env.MergeFlags(env['COMPILE_FLAGS'])
if env['CUSTOM_ENV']:
custom_flags = True
# Honour the user choice of compiler (if any).
if 'CC' in os.environ and len(os.environ['CC']) > 0:
env['CC'] = os.environ['CC']
if 'CXX' in os.environ and len(os.environ['CXX']) > 0:
env['CXX'] = os.environ['CXX']
# Honour the user supplied flags (if any), but notify the user that this is not supported.
if 'CFLAGS' in os.environ and len(os.environ['CFLAGS']) > 0:
env.Append(CFLAGS = str(os.environ['CFLAGS'].replace('\"', '')))
if 'CXXFLAGS' in os.environ and len(os.environ['CXXFLAGS']) > 0:
env.Append(CXXFLAGS = str(os.environ['CXXFLAGS'].replace('\"', '')))
if 'LDFLAGS' in os.environ and len(os.environ['LDFLAGS']) > 0:
env.Append(LINKFLAGS = str(os.environ['LDFLAGS'].replace('\"', '')))
if custom_flags:
print('''
* Usage of additional flags is not supported by the ffado-devs.
* Use at own risk!
*
* Flags in use:
* CC = %s
* CXX = %s
* CFLAGS = %s
* CXXFLAGS = %s
* LDFLAGS = %s
''' % (env['CC'], env['CXX'], env['CFLAGS'], env['CXXFLAGS'], env['LINKFLAGS']))
Help( """
For building ffado 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"
Note that this is a development version! Don't complain if its not working!
See www.ffado.org for stable releases.
""" )
Help( opts.GenerateHelpText( env ) )
# make sure the necessary dirs exist
if not os.path.isdir( "cache" ):
os.makedirs( "cache" )
if not os.path.isdir( 'cache/objects' ):
os.makedirs( 'cache/objects' )
CacheDir( 'cache/objects' )
opts.Save( 'cache/options.cache', env )
def ConfigGuess( context ):
context.Message( "Trying to find the system triple: " )
ret = check_output(("/bin/sh", "admin/config.guess")).rstrip()
context.Result( ret )
return ret.decode()
def CheckForApp( context, app ):
context.Message( "Checking whether '" + app + "' executes " )
ret = context.TryAction( app )
context.Result( ret[0] )
return ret[0]
def CheckForPyModule( context, module ):
context.Message( "Checking for the python module '" + module + "' " )
ret = context.TryAction( "$PYTHON_INTERPRETER $SOURCE", "import %s" % module, ".py" )
context.Result( ret[0] )
return ret[0]
def CompilerCheck( context ):
context.Message( "Checking for a working C-compiler " )
ret = context.TryRun( """
#include
int main() {
printf( "Hello World!" );
return 0;
}""", '.c' )[0]
context.Result( ret )
if ret == 0:
return False;
context.Message( "Checking for a working C++-compiler " )
ret = context.TryRun( """
#include
int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}""", ".cpp" )[0]
context.Result( ret )
return ret
def CheckPKG(context, name):
context.Message( 'Checking for %s... ' % name )
ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0]
context.Result( ret )
return ret
tests = {
"ConfigGuess" : ConfigGuess,
"CheckForApp" : CheckForApp,
"CheckForPyModule": CheckForPyModule,
"CompilerCheck" : CompilerCheck,
"CheckPKG" : CheckPKG,
}
tests.update( env['PKGCONFIG_TESTS'] )
tests.update( env['PYUIC_TESTS'] )
tests.update( env['PYUIC4_TESTS'] )
conf = Configure( env,
custom_tests = tests,
conf_dir = "cache/",
log_file = 'cache/config.log' )
version_re = re.compile(r'^(\d+)\.(\d+)\.(\d+)')
def CheckJackdVer():
print('Checking jackd version...', end='')
popen = Popen(("which", 'jackd'), stdout=PIPE, stderr=PIPE)
stdout, stderr = popen.communicate()
assert popen.returncode in (0, 1), "which returned a unexpected status"
if popen.returncode == 1:
print("not installed")
return None
jackd = stdout.decode ().rstrip ()
ret = check_output ((jackd, '--version')).decode() .rstrip ()
ret = ret.split ('\n') [-1]; # Last line.
ret = ret.split () [2]; # Third field.
if not version_re.match (ret):
print("failed to parse version")
return None
print (ret)
# Trim off any "rc" (release candidate) components from the end of the
# version string
ret = ret.split ('rc')[0]
ret = ret.split ('.')
ret = map (int, ret)
return tuple (ret)
if env['SERIALIZE_USE_EXPAT']:
env['SERIALIZE_USE_EXPAT']=1
else:
env['SERIALIZE_USE_EXPAT']=0
if env['ENABLE_BOUNCE'] or env['ENABLE_ALL']:
env['REQUIRE_LIBAVC']=1
else:
env['REQUIRE_LIBAVC']=0
if not env.GetOption('clean'):
#
# Check for working gcc and g++ compilers and their environment.
#
if not conf.CompilerCheck():
print("\nIt seems as if your system isn't even able to compile any C-/C++-programs. Probably you don't have gcc and g++ installed. Compiling a package from source without a working compiler is very hard to do, please install the needed packages.\nHint: on *ubuntu you need both gcc- and g++-packages installed, easiest solution is to install build-essential which depends on gcc and g++.")
Exit( 1 )
# Check for pkg-config before using pkg-config to check for other dependencies.
if not conf.CheckForPKGConfig():
print("\nThe program 'pkg-config' could not be found.\nEither you have to install the corresponding package first or make sure that PATH points to the right directions.")
Exit( 1 )
#
# The following checks are for headers and libs and packages we need.
#
allpresent = 1;
# for cache-serialization.
if env['SERIALIZE_USE_EXPAT']:
allpresent &= conf.CheckHeader( "expat.h" )
allpresent &= conf.CheckLib( 'expat', 'XML_ExpatVersion', '#include ' )
pkgs = {
'libraw1394' : '2.0.5',
'libiec61883' : '1.1.0',
'libconfig++' : '0'
}
if env['REQUIRE_LIBAVC']:
pkgs['libavc1394'] = '0.5.3'
if not env['SERIALIZE_USE_EXPAT']:
if conf.CheckPKG('libxml++-3.0'):
pkgs['libxml++-3.0'] = '3.0.0'
if not('libxml++-3.0' in pkgs):
pkgs['libxml++-2.6'] = '2.13.0'
# Provide a way for users to compile newer libffado which will work
# against older jack installations which will not accept the new API
# version reported at runtime.
have_jack = conf.CheckPKG('jack')
if have_jack:
good_jack1 = conf.CheckPKG('jack < 1.9.0') and conf.CheckPKG('jack >= 0.121.4')
good_jack2 = conf.CheckPKG('jack >= 1.9.9')
else:
jackd_ver = CheckJackdVer()
if jackd_ver:
# If jackd is unknown to pkg-config but is never-the-less
# runnable, use the version number reported by it. This means
# users don't have to have jack development files present on
# their system for this to work.
have_jack = jackd_ver >= (0, 0, 0)
good_jack1 = jackd_ver < (1, 9, 0) and jackd_ver >= (0, 121, 4)
good_jack2 = jackd_ver >= (1, 9, 9)
if env['ENABLE_SETBUFFERSIZE_API_VER'] == 'auto':
if not(have_jack):
print("""
No Jack Audio Connection Kit (JACK) installed: assuming a FFADO
setbuffersize-compatible version will be used.
""")
elif not(good_jack1 or good_jack2):
FFADO_API_VERSION="8"
print("""
Installed Jack Audio Connection Kit (JACK) jack does not support FFADO
setbuffersize API: will report earlier API version at runtime. Consider
upgrading to jack1 >=0.122.0 or jack2 >=1.9.9 at some point, and then
recompile ffado to gain access to this added feature.
""")
else:
print("Installed Jack Audio Connection Kit (JACK) supports FFADO setbuffersize API")
elif env['ENABLE_SETBUFFERSIZE_API_VER'] == 'true':
if (have_jack and not(good_jack1) and not(good_jack2)):
print("""
SetBufferSize API version is enabled but no suitable version of Jack Audio
Connection Kit (JACK) has been found. The resulting FFADO would cause your
jackd to abort with "incompatible FFADO version". Please upgrade to
jack1 >=0.122.0 or jack2 >=1.9.9, or set ENABLE_SETBUFFERSIZE_API_VER to "auto"
or "false".
""")
# Although it's not strictly an error, in almost every case that
# this occurs the user will want to know about it and fix the
# problem, so we exit so they're guaranteed of seeing the above
# message.
Exit( 1 )
else:
print("Will report SetBufferSize API version at runtime")
elif env['ENABLE_SETBUFFERSIZE_API_VER'] == 'force':
print("Will report SetBufferSize API version at runtime")
else:
FFADO_API_VERSION="8"
print("Will not report SetBufferSize API version at runtime")
for pkg in pkgs:
name2 = pkg.replace("+","").replace(".","").replace("-","").upper()
env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] )
#print('%s_FLAGS' % name2)
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 for each of the lines saying "no".
(Remember to also install the *-devel packages!)
And remember to remove the cache with "rm -Rf .sconsign.dblite cache" so the
results above get rechecked.
""")
Exit( 1 )
# libxml++-2.6 requires a c++11 compiler as of version 2.39.1. The
# gnu++11 standard seems to work both with these later libxml++ versions
# and ffado itself, although a significant number of warnings are
# produced. Add the necessary option to CXXFLAGS if required.
if conf.CheckPKG('libxml++-2.6 >= 2.39.1'):
env.Append(CXXFLAGS = '-std=gnu++11')
if conf.CheckPKG('libxml++-3.0 >= 3.0.0'):
env.Append(CXXFLAGS = '-std=gnu++11')
# Check for C99 lrint() and lrintf() functions used to convert from
# float to integer more efficiently via float_cast.h. If not
# present the standard slower methods will be used instead. This
# might not be the best way of testing for these but it's the only
# way which seems to work properly. CheckFunc() fails due to
# argument count problems.
if 'CFLAGS' in env:
oldcf = env['CFLAGS']
else:
oldcf = ""
env.Append(CFLAGS = '-std=c99')
if conf.CheckLibWithHeader( "m", "math.h", "c", "lrint(3.2);" ):
HAVE_LRINT = 1
else:
HAVE_LRINT = 0
if conf.CheckLibWithHeader( "m", "math.h", "c", "lrintf(3.2);" ):
HAVE_LRINTF = 1
else:
HAVE_LRINTF = 0
env['HAVE_LRINT'] = HAVE_LRINT;
env['HAVE_LRINTF'] = HAVE_LRINTF;
env.Replace(CFLAGS=oldcf)
#
# Optional checks follow:
#
# PyQT checks
if env['BUILD_MIXER'] != 'false':
if ( conf.CheckForApp( 'which pyuic4' ) \
and conf.CheckForPyModule( 'PyQt4' ) \
and conf.CheckForPyModule( 'dbus.mainloop.qt' )) \
or ( conf.CheckForApp( 'which pyuic5' ) \
and conf.CheckForPyModule( 'PyQt5' ) \
and conf.CheckForPyModule( 'dbus.mainloop.pyqt5' )):
env['BUILD_MIXER'] = 'true'
elif not env.GetOption('clean'):
if env['BUILD_MIXER'] == 'auto':
env['BUILD_MIXER'] = 'false'
print("""
The prerequisites ('pyuic4'/'pyuic5' and the python-modules 'dbus' and
'PyQt4'/'PyQt5', the packages could be named like dbus-python and PyQt) to
build the mixer were not found. Therefore the qt mixer will not be installed.""")
else: # env['BUILD_MIXER'] == 'true'
print("""
The prerequisites ('pyuic4'/'pyuic5' and the python-modules 'dbus' and
'PyQt4'/'PyQt5', the packages could be named like dbus-python and PyQt) to
build the mixer were not found, but BUILD_MIXER was requested.""")
Exit( 1 )
env['XDG_TOOLS'] = False
if env['BUILD_MIXER'] == 'true':
if conf.CheckForApp( 'xdg-desktop-menu --help' ) and conf.CheckForApp( 'xdg-icon-resource --help' ):
env['XDG_TOOLS'] = True
else:
print("""
I couldn't find the 'xdg-desktop-menu' and 'xdg-icon-resource' programs. These
are needed to add the fancy entry for the mixer to your menu, but you can still
start it by executing "ffado-mixer".""")
#
# Optional pkg-config
#
pkgs = {
'alsa': '0',
'dbus-1': '1.0',
'dbus-c++-1' : '0',
}
for pkg in pkgs:
name2 = pkg.replace("+","").replace(".","").replace("-","").upper()
env['%s_FLAGS' % name2] = conf.GetPKGFlags( pkg, pkgs[pkg] )
if not env['DBUS1_FLAGS'] or not env['DBUSC1_FLAGS'] or not conf.CheckForApp('which dbusxx-xml2cpp'):
env['DBUS1_FLAGS'] = b""
env['DBUSC1_FLAGS'] = b""
print("""
One of the dbus-headers, the dbus-c++-headers and/or the application
'dbusxx-xml2cpp' where not found. The dbus-server for ffado will therefore not
be built.
""")
else:
# Get the directory where dbus stores the service-files
env['dbus_service_dir'] = conf.GetPKGVariable( 'dbus-1', 'session_bus_services_dir' ).strip()
# this is required to indicate that the DBUS version we use has support
# for platform dependent threading init functions
# this is true for DBUS >= 0.96 or so. Since we require >= 1.0 it is
# always true
env['DBUS1_FLAGS'] += b" -DDBUS_HAS_THREADS_INIT_DEFAULT"
# The controlserver-glue.h file generated by dbusxx-xml2cpp generates
# a large number of instances where call.reader()'s return value is
# stored (in ri) but not used. This generates a compiler warning which
# we can do nothing about. Therefore when compiling dbus-related
# code, suppress the "set but not used" warning.
env['DBUS1_FLAGS'] += b" -Wno-unused-but-set-variable"
config_guess = conf.ConfigGuess()
conf.Finish()
if env['DEBUG']:
print("Doing a debug build")
env.MergeFlags( "-Wall -g -DDEBUG" )
env['DEBUG_MESSAGES'] = True
elif not custom_flags:
# Only merge -O2 to flags if the user has not specified custom flags.
env.MergeFlags( "-O2" )
if env['DEBUG_MESSAGES']:
env.MergeFlags( "-DDEBUG_MESSAGES" )
if env['PROFILE']:
print("Doing a PROFILE build")
env.MergeFlags( "-Wall -g" )
if env['PEDANTIC']:
env.MergeFlags( "-Werror" )
if env['ENABLE_ALL']:
env['ENABLE_BEBOB'] = True
env['ENABLE_FIREWORKS'] = True
env['ENABLE_OXFORD'] = True
env['ENABLE_MOTU'] = True
env['ENABLE_DICE'] = True
env['ENABLE_METRIC_HALO'] = True
env['ENABLE_RME'] = True
env['ENABLE_DIGIDESIGN'] = True
env['ENABLE_BOUNCE'] = True
env['BUILD_STATIC_LIB'] = False
if env['BUILD_STATIC_TOOLS']:
print("Building static versions of the tools...")
env['BUILD_STATIC_LIB'] = True
env['build_base']="#/"
#
# Get the DESTDIR (if wanted) from the commandline
#
env.destdir = ARGUMENTS.get( 'DESTDIR', "" )
#
# Uppercase variables are for usage in code, lowercase versions for usage in
# scons-files for installing.
#
env['BINDIR'] = Template( env['BINDIR'] ).safe_substitute( env )
env['LIBDIR'] = Template( env['LIBDIR'] ).safe_substitute( env )
env['INCLUDEDIR'] = Template( env['INCLUDEDIR'] ).safe_substitute( env )
env['SHAREDIR'] = Template( env['SHAREDIR'] ).safe_substitute( env )
env['LIBDATADIR'] = Template( env['LIBDATADIR'] ).safe_substitute( env )
env['UDEVDIR'] = Template( env['UDEVDIR'] ).safe_substitute( env )
env['PYTHON_INTERPRETER'] = Template( env['PYTHON_INTERPRETER'] ).safe_substitute( env )
env['prefix'] = Template( env.destdir + env['PREFIX'] ).safe_substitute( env )
env['bindir'] = Template( env.destdir + env['BINDIR'] ).safe_substitute( env )
env['libdir'] = Template( env.destdir + env['LIBDIR'] ).safe_substitute( env )
env['includedir'] = Template( env.destdir + env['INCLUDEDIR'] ).safe_substitute( env )
env['sharedir'] = Template( env.destdir + env['SHAREDIR'] ).safe_substitute( env )
env['libdatadir'] = Template( env.destdir + env['LIBDATADIR'] ).safe_substitute( env )
env['mandir'] = Template( env.destdir + env['MANDIR'] ).safe_substitute( env )
env['pypkgdir'] = Template( env.destdir + env['PYPKGDIR'] ).safe_substitute( env )
env['udevdir'] = Template( env.destdir + env['UDEVDIR'] ).safe_substitute( env )
env['PYPKGDIR'] = Template( env['PYPKGDIR'] ).safe_substitute( env )
env['metainfodir'] = Template( env.destdir + "/usr/share/metainfo" ).safe_substitute( env )
env.Command( target=env['sharedir'], source="", action=Mkdir( env['sharedir'] ) )
env.Alias( "install", env['libdir'] )
env.Alias( "install", env['includedir'] )
env.Alias( "install", env['sharedir'] )
env.Alias( "install", env['libdatadir'] )
env.Alias( "install", env['bindir'] )
env.Alias( "install", env['mandir'] )
if env['BUILD_MIXER'] == 'true':
env.Alias( "install", env['pypkgdir'] )
env.Alias( "install", env['metainfodir'] )
#
# shamelessly copied from the Ardour scons file
#
opt_flags = []
env['USE_SSE'] = 0
# guess at the platform, used to define compiler flags
config_cpu = 0
config_arch = 1
config_kernel = 2
config_os = 3
config = config_guess.split ("-")
needs_fPIC = False
#=== Begin Revised CXXFLAGS =========================================
def cpuinfo_kv():
"""generator which reads lines from Linux /proc/cpuinfo and splits them
into key:value tokens and yields (key, value) tuple.
"""
with open('/proc/cpuinfo', 'r') as f:
for line in f:
line = line.strip()
if line:
k,v = line.split(':', 1)
yield (k.strip(), v.strip())
class CpuInfo (object):
"""Collects information about the CPU, mainly from /proc/cpuinfo
"""
def __init__(self):
self.sysname, self.hostname, self.release, self.version, self.machine = os.uname()
# general CPU architecture
self.is_x86 = self.machine in ('i686', 'x86_64') or \
re.match("i[3-5]86", self.machine) or False
self.is_powerpc = self.machine in ('ppc64', 'ppc', 'powerpc', 'powerpc64', 'ppc64le')
#!!! probably not comprehensive
self.is_mips = self.machine == 'mips'
#!!! not a comprehensive list. uname -m on one android phone reports 'armv71'
# I have no other arm devices I can check
self.is_arm = self.machine in ('armv71', )
self.cpu_count = 0
if self.is_x86:
self.cpu_info_x86()
elif self.is_powerpc:
self.cpu_info_ppc()
elif self.is_mips:
self.cpu_info_mips()
# 64-bit (x86_64/AMD64/Intel64)
# Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)
self.is_64bit = (self.is_x86 and 'lm' in self.x86_flags) or \
(self.is_powerpc and \
('970' in self.ppc_type or 'power8' in self.ppc_type.lower()))
# Hardware virtualization capable: vmx (Intel), svm (AMD, Hygon)
self.has_hwvirt = self.is_x86 and (
((self.is_amd or self.is_hygon) and
'svm' in self.x86_flags) or
(self.is_intel and 'vmx' in self.x86_flags))
# Physical Address Extensions (support for more than 4GB of RAM)
self.has_pae = self.is_x86 and 'pae' in self.x86_flags
def cpu_info_x86(self):
"parse /proc/cpuinfo for x86 kernels"
for k,v in cpuinfo_kv():
if k == 'processor':
self.cpu_count += 1
if self.cpu_count > 1:
# assume all CPUs are identical features, no need to
# parse all of them
continue
elif k == 'vendor_id': # AuthenticAMD, HygonGenuine, GenuineIntel
self.vendor_id = v
self.is_amd = v == 'AuthenticAMD'
self.is_hygon = v == 'HygonGenuine'
self.is_intel = v == 'GenuineIntel'
elif k == 'flags':
self.x86_flags = v.split()
elif k == 'model name':
self.model_name = v
elif k == 'cpu family':
self.cpu_family = v
elif k == 'model':
self.model = v
def cpu_info_ppc(self):
"parse /proc/cpuinfo for PowerPC kernels"
# http://en.wikipedia.org/wiki/List_of_PowerPC_processors
# PowerPC 7xx family
# PowerPC 740 and 750, 233-366 MHz
# 745/755, 300–466 MHz
# PowerPC G4 series
# 7400/7410 350 - 550 MHz, uses AltiVec, a SIMD extension of the original PPC specs
# 7450 micro-architecture family up to 1.5 GHz and 256 kB on-chip L2 cache and improved Altivec
# 7447/7457 micro-architecture family up to 1.8 GHz with 512 kB on-chip L2 cache
# 7448 micro-architecture family (1.5 GHz) in 90 nm with 1MB L2 cache and slightly
# improved AltiVec (out of order instructions).
# 8640/8641/8640D/8641D with one or two e600 (Formerly known as G4) cores, 1MB L2 cache
# PowerPC G5 series
# 970 (2003), 64-bit, derived from POWER4, enhanced with VMX, 512 kB L2 cache, 1.4 – 2 GHz
# 970FX (2004), manufactured at 90 nm, 1.8 - 2.7 GHz
# 970GX (2006), manufactured at 90 nm, 1MB L2 cache/core, 1.2 - 2.5 GHz
# 970MP (2005), dual core, 1 MB L2 cache/core, 1.6 - 2.5 GHz
for k,v in cpuinfo_kv():
if k == 'processor':
self.cpu_count += 1
elif k == 'cpu':
self.is_altivec_supported = 'altivec' in v
if ',' in v:
ppc_type, x = v.split(',')
else:
ppc_type = v
self.ppc_type = ppc_type.strip()
# older kernels might not have a 'processor' line
if self.cpu_count == 0:
self.cpu_count += 1
def cpu_info_mips(self):
"parse /proc/cpuinfo for MIPS kernels"
for k,v in cpuinfo_kv():
if k == 'processor':
self.cpu_count += 1
elif k == 'cpu model':
self.mips_cpu_model = v
def is_userspace_32bit(cpuinfo):
"""Even if `uname -m` reports a 64-bit architecture, userspace could still
be 32-bit, such as Debian on powerpc64. This function tries to figure out
if userspace is 32-bit, i.e. we might need to pass '-m32' or '-m64' to gcc.
"""
if not cpuinfo.is_64bit:
return True
# note that having a 64-bit CPU means nothing for these purposes. You could
# run a completely 32-bit system on a 64-bit capable CPU.
answer = None
# If setting DIST_TARGET to i686 on a 64-bit CPU to facilitate
# compilation of a multilib environment, force 32-bit.
if env['DIST_TARGET'] == 'i686':
return True
# Debian ppc64 returns machine 'ppc64', but userspace might be 32-bit
# We'll make an educated guess by examining a known executable
exe = '/bin/mount'
if os.path.isfile(exe):
#print('Found %s' % exe)
if os.path.islink(exe):
real_exe = os.path.join(os.path.dirname(exe), os.readlink(exe))
#print('%s is a symlink to %s' % (exe, real_exe))
else:
real_exe = exe
# presumably if a person is running this script, they should have
# a gcc toolchain installed...
x = check_output(('objdump', '-Wi', real_exe)).decode()
# should emit a line that looks like this:
# /bin/mount: file format elf32-i386
# or like this:
# /bin/mount: file format elf64-x86-64
# or like this:
# /bin/mount: file format elf32-powerpc
for line in x.split('\n'):
line = line.strip()
if line.startswith(real_exe):
x, fmt = line.rsplit(None, 1)
answer = 'elf32' in fmt
break
else:
print('!!! Not found %s' % exe)
return answer
def cc_flags_x86(cpuinfo, enable_optimizations):
"""add certain gcc -m flags based on CPU features
"""
# See http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/i386-and-x86_002d64-Options.html
cc_opts = []
if cpuinfo.machine == 'i586':
cc_opts.append('-march=i586')
elif cpuinfo.machine == 'i686':
cc_opts.append('-march=i686')
if 'mmx' in cpuinfo.x86_flags:
cc_opts.append('-mmmx')
# map from proc/cpuinfo flags to gcc options
opt_flags = [
('sse', ('-mfpmath=sse', '-msse')),
('sse2', '-msse2'),
('ssse3', '-mssse3'),
('sse4', '-msse4'),
('sse4_1', '-msse4.1'),
('sse4_2', '-msse4.2'),
('sse4a', '-msse4a'),
('3dnow', '-m3dnow'),
]
if enable_optimizations:
for flag, gccopt in opt_flags:
if flag in cpuinfo.x86_flags:
if isinstance(gccopt, (tuple, list)):
cc_opts.extend(gccopt)
else:
cc_opts.append(gccopt)
return cc_opts
def cc_flags_powerpc(cpuinfo, enable_optimizations):
"""add certain gcc -m flags based on CPU model
"""
cc_opts = []
if cpuinfo.is_altivec_supported:
cc_opts.append ('-maltivec')
cc_opts.append ('-mabi=altivec')
if re.match('74[0145][0578]A?', cpuinfo.ppc_type) is not None:
cc_opts.append ('-mcpu=7400')
cc_opts.append ('-mtune=7400')
elif re.match('750', cpuinfo.ppc_type) is not None:
cc_opts.append ('-mcpu=750')
cc_opts.append ('-mtune=750')
elif re.match('PPC970', cpuinfo.ppc_type) is not None:
cc_opts.append ('-mcpu=970')
cc_opts.append ('-mtune=970')
elif re.match('Cell Broadband Engine', cpuinfo.ppc_type) is not None:
cc_opts.append('-mcpu=cell')
cc_opts.append('-mtune=cell')
return cc_opts
#=== End Revised CXXFLAGS =========================================
# Autodetect
if env['DIST_TARGET'] == 'auto':
if re.search ("x86_64", config[config_cpu]) is not None:
env['DIST_TARGET'] = 'x86_64'
elif re.search("i[0-5]86", config[config_cpu]) is not None:
env['DIST_TARGET'] = 'i386'
elif re.search("i686", config[config_cpu]) is not None:
env['DIST_TARGET'] = 'i686'
elif re.search("powerpc64", config[config_cpu]) is not None:
env['DIST_TARGET'] = 'powerpc64'
elif re.search("powerpc", config[config_cpu]) is not None:
env['DIST_TARGET'] = 'powerpc'
else:
env['DIST_TARGET'] = config[config_cpu]
print("Detected DIST_TARGET = " + env['DIST_TARGET'])
#=== Begin Revised CXXFLAGS =========================================
# comment on DIST_TARGET up top implies it can be used for cross-compiling
# but that's not true because even if it is not 'auto' the original
# script still reads /proc/cpuinfo to determine gcc arch flags.
# This script does the same as the original. Needs to be fixed someday.
cpuinfo = CpuInfo()
if cpuinfo.is_x86:
opt_flags.extend(cc_flags_x86(cpuinfo, env['ENABLE_OPTIMIZATIONS']))
if cpuinfo.is_powerpc:
opt_flags.extend(cc_flags_powerpc(cpuinfo, env['ENABLE_OPTIMIZATIONS']))
if '-msse' in opt_flags:
env['USE_SSE'] = 1
if '-msse2' in opt_flags:
env['USE_SSE2'] = 1
if env['DETECT_USERSPACE_ENV']:
m32 = is_userspace_32bit(cpuinfo)
print('User space is %s' % (m32 and '32-bit' or '64-bit'))
if cpuinfo.is_powerpc:
if m32:
print("Doing a 32-bit PowerPC build for %s CPU" % cpuinfo.ppc_type)
machineflags = { 'CXXFLAGS' : ['-m32'] }
else:
print("Doing a 64-bit PowerPC build for %s CPU" % cpuinfo.ppc_type)
machineflags = { 'CXXFLAGS' : ['-m64'] }
env.MergeFlags( machineflags )
elif cpuinfo.is_x86:
if m32:
print("Doing a 32-bit %s build for %s" % (cpuinfo.machine, cpuinfo.model_name))
if cpuinfo.machine == 'x86_64':
machineflags = { 'CXXFLAGS' : ['-mx32'] }
else:
machineflags = { 'CXXFLAGS' : ['-m32'] }
else:
print("Doing a 64-bit %s build for %s" % (cpuinfo.machine, cpuinfo.model_name))
machineflags = { 'CXXFLAGS' : ['-m64'] }
needs_fPIC = True
env.MergeFlags( machineflags )
#=== End Revised CXXFLAGS =========================================
if needs_fPIC or ( 'COMPILE_FLAGS' in env and '-fPIC' in env['COMPILE_FLAGS'] ):
env.MergeFlags( "-fPIC" )
# end of processor-specific section
if env['ENABLE_OPTIMIZATIONS']:
opt_flags.extend (["-fomit-frame-pointer","-ffast-math","-funroll-loops"])
env.MergeFlags( opt_flags )
print("Doing an optimized build...")
try:
env['REVISION'] = check_output(('svnversion', '.',)).decode().rstrip()
except:
env['REVISION'] = ''
# This may be as simple as '89' or as complex as '4123:4184M'.
# We'll just use the last bit.
env['REVISION'] = env['REVISION'].split(':')[-1]
# Assume an unversioned directory indicates a release.
if env['REVISION'].startswith ('Unversioned'):
env['REVISION'] = ''
# try to circumvent localized versions
if env['REVISION'].startswith ('export'):
env['REVISION'] = ''
# avoid the 1.999.41- type of version for exported versions
if env['REVISION'] != '':
env['REVISIONSTRING'] = '-' + env['REVISION']
else:
env['REVISIONSTRING'] = ''
env['FFADO_API_VERSION'] = FFADO_API_VERSION
env['PACKAGE'] = "libffado"
env['VERSION'] = FFADO_VERSION
env['LIBVERSION'] = "1.0.0"
env['CONFIGDIR'] = "~/.ffado"
env['CACHEDIR'] = "~/.ffado"
env['USER_CONFIG_FILE'] = env['CONFIGDIR'] + "/configuration"
env['SYSTEM_CONFIG_FILE'] = env['SHAREDIR'] + "/configuration"
env['REGISTRATION_URL'] = "http://ffado.org/deviceregistration/register.php?action=register"
#
# To have the top_srcdir as the doxygen-script is used from auto*
#
env['top_srcdir'] = env.Dir( "." ).abspath
#
# Start building
#
env.ScanReplace( "config.h.in" )
env.ScanReplace( "config_debug.h.in" )
env.ScanReplace( "version.h.in" )
# ensure that the config.h is updated
env.Depends( "config.h", "SConstruct" )
env.Depends( "config.h", 'cache/options.cache' )
# update version.h whenever the version or SVN revision changes
env.Depends( "version.h", env.Value(env['REVISION']))
env.Depends( "version.h", env.Value(env['VERSION']))
env.Depends( "libffado.pc", "SConstruct" )
pkgconfig = env.ScanReplace( "libffado.pc.in" )
env.Install( env['libdir'] + '/pkgconfig', pkgconfig )
env.Install( env['sharedir'], 'configuration' )
subdirs=['src','libffado','support','doc']
if env['BUILD_TESTS']:
subdirs.append('tests')
env.SConscript( dirs=subdirs, exports="env" )
if 'debian' in COMMAND_LINE_TARGETS:
env.SConscript("deb/SConscript", exports="env")
# By default only src is built but all is cleaned
if not env.GetOption('clean'):
Default( 'src' )
Default( 'support' )
if env['BUILD_TESTS']:
Default( 'tests' )
if env['BUILD_DOC'] != 'none':
Default( 'doc' )
env.Install( env['metainfodir'], "support/xdg/ffado-mixer.appdata.xml" )
#
# Deal with the DESTDIR vs. xdg-tools conflict (which is basicely that the
# xdg-tools can't deal with DESTDIR, so the packagers have to deal with this
# their own :-/
#
if len(env.destdir) > 0:
if not len( ARGUMENTS.get( "WILL_DEAL_WITH_XDG_MYSELF", "" ) ) > 0:
print("""
WARNING!
You are using the (packagers) option DESTDIR to install this package to a
different place than the real prefix. As the xdg-tools can't cope with
that, the .desktop-files are not installed by this build, you have to
deal with them your own.
(And you have to look into the SConstruct to learn how to disable this
message.)
""")
else:
def CleanAction( action ):
if env.GetOption( "clean" ):
env.Execute( action )
if env['BUILD_MIXER'] == 'true' and env['XDG_TOOLS']:
if not env.GetOption("clean"):
action = "install"
else:
action = "uninstall"
mixerdesktopaction = env.Action( "-xdg-desktop-menu %s support/xdg/ffado.org-ffadomixer.desktop" % action )
mixericonaction = env.Action( "-xdg-icon-resource %s --size 64 --novendor --context apps support/xdg/hi64-apps-ffado.png ffado" % action )
env.Command( "__xdgstuff1", None, mixerdesktopaction )
env.Command( "__xdgstuff2", None, mixericonaction )
env.Alias( "install", ["__xdgstuff1", "__xdgstuff2" ] )
CleanAction( mixerdesktopaction )
CleanAction( mixericonaction )
#
# Create a tags-file for easier emacs/vim-source-browsing
# I don't know if the dependency is right...
#
findcommand = "find . \( -path \"*.h\" -o -path \"*.cpp\" -o -path \"*.c\" \) \! -path \"*.svn*\" \! -path \"./doc*\" \! -path \"./cache*\""
env.Command( "tags", "", findcommand + " |xargs ctags" )
env.Command( "TAGS", "", findcommand + " |xargs etags" )
env.AlwaysBuild( "tags", "TAGS" )
if 'NoCache' in dir(env):
env.NoCache( "tags", "TAGS" )
# Another convinience target
if env.GetOption( "clean" ):
env.Execute( "rm cache/objects -Rf" )
#
# vim: ts=4 sw=4 et
libffado-2.4.7/admin/ 0000755 0001750 0000144 00000000000 14340644625 013762 5 ustar jwoithe users libffado-2.4.7/admin/config.guess 0000644 0001750 0000144 00000141202 14340644323 016272 0 ustar jwoithe users #! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2022-05-25'
# This file 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 .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
#
# Please send patches to .
# The "shellcheck disable" line above the timestamp inhibits complaints
# about features and limitations of the classic Bourne shell that were
# superseded or lifted in POSIX. However, this script identifies a wide
# variety of pre-POSIX systems that do not have POSIX shells at all, and
# even some reasonably current systems (Solaris 10 as case-in-point) still
# have a pre-POSIX /bin/sh.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
# Just in case it came from the environment.
GUESS=
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
tmp=
# shellcheck disable=SC2172
trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
set_cc_for_build() {
# prevent multiple calls if $tmp is already set
test "$tmp" && return 0
: "${TMPDIR=/tmp}"
# shellcheck disable=SC2039,SC3028
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
dummy=$tmp/dummy
case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
,,) echo "int x;" > "$dummy.c"
for driver in cc gcc c89 c99 ; do
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
CC_FOR_BUILD=$driver
break
fi
done
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac
}
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
LIBC=unknown
set_cc_for_build
cat <<-EOF > "$dummy.c"
#include
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#elif defined(__GLIBC__)
LIBC=gnu
#else
#include
/* First heuristic to detect musl libc. */
#ifdef __DEFINED_va_list
LIBC=musl
#endif
#endif
EOF
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
eval "$cc_set_libc"
# Second heuristic to detect musl libc.
if [ "$LIBC" = unknown ] &&
command -v ldd >/dev/null &&
ldd --version 2>&1 | grep -q ^musl; then
LIBC=musl
fi
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
if [ "$LIBC" = unknown ]; then
LIBC=gnu
fi
;;
esac
# Note: order is significant - the case branches are not exclusive.
case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
/usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
echo unknown)`
case $UNAME_MACHINE_ARCH in
aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
machine=${arch}${endian}-unknown
;;
*) machine=$UNAME_MACHINE_ARCH-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
case $UNAME_MACHINE_ARCH in
earm*)
os=netbsdelf
;;
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# Determine ABI tags.
case $UNAME_MACHINE_ARCH in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case $UNAME_VERSION in
Debian*)
release='-gnu'
;;
*)
release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
GUESS=$machine-${os}${release}${abi-}
;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
;;
*:SecBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
;;
*:LibertyBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
;;
*:MidnightBSD:*:*)
GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
;;
*:ekkoBSD:*:*)
GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
;;
*:SolidBSD:*:*)
GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
;;
*:OS108:*:*)
GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
;;
macppc:MirBSD:*:*)
GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
;;
*:MirBSD:*:*)
GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
;;
*:Sortix:*:*)
GUESS=$UNAME_MACHINE-unknown-sortix
;;
*:Twizzler:*:*)
GUESS=$UNAME_MACHINE-unknown-twizzler
;;
*:Redox:*:*)
GUESS=$UNAME_MACHINE-unknown-redox
;;
mips:OSF1:*.*)
GUESS=mips-dec-osf1
;;
alpha:OSF1:*:*)
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
trap '' 0
case $UNAME_RELEASE in
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case $ALPHA_CPU_TYPE in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)")
UNAME_MACHINE=alpha ;;
"EV5 (21164)")
UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)")
UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)")
UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)")
UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)")
UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)")
UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)")
UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)")
UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)")
UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)")
UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)")
UNAME_MACHINE=alphaev79 ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
;;
Amiga*:UNIX_System_V:4.0:*)
GUESS=m68k-unknown-sysv4
;;
*:[Aa]miga[Oo][Ss]:*:*)
GUESS=$UNAME_MACHINE-unknown-amigaos
;;
*:[Mm]orph[Oo][Ss]:*:*)
GUESS=$UNAME_MACHINE-unknown-morphos
;;
*:OS/390:*:*)
GUESS=i370-ibm-openedition
;;
*:z/VM:*:*)
GUESS=s390-ibm-zvmoe
;;
*:OS400:*:*)
GUESS=powerpc-ibm-os400
;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
GUESS=arm-acorn-riscix$UNAME_RELEASE
;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
GUESS=arm-unknown-riscos
;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
GUESS=hppa1.1-hitachi-hiuxmpp
;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
case `(/bin/universe) 2>/dev/null` in
att) GUESS=pyramid-pyramid-sysv3 ;;
*) GUESS=pyramid-pyramid-bsd ;;
esac
;;
NILE*:*:*:dcosx)
GUESS=pyramid-pyramid-svr4
;;
DRS?6000:unix:4.0:6*)
GUESS=sparc-icl-nx6
;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) GUESS=sparc-icl-nx7 ;;
esac
;;
s390x:SunOS:*:*)
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
;;
sun4H:SunOS:5.*:*)
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
GUESS=sparc-hal-solaris2$SUN_REL
;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
GUESS=sparc-sun-solaris2$SUN_REL
;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
GUESS=i386-pc-auroraux$UNAME_RELEASE
;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
set_cc_for_build
SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH=x86_64
fi
fi
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
GUESS=sparc-sun-solaris3$SUN_REL
;;
sun4*:SunOS:*:*)
case `/usr/bin/arch -k` in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
GUESS=sparc-sun-sunos$SUN_REL
;;
sun3*:SunOS:*:*)
GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
case `/bin/arch` in
sun3)
GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun4)
GUESS=sparc-sun-sunos$UNAME_RELEASE
;;
esac
;;
aushp:SunOS:*:*)
GUESS=sparc-auspex-sunos$UNAME_RELEASE
;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
GUESS=m68k-atari-mint$UNAME_RELEASE
;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
GUESS=m68k-atari-mint$UNAME_RELEASE
;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
GUESS=m68k-atari-mint$UNAME_RELEASE
;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
GUESS=m68k-milan-mint$UNAME_RELEASE
;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
GUESS=m68k-hades-mint$UNAME_RELEASE
;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
GUESS=m68k-unknown-mint$UNAME_RELEASE
;;
m68k:machten:*:*)
GUESS=m68k-apple-machten$UNAME_RELEASE
;;
powerpc:machten:*:*)
GUESS=powerpc-apple-machten$UNAME_RELEASE
;;
RISC*:Mach:*:*)
GUESS=mips-dec-mach_bsd4.3
;;
RISC*:ULTRIX:*:*)
GUESS=mips-dec-ultrix$UNAME_RELEASE
;;
VAX*:ULTRIX*:*:*)
GUESS=vax-dec-ultrix$UNAME_RELEASE
;;
2020:CLIX:*:* | 2430:CLIX:*:*)
GUESS=clipper-intergraph-clix$UNAME_RELEASE
;;
mips:*:*:UMIPS | mips:*:*:RISCos)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#ifdef __cplusplus
#include /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
GUESS=mips-mips-riscos$UNAME_RELEASE
;;
Motorola:PowerMAX_OS:*:*)
GUESS=powerpc-motorola-powermax
;;
Motorola:*:4.3:PL8-*)
GUESS=powerpc-harris-powermax
;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
GUESS=powerpc-harris-powermax
;;
Night_Hawk:Power_UNIX:*:*)
GUESS=powerpc-harris-powerunix
;;
m88k:CX/UX:7*:*)
GUESS=m88k-harris-cxux7
;;
m88k:*:4*:R4*)
GUESS=m88k-motorola-sysv4
;;
m88k:*:3*:R3*)
GUESS=m88k-motorola-sysv3
;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
test "$TARGET_BINARY_INTERFACE"x = x
then
GUESS=m88k-dg-dgux$UNAME_RELEASE
else
GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
fi
else
GUESS=i586-dg-dgux$UNAME_RELEASE
fi
;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
GUESS=m88k-dolphin-sysv3
;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
GUESS=m88k-motorola-sysv3
;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
GUESS=m88k-tektronix-sysv3
;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
GUESS=m68k-tektronix-bsd
;;
*:IRIX*:*:*)
IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
GUESS=mips-sgi-irix$IRIX_REL
;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id
;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
GUESS=i386-ibm-aix
;;
ia64:AIX:*:*)
if test -x /usr/bin/oslevel ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#include
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
GUESS=$SYSTEM_NAME
else
GUESS=rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
GUESS=rs6000-ibm-aix3.2.4
else
GUESS=rs6000-ibm-aix3.2
fi
;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if test -x /usr/bin/lslpp ; then
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
GUESS=$IBM_ARCH-ibm-aix$IBM_REV
;;
*:AIX:*:*)
GUESS=rs6000-ibm-aix
;;
ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
GUESS=romp-ibm-bsd4.4
;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to
;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
GUESS=rs6000-bull-bosx
;;
DPX/2?00:B.O.S.:*:*)
GUESS=m68k-bull-sysv3
;;
9000/[34]??:4.3bsd:1.*:*)
GUESS=m68k-hp-bsd
;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
GUESS=m68k-hp-bsd4.4
;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
case $UNAME_MACHINE in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if test -x /usr/bin/getconf; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case $sc_cpu_version in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case $sc_kernel_bits in
32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
if test "$HP_ARCH" = ""; then
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#define _HPUX_SOURCE
#include
#include
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if test "$HP_ARCH" = hppa2.0w
then
set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
# generating 64-bit code. GNU and HP use different nomenclature:
#
# $ CC_FOR_BUILD=cc ./config.guess
# => hppa2.0w-hp-hpux11.23
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
HP_ARCH=hppa2.0w
else
HP_ARCH=hppa64
fi
fi
GUESS=$HP_ARCH-hp-hpux$HPUX_REV
;;
ia64:HP-UX:*:*)
HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
GUESS=ia64-hp-hpux$HPUX_REV
;;
3050*:HI-UX:*:*)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#include
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
GUESS=unknown-hitachi-hiuxwe2
;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
GUESS=hppa1.1-hp-bsd
;;
9000/8??:4.3bsd:*:*)
GUESS=hppa1.0-hp-bsd
;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
GUESS=hppa1.0-hp-mpeix
;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
GUESS=hppa1.1-hp-osf
;;
hp8??:OSF1:*:*)
GUESS=hppa1.0-hp-osf
;;
i*86:OSF1:*:*)
if test -x /usr/sbin/sysversion ; then
GUESS=$UNAME_MACHINE-unknown-osf1mk
else
GUESS=$UNAME_MACHINE-unknown-osf1
fi
;;
parisc*:Lites*:*:*)
GUESS=hppa1.1-hp-lites
;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
GUESS=c1-convex-bsd
;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
GUESS=c34-convex-bsd
;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
GUESS=c38-convex-bsd
;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
GUESS=c4-convex-bsd
;;
CRAY*Y-MP:*:*:*)
CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
GUESS=ymp-cray-unicos$CRAY_REL
;;
CRAY*[A-Z]90:*:*:*)
echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
GUESS=t90-cray-unicos$CRAY_REL
;;
CRAY*T3E:*:*:*)
CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
GUESS=alphaev5-cray-unicosmk$CRAY_REL
;;
CRAY*SV1:*:*:*)
CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
GUESS=sv1-cray-unicos$CRAY_REL
;;
*:UNICOS/mp:*:*)
CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
GUESS=craynv-cray-unicosmp$CRAY_REL
;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
;;
sparc*:BSD/OS:*:*)
GUESS=sparc-unknown-bsdi$UNAME_RELEASE
;;
*:BSD/OS:*:*)
GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
;;
arm:FreeBSD:*:*)
UNAME_PROCESSOR=`uname -p`
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
else
FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
fi
;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
;;
i*:CYGWIN*:*)
GUESS=$UNAME_MACHINE-pc-cygwin
;;
*:MINGW64*:*)
GUESS=$UNAME_MACHINE-pc-mingw64
;;
*:MINGW*:*)
GUESS=$UNAME_MACHINE-pc-mingw32
;;
*:MSYS*:*)
GUESS=$UNAME_MACHINE-pc-msys
;;
i*:PW*:*)
GUESS=$UNAME_MACHINE-pc-pw32
;;
*:SerenityOS:*:*)
GUESS=$UNAME_MACHINE-pc-serenity
;;
*:Interix*:*)
case $UNAME_MACHINE in
x86)
GUESS=i586-pc-interix$UNAME_RELEASE
;;
authenticamd | genuineintel | EM64T)
GUESS=x86_64-unknown-interix$UNAME_RELEASE
;;
IA64)
GUESS=ia64-unknown-interix$UNAME_RELEASE
;;
esac ;;
i*:UWIN*:*)
GUESS=$UNAME_MACHINE-pc-uwin
;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
GUESS=x86_64-pc-cygwin
;;
prep*:SunOS:5.*:*)
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
GUESS=powerpcle-unknown-solaris2$SUN_REL
;;
*:GNU:*:*)
# the GNU system
GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
;;
*:Minix:*:*)
GUESS=$UNAME_MACHINE-unknown-minix
;;
aarch64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
arm*:Linux:*:*)
set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
else
GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
fi
fi
;;
avr32*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
cris:Linux:*:*)
GUESS=$UNAME_MACHINE-axis-linux-$LIBC
;;
crisv32:Linux:*:*)
GUESS=$UNAME_MACHINE-axis-linux-$LIBC
;;
e2k:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
frv:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
hexagon:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
i*86:Linux:*:*)
GUESS=$UNAME_MACHINE-pc-linux-$LIBC
;;
ia64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
k1om:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
m32r*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
m68*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
mips:Linux:*:* | mips64:Linux:*:*)
set_cc_for_build
IS_GLIBC=0
test x"${LIBC}" = xgnu && IS_GLIBC=1
sed 's/^ //' << EOF > "$dummy.c"
#undef CPU
#undef mips
#undef mipsel
#undef mips64
#undef mips64el
#if ${IS_GLIBC} && defined(_ABI64)
LIBCABI=gnuabi64
#else
#if ${IS_GLIBC} && defined(_ABIN32)
LIBCABI=gnuabin32
#else
LIBCABI=${LIBC}
#endif
#endif
#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
CPU=mipsisa64r6
#else
#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
CPU=mipsisa32r6
#else
#if defined(__mips64)
CPU=mips64
#else
CPU=mips
#endif
#endif
#endif
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
MIPS_ENDIAN=el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
MIPS_ENDIAN=
#else
MIPS_ENDIAN=
#endif
#endif
EOF
cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
eval "$cc_set_vars"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
openrisc*:Linux:*:*)
GUESS=or1k-unknown-linux-$LIBC
;;
or32:Linux:*:* | or1k*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
padre:Linux:*:*)
GUESS=sparc-unknown-linux-$LIBC
;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
GUESS=hppa64-unknown-linux-$LIBC
;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
*) GUESS=hppa-unknown-linux-$LIBC ;;
esac
;;
ppc64:Linux:*:*)
GUESS=powerpc64-unknown-linux-$LIBC
;;
ppc:Linux:*:*)
GUESS=powerpc-unknown-linux-$LIBC
;;
ppc64le:Linux:*:*)
GUESS=powerpc64le-unknown-linux-$LIBC
;;
ppcle:Linux:*:*)
GUESS=powerpcle-unknown-linux-$LIBC
;;
riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
s390:Linux:*:* | s390x:Linux:*:*)
GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
;;
sh64*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
sh*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
sparc:Linux:*:* | sparc64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
tile*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
vax:Linux:*:*)
GUESS=$UNAME_MACHINE-dec-linux-$LIBC
;;
x86_64:Linux:*:*)
set_cc_for_build
CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
ABI=64
sed 's/^ //' << EOF > "$dummy.c"
#ifdef __i386__
ABI=x86
#else
#ifdef __ILP32__
ABI=x32
#endif
#endif
EOF
cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
eval "$cc_set_abi"
case $ABI in
x86) CPU=i686 ;;
x32) LIBCABI=${LIBC}x32 ;;
esac
fi
GUESS=$CPU-pc-linux-$LIBCABI
;;
xtensa*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
GUESS=i386-sequent-sysv4
;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
GUESS=$UNAME_MACHINE-pc-os2-emx
;;
i*86:XTS-300:*:STOP)
GUESS=$UNAME_MACHINE-unknown-stop
;;
i*86:atheos:*:*)
GUESS=$UNAME_MACHINE-unknown-atheos
;;
i*86:syllable:*:*)
GUESS=$UNAME_MACHINE-pc-syllable
;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
GUESS=i386-unknown-lynxos$UNAME_RELEASE
;;
i*86:*DOS:*:*)
GUESS=$UNAME_MACHINE-pc-msdosdjgpp
;;
i*86:*:4.*:*)
UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
else
GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
fi
;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
else
GUESS=$UNAME_MACHINE-pc-sysv32
fi
;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
GUESS=i586-pc-msdosdjgpp
;;
Intel:Mach:3*:*)
GUESS=i386-pc-mach3
;;
paragon:*:*:*)
GUESS=i860-intel-osf1
;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4
fi
;;
mini*:CTIX:SYS*5:*)
# "miniframe"
GUESS=m68010-convergent-sysv
;;
mc68k:UNIX:SYSTEM5:3.51m)
GUESS=m68k-convergent-sysv
;;
M680?0:D-NIX:5.3:*)
GUESS=m68k-diab-dnix
;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
GUESS=m68k-unknown-lynxos$UNAME_RELEASE
;;
mc68030:UNIX_System_V:4.*:*)
GUESS=m68k-atari-sysv4
;;
TSUNAMI:LynxOS:2.*:*)
GUESS=sparc-unknown-lynxos$UNAME_RELEASE
;;
rs6000:LynxOS:2.*:*)
GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
;;
SM[BE]S:UNIX_SV:*:*)
GUESS=mips-dde-sysv$UNAME_RELEASE
;;
RM*:ReliantUNIX-*:*:*)
GUESS=mips-sni-sysv4
;;
RM*:SINIX-*:*:*)
GUESS=mips-sni-sysv4
;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
GUESS=$UNAME_MACHINE-sni-sysv4
else
GUESS=ns32k-sni-sysv
fi
;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says
GUESS=i586-unisys-sysv4
;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes .
# How about differentiating between stratus architectures? -djm
GUESS=hppa1.1-stratus-sysv4
;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
GUESS=i860-stratus-sysv4
;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
GUESS=$UNAME_MACHINE-stratus-vos
;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
GUESS=hppa1.1-stratus-vos
;;
mc68*:A/UX:*:*)
GUESS=m68k-apple-aux$UNAME_RELEASE
;;
news*:NEWS-OS:6*:*)
GUESS=mips-sony-newsos6
;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if test -d /usr/nec; then
GUESS=mips-nec-sysv$UNAME_RELEASE
else
GUESS=mips-unknown-sysv$UNAME_RELEASE
fi
;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
GUESS=powerpc-be-beos
;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
GUESS=powerpc-apple-beos
;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
GUESS=i586-pc-beos
;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
GUESS=i586-pc-haiku
;;
ppc:Haiku:*:*) # Haiku running on Apple PowerPC
GUESS=powerpc-apple-haiku
;;
*:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
GUESS=$UNAME_MACHINE-unknown-haiku
;;
SX-4:SUPER-UX:*:*)
GUESS=sx4-nec-superux$UNAME_RELEASE
;;
SX-5:SUPER-UX:*:*)
GUESS=sx5-nec-superux$UNAME_RELEASE
;;
SX-6:SUPER-UX:*:*)
GUESS=sx6-nec-superux$UNAME_RELEASE
;;
SX-7:SUPER-UX:*:*)
GUESS=sx7-nec-superux$UNAME_RELEASE
;;
SX-8:SUPER-UX:*:*)
GUESS=sx8-nec-superux$UNAME_RELEASE
;;
SX-8R:SUPER-UX:*:*)
GUESS=sx8r-nec-superux$UNAME_RELEASE
;;
SX-ACE:SUPER-UX:*:*)
GUESS=sxace-nec-superux$UNAME_RELEASE
;;
Power*:Rhapsody:*:*)
GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
;;
*:Rhapsody:*:*)
GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
;;
arm64:Darwin:*:*)
GUESS=aarch64-apple-darwin$UNAME_RELEASE
;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p`
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
if command -v xcode-select > /dev/null 2> /dev/null && \
! xcode-select --print-path > /dev/null 2> /dev/null ; then
# Avoid executing cc if there is no toolchain installed as
# cc will be a stub that puts up a graphical alert
# prompting the user to install developer tools.
CC_FOR_BUILD=no_compiler_found
else
set_cc_for_build
fi
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_PPC >/dev/null
then
UNAME_PROCESSOR=powerpc
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# uname -m returns i386 or x86_64
UNAME_PROCESSOR=$UNAME_MACHINE
fi
GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
;;
*:QNX:*:4*)
GUESS=i386-pc-qnx
;;
NEO-*:NONSTOP_KERNEL:*:*)
GUESS=neo-tandem-nsk$UNAME_RELEASE
;;
NSE-*:NONSTOP_KERNEL:*:*)
GUESS=nse-tandem-nsk$UNAME_RELEASE
;;
NSR-*:NONSTOP_KERNEL:*:*)
GUESS=nsr-tandem-nsk$UNAME_RELEASE
;;
NSV-*:NONSTOP_KERNEL:*:*)
GUESS=nsv-tandem-nsk$UNAME_RELEASE
;;
NSX-*:NONSTOP_KERNEL:*:*)
GUESS=nsx-tandem-nsk$UNAME_RELEASE
;;
*:NonStop-UX:*:*)
GUESS=mips-compaq-nonstopux
;;
BS2000:POSIX*:*:*)
GUESS=bs2000-siemens-sysv
;;
DS/*:UNIX_System_V:*:*)
GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
if test "${cputype-}" = 386; then
UNAME_MACHINE=i386
elif test "x${cputype-}" != x; then
UNAME_MACHINE=$cputype
fi
GUESS=$UNAME_MACHINE-unknown-plan9
;;
*:TOPS-10:*:*)
GUESS=pdp10-unknown-tops10
;;
*:TENEX:*:*)
GUESS=pdp10-unknown-tenex
;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
GUESS=pdp10-dec-tops20
;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
GUESS=pdp10-xkl-tops20
;;
*:TOPS-20:*:*)
GUESS=pdp10-unknown-tops20
;;
*:ITS:*:*)
GUESS=pdp10-unknown-its
;;
SEI:*:*:SEIUX)
GUESS=mips-sei-seiux$UNAME_RELEASE
;;
*:DragonFly:*:*)
DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case $UNAME_MACHINE in
A*) GUESS=alpha-dec-vms ;;
I*) GUESS=ia64-dec-vms ;;
V*) GUESS=vax-dec-vms ;;
esac ;;
*:XENIX:*:SysV)
GUESS=i386-pc-xenix
;;
i*86:skyos:*:*)
SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
;;
i*86:rdos:*:*)
GUESS=$UNAME_MACHINE-pc-rdos
;;
i*86:Fiwix:*:*)
GUESS=$UNAME_MACHINE-pc-fiwix
;;
*:AROS:*:*)
GUESS=$UNAME_MACHINE-unknown-aros
;;
x86_64:VMkernel:*:*)
GUESS=$UNAME_MACHINE-unknown-esx
;;
amd64:Isilon\ OneFS:*:*)
GUESS=x86_64-unknown-onefs
;;
*:Unleashed:*:*)
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
;;
esac
# Do we have a guess based on uname results?
if test "x$GUESS" != x; then
echo "$GUESS"
exit
fi
# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <
#include
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#include
#if defined(_SIZE_T_) || defined(SIGLOST)
#include
#endif
#endif
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
#if !defined (ultrix)
#include
#if defined (BSD)
#if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
#else
#if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
#else
printf ("vax-dec-bsd\n"); exit (0);
#endif
#endif
#else
printf ("vax-dec-bsd\n"); exit (0);
#endif
#else
#if defined(_SIZE_T_) || defined(SIGLOST)
struct utsname un;
uname (&un);
printf ("vax-dec-ultrix%s\n", un.release); exit (0);
#else
printf ("vax-dec-ultrix\n"); exit (0);
#endif
#endif
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#if defined(_SIZE_T_) || defined(SIGLOST)
struct utsname *un;
uname (&un);
printf ("mips-dec-ultrix%s\n", un.release); exit (0);
#else
printf ("mips-dec-ultrix\n"); exit (0);
#endif
#endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
echo "$0: unable to guess system type" >&2
case $UNAME_MACHINE:$UNAME_SYSTEM in
mips:Linux | mips64:Linux)
# If we got here on MIPS GNU/Linux, output extra information.
cat >&2 <&2 <&2 </dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
UNAME_SYSTEM = "$UNAME_SYSTEM"
UNAME_VERSION = "$UNAME_VERSION"
EOF
fi
exit 1
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
libffado-2.4.7/admin/dbus.py 0000644 0001750 0000144 00000002740 14206145246 015270 0 ustar jwoithe users #!/usr/bin/python
#
# Copyright (C) 2007-2008 Arnold Krille
# Copyright (C) 2007-2008 Pieter Palmers
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
#
# xml translator
#
def dbusxx_xml2cpp_adaptor_action( target, source, env ):
env.Execute( "dbusxx-xml2cpp %s --adaptor=%s" % ( source[0], target[0] ) )
return 0
def dbusxx_xml2cpp_proxy_action( target, source, env ):
env.Execute( "dbusxx-xml2cpp %s --proxy=%s" % ( source[0], target[0] ) )
return 0
def generate( env, **kw ):
env['BUILDERS']['Xml2Cpp_Adaptor'] = env.Builder(action = dbusxx_xml2cpp_adaptor_action,
suffix = '.h', src_suffix = '.xml')
env['BUILDERS']['Xml2Cpp_Proxy'] = env.Builder(action = dbusxx_xml2cpp_proxy_action,
suffix = '.h', src_suffix = '.xml', single_source=True )
def exists( env ):
return 1
libffado-2.4.7/admin/doxygen.py 0000644 0001750 0000144 00000015431 14206145246 016011 0 ustar jwoithe users #!/usr/bin/python
#
# Copyright (C) 2007-2008 Arnold Krille
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, 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
from functools import reduce
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.decode(), 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 key in data:
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
to_pop = []
for (k, v) in data.items():
if len(v) == 0:
# data.pop(k) # Shouldn't modify dictionary while looping
to_pop.append(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]
for k in to_pop:
data.pop(k)
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")
libffado-2.4.7/admin/pkgconfig.py 0000644 0001750 0000144 00000006661 14206145246 016310 0 ustar jwoithe users #!/usr/bin/python
#
# Copyright (C) 2007-2008 Arnold Krille
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
#
# Taken from http://www.scons.org/wiki/UsingPkgConfig
# and heavily modified
#
import subprocess
#
# 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 = subprocess.Popen(['pkg-config', '--cflags', '--libs', name], stdout=subprocess.PIPE)
ret = out.stdout.read()
context.Result( True )
return ret
#
# Checks for the existance of the package and returns the value of the specified variable.
#
def GetPKGVariable( context, name, variable ):
import os
context.Message( "Checking for variable %s in package %s... \t" % (variable,name) )
ret = context.TryAction( "pkg-config --exists '%s'" % name )[0]
if not ret:
context.Result( ret )
return ret
out = subprocess.Popen(['pkg-config', '--variable=%s' % variable, name], stdout=subprocess.PIPE)
ret = out.stdout.read()
context.Result( True )
return ret
def generate( env, **kw ):
env['PKGCONFIG_TESTS' ] = { 'CheckForPKGConfig' : CheckForPKGConfig, 'CheckForPKG' : CheckForPKG, 'GetPKGFlags' : GetPKGFlags, 'GetPKGVariable' : GetPKGVariable }
def exists( env ):
return 1
libffado-2.4.7/admin/pyuic.py 0000644 0001750 0000144 00000002762 14206145246 015470 0 ustar jwoithe users #!/usr/bin/python
#
# Copyright (C) 2007-2008 Arnold Krille
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
import imp
def pyuic_action( target, source, env ):
env.Execute( "pyuic " + str( source[0] ) + " > " + str( target[0] ) )
return 0
def pyuic_string( target, source, env ):
return "building '%s' from '%s'" % ( str(target[0]), str( source[0] ) )
def PyQtCheck( context ):
context.Message( "Checking for pyuic (by checking for the python module pyqtconfig) " )
ret = True
try:
imp.find_module( "pyqtconfig" )
except ImportError:
ret = False
context.Result( ret )
return ret
def generate( env, **kw ):
env['BUILDERS']['PyUIC'] = env.Builder( action=pyuic_action, src_suffix=".ui", single_source=True )
env['PYUIC_TESTS'] = { "PyQtCheck" : PyQtCheck }
def exists( env ):
return 1
libffado-2.4.7/admin/pyuic4.py 0000644 0001750 0000144 00000002774 14206145246 015557 0 ustar jwoithe users #!/usr/bin/python
#
# Copyright (C) 2007-2008 Arnold Krille
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
import imp
def pyuic4_action( target, source, env ):
env.Execute( "pyuic4 " + str( source[0] ) + " > " + str( target[0] ) )
return 0
def pyuic4_string( target, source, env ):
return "building '%s' from '%s'" % ( str(target[0]), str( source[0] ) )
def PyQt4Check( context ):
context.Message( "Checking for pyuic4 (by checking for the python module pyqtconfig) " )
ret = True
try:
imp.find_module( "pyqtconfig" )
except ImportError:
ret = False
context.Result( ret )
return ret
def generate( env, **kw ):
env['BUILDERS']['PyUIC4'] = env.Builder( action=pyuic4_action, src_suffix=".ui", single_source=True )
env['PYUIC4_TESTS'] = { "PyQt4Check" : PyQt4Check }
def exists( env ):
return 1
libffado-2.4.7/admin/pyuic5.py 0000644 0001750 0000144 00000003041 14206145246 015544 0 ustar jwoithe users #!/usr/bin/python
#
# Copyright (C) 2007-2008 Arnold Krille
# Copyright (C) 2017 Jonathan Woithe
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
import imp
def pyuic5_action( target, source, env ):
env.Execute( "pyuic5 " + str( source[0] ) + " > " + str( target[0] ) )
return 0
def pyuic5_string( target, source, env ):
return "building '%s' from '%s'" % ( str(target[0]), str( source[0] ) )
def PyQt5Check( context ):
context.Message( "Checking for pyuic5 (by checking for the python module pyqtconfig) " )
ret = True
try:
imp.find_module( "pyqtconfig" )
except ImportError:
ret = False
context.Result( ret )
return ret
def generate( env, **kw ):
env['BUILDERS']['PyUIC5'] = env.Builder( action=pyuic5_action, src_suffix=".ui", single_source=True )
env['PYUIC5_TESTS'] = { "PyQt5Check" : PyQt5Check }
def exists( env ):
return 1
libffado-2.4.7/admin/scanreplace.py 0000644 0001750 0000144 00000002700 14206145246 016607 0 ustar jwoithe users #!/usr/bin/python
#
# Copyright (C) 2007-2008 Arnold Krille
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
#
# Taken from http://www.scons.org/wiki/ReplacementBuilder
#
from string import Template
import os
def replace_action(target, source, env):
open( str(target[0]), 'w' ).write( Template( open( str(source[0]), 'r' ).read() ).safe_substitute( env ) )
os.chmod( str(target[0]), os.stat( str(source[0]) ).st_mode )
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
libffado-2.4.7/configuration 0000644 0001750 0000144 00000056115 14340644323 015467 0 ustar jwoithe users device_definitions = (
{
vendorid = 0x00000f;
modelid = 0x00010065;
vendorname = "Mackie";
modelname = "Onyx FireWire";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{ # Added by arnonym from ffado-mixers list
vendorid = 0x00000f;
modelid = 0x00010067;
vendorname = "Mackie";
modelname = "Onyx FireWire";
driver = "BEBOB";
mixer = "MackieOnyx";
xmit_max_cycles_early_transmit = 4;
},
{ # Added by yellius
vendorid = 0x0022E;
modelid = 0x10067;
vendorname = "Tascam";
modelname = "IFFWDM";
driver = "BEBOB";
},
{ # IDs provided by Travis Kepley
vendorid = 0x000ff2;
modelid = 0x000006;
vendorname = "Loud Technologies Inc.";
modelname = "Onyx 1640i (DICE)";
driver = "DICE";
},
{ # IDs provided by Melanie Bernkopf. Mixer entry from Scott Martin.
vendorid = 0x000ff2;
modelid = 0x000007;
vendorname = "Loud Technologies Inc.";
modelname = "Onyx Blackbird";
driver = "DICE";
mixer = "Generic_Dice_EAP";
},
{ # IDs provided by Steven Tonge
vendorid = 0x000ff2;
modelid = 0x001640;
vendorname = "Loud Technologies Inc.";
modelname = "Onyx 1640i (Oxford)";
driver = "OXFORD";
# This transfer delay was tested at 48 kHz, as per
# http://sourceforge.net/p/ffado/mailman/message/26964819/
xmit_transfer_delay = 12800;
},
{ # entries provided by Holger Dehnhardt
vendorid = 0x000ff2;
modelid = 0x081216;
vendorname = "Loud Technologies Inc.";
modelname = "Onyx-i";
driver = "OXFORD";
xmit_transfer_delay = 11776;
},
{ # IDs from Geoff Beasley.
vendorid = 0x001564;
modelid = 0x00000006;
vendorname = "Behringer";
modelname = "X32";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{ # IDs from Tony Rocco.
vendorid = 0x001564;
modelid = 0x00001604;
vendorname = "Behringer";
modelname = "UFX-1604 mixer";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x0003db;
modelid = 0x00010048;
vendorname = "Apogee Electronics";
modelname = "Rosetta 200";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{ # From Greg Dorian
vendorid = 0x0003db;
modelid = 0x01dddd;
vendorname = "Apogee";
modelname = "Duet";
driver = "OXFORD";
},
{
vendorid = 0x0007f5;
modelid = 0x00010048;
vendorname = "BridgeCo";
modelname = "RD Audio1";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x0007f5;
modelid = 0x00010049;
vendorname = "BridgeCo";
modelname = "Audio 5";
driver = "BEBOB";
mixer = "BCoAudio5Control";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000a92;
modelid = 0x00010000;
vendorname = "PreSonus";
modelname = "FIREBOX";
driver = "BEBOB";
mixer = "Presonus_Firebox";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000a92;
modelid = 0x00010001;
vendorname = "PreSonus";
modelname = "Inspire1394";
driver = "BEBOB";
mixer = "Presonus_Inspire1394";
},
{
vendorid = 0x000a92;
modelid = 0x00010066;
vendorname = "PreSonus";
modelname = "FirePOD";
driver = "BEBOB";
mixer = "Presonus_FP10";
xmit_max_cycles_early_transmit = 4;
},
{ # Presonus Firestudio 26x26, Bob Hamil via jaimes on the forums
vendorid = 0x000a92;
modelid = 0x00000008;
vendorname = "Presonus";
modelname = "Firestudio 26x26";
mixer = "Generic_Dice_EAP";
driver = "DICE";
},
{ # Presonus Firestudio Project, from Walt Baldwin
vendorid = 0x000a92;
modelid = 0x0000000b;
vendorname = "Presonus";
modelname = "Firestudio Project";
mixer = "Generic_Dice_EAP";
driver = "DICE";
},
{ # Presonus Firestudio Tube, from Tobi Kraus
vendorid = 0x000a92;
modelid = 0x0000000c;
vendorname = "Presonus";
modelname = "Firestudio Tube";
mixer = "Generic_Dice_EAP";
driver = "DICE";
},
{ # Entry for Firestudio mobile provided by "Pule" via the forums.
vendorid = 0x000a92;
modelid = 0x00000011;
vendorname = "PreSonus";
modelname = "Firestudio Mobile";
mixer = "Generic_Dice_EAP";
driver = "DICE";
},
{ # Entry for StudioLive 2442, from Walt Baldwin
vendorid = 0x00000A92;
modelid = 0x00000012;
vendorname = "PreSonus";
modelname = "STUDIOLIVE_2442";
driver = "DICE";
},
{ # Entry for StudioLive 1602, from Ulrich-Lorenz Schluter
vendorid = 0x00000A92;
modelid = 0x00000013;
vendorname = "PreSonus";
modelname = "STUDIOLIVE_1602";
driver = "DICE";
},
{ # Entry for Studiolive 32.4.2, from Karl Swisher
vendorid = 0x00000a92;
modelid = 0x00000014;
vendorname = "PreSonus";
modelname = "STUDIOLIVE_3242_mk2";
driver = "DICE";
},
{
vendorid = 0x000aac;
modelid = 0x00000003;
vendorname = "TerraTec Electronic GmbH";
modelname = "Phase 88 FW";
driver = "BEBOB";
mixer = "Phase88Control";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000aac;
modelid = 0x00000004;
vendorname = "TerraTec Electronic GmbH";
modelname = "Phase X24 FW (model version 4)";
driver = "BEBOB";
mixer = "Phase24Control";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000aac;
modelid = 0x00000007;
vendorname = "TerraTec Electronic GmbH";
modelname = "Phase X24 FW (model version 7)";
driver = "BEBOB";
mixer = "Phase24Control";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000f1b;
modelid = 0x00010064;
vendorname = "ESI";
modelname = "Quatafire 610";
driver = "BEBOB";
mixer = "QuataFire";
xmit_max_cycles_early_transmit = 4;
},
# Shalok Shalom has a Quantafire 610 which reports a different modelid.
# The reasons for this are unknown.
{
vendorid = 0x000f1b;
modelid = 0x00000210;
vendorname = "ESI";
modelname = "Quatafire 610 variant";
driver = "BEBOB";
mixer = "QuataFire";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x00130e;
modelid = 0x00000003;
vendorname = "Focusrite";
modelname = "Saffire Pro26IO";
driver = "BEBOB";
mixer = "SaffirePro";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x00130e;
modelid = 0x00000006;
vendorname = "Focusrite";
modelname = "Saffire Pro10IO";
driver = "BEBOB";
mixer = "SaffirePro";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x00130e;
modelid = 0x00000000;
vendorname = "Focusrite";
modelname = "Saffire (LE)";
driver = "BEBOB";
mixer = "Saffire";
cmd_interval_time = 10000;
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x0040ab;
modelid = 0x00010049;
vendorname = "EDIROL";
modelname = "FA-66";
driver = "BEBOB";
mixer = "EdirolFa66Control";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x0040ab;
modelid = 0x00010048;
vendorname = "EDIROL";
modelname = "FA-101";
driver = "BEBOB";
mixer = "EdirolFa101Control";
xmit_max_cycles_early_transmit = 4;
},
{ # Added by Mark Brand (orania)
vendorid = 0x000d6c;
modelid = 0x0000000a;
vendorname = "M-Audio";
modelname = "Ozonic";
driver = "BEBOB";
mixer = "MAudio_BeBoB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000d6c;
modelid = 0x00010062;
vendorname = "M-Audio";
modelname = "FW Solo";
driver = "BEBOB";
mixer = "MAudio_BeBoB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000d6c;
modelid = 0x00010081;
vendorname = "M-Audio";
modelname = "NRV10";
driver = "BEBOB";
# no mixer
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000d6c;
modelid = 0x00010060;
vendorname = "M-Audio";
modelname = "FW Audiophile";
driver = "BEBOB";
mixer = "MAudio_BeBoB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000d6c;
modelid = 0x00010046;
vendorname = "M-Audio";
modelname = "FW 410";
driver = "BEBOB";
mixer = "MAudio_BeBoB";
xmit_max_cycles_early_transmit = 4;
},
{
// experimental for mixer functionality
vendorid = 0x000d6c;
modelid = 0x00010071;
vendorname = "M-Audio";
modelname = "FW 1814";
driver = "BEBOB";
mixer = "MAudio_BeBoB";
xmit_max_cycles_early_transmit = 4;
},
{
// experimental for mixer functionality
vendorid = 0x000d6c;
modelid = 0x00010091;
vendorname = "M-Audio";
modelname = "ProjectMix I/O";
driver = "BEBOB";
mixer = "MAudio_BeBoB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000d6c;
modelid = 0x000100A1;
vendorname = "M-Audio";
modelname = "ProFire Lightbridge";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x000d6c;
modelid = 0x00000010;
vendorname = "M-Audio";
modelname = "ProFire 2626";
driver = "DICE";
mixer = "Profire2626";
},
{
vendorid = 0x000d6c;
modelid = 0x00000011;
vendorname = "M-Audio";
modelname = "ProFire 610";
driver = "DICE";
mixer = "Profire2626";
},
{
vendorid = 0x000aac;
modelid = 0x00000002;
vendorname = "Acoustic Reality";
modelname = "eAR Master One";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x0000000A;
modelid = 0x00030000;
vendorname = "CME";
modelname = "Matrix K FW";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x1486;
modelid = 0xAF2;
vendorname = "Echo";
modelname = "AudioFire2";
driver = "FIREWORKS";
mixer = "AudioFire";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0x1486;
modelid = 0xAF4;
vendorname = "Echo";
modelname = "AudioFire4";
driver = "FIREWORKS";
mixer = "AudioFire";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x1486;
modelid = 0xAF8;
vendorname = "Echo";
modelname = "AudioFire8";
driver = "FIREWORKS";
mixer = "AudioFire";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0x1486;
modelid = 0xAF9;
vendorname = "Echo";
modelname = "AudioFire8a";
driver = "FIREWORKS";
mixer = "AudioFire";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0x1486;
modelid = 0xAF12;
vendorname = "Echo";
modelname = "AudioFire12";
driver = "FIREWORKS";
mixer = "AudioFire";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0x1486;
modelid = 0xAF12D;
vendorname = "Echo";
modelname = "AudioFire12HD";
driver = "FIREWORKS";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0x1486;
modelid = 0xF8;
vendorname = "Echo";
modelname = "Fireworks 8";
driver = "FIREWORKS";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0x1486;
modelid = 0xAFD1;
vendorname = "Echo";
modelname = "FW HDMI";
driver = "FIREWORKS";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0xFF2;
modelid = 0x400F;
vendorname = "Mackie";
modelname = "Onyx 400F";
driver = "FIREWORKS";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0xFF2;
modelid = 0x1200F;
vendorname = "Mackie";
modelname = "Onyx 1200F";
driver = "FIREWORKS";
xmit_max_cycles_early_transmit = 2;
},
{
vendorid = 0x1564;
modelid = 0xFC22;
vendorname = "Behringer";
modelname = "FCA202";
driver = "OXFORD";
},
{
vendorid = 0x00001260;
modelid = 0x00001000;
vendorname = "Stanton DJ";
modelname = "SCS.1m";
driver = "GENERICAVC";
xmit_max_cycles_early_transmit = 4;
xmit_sp_dll_bw = 1.0;
recv_sp_dll_bw = 1.0;
},
{ # added by arnonym from ffado-mixers list
vendorid = 0x0001f2;
modelid = 0x00000000;
vendorname = "Motu";
modelname = "All pre-mark3 devices";
driver = "MOTU";
mixer = "Motu";
},
{
vendorid = 0x0001f2;
modelid = 0x00000001;
vendorname = "Motu";
modelname = "All mark3 devices";
driver = "MOTU";
mixer = "Motu_Mark3";
},
{
vendorid = 0x000a35;
# Note: RME detection code compares the modelid field against the
# device's unit version since RME seem to use the configrom modelid
# for other things not necessarily related to device differentiation.
modelid = 0x0001;
vendorname = "RME";
modelname = "FireFace800";
driver = "RME";
mixer = "Rme";
},
{
vendorid = 0x000a35;
# Note: RME detection code compares the modelid field against the
# device's unit version since RME seem to use the configrom modelid
# for other things not necessarily related to device differentiation.
modelid = 0x0002;
vendorname = "RME";
modelname = "FireFace400";
driver = "RME";
mixer = "Rme";
},
{
vendorid = 0x000a35;
# Note: RME detection code compares the modelid field against the
# device's unit version since RME seem to use the configrom modelid
# for other things not necessarily related to device differentiation.
modelid = 0x0003;
vendorname = "RME";
modelname = "FireFace UFX";
driver = "RME";
mixer = "Rme";
},
{
vendorid = 0x000a35;
# Note: RME detection code compares the modelid field against the
# device's unit version since RME seem to use the configrom modelid
# for other things not necessarily related to device differentiation.
# Unit version (0x04) provided by Florian Hanisch.
modelid = 0x0004;
vendorname = "RME";
modelname = "FireFace UCX";
driver = "RME";
mixer = "Rme";
},
{
vendorid = 0x000a35;
# Note: RME detection code compares the modelid field against the
# device's unit version since RME seem to use the configrom modelid
# for other things not necessarily related to device differentiation.
# Unit version (0x05) provided by Florian Hofmann.
modelid = 0x0005;
vendorname = "RME";
modelname = "FireFace 802";
driver = "RME";
mixer = "Rme";
},
{
vendorid = 0x000166;
modelid = 0x0001;
vendorname = "TCAT";
modelname = "DiceII EVM (1)";
driver = "DICE";
},
{
vendorid = 0x000166;
modelid = 0x0002;
vendorname = "TCAT";
modelname = "DiceII EVM (2)";
driver = "DICE";
},
{
vendorid = 0x000166;
modelid = 0x0004;
vendorname = "TCAT";
modelname = "DiceII EVM (4)";
driver = "DICE";
},
{
vendorid = 0x000166;
modelid = 0x00000020;
vendorname = "TC Electronic";
modelname = "Konnekt 24D";
driver = "DICE";
},
{
vendorid = 0x000166;
modelid = 0x00000021;
vendorname = "TC Electronic";
modelname = "Konnekt 8";
driver = "DICE";
},
{ # Details provided by "Juanramon" in a comment post on the website
vendorid = 0x000166;
modelid = 0x00000022;
vendorname = "TC Electronic";
modelname = "Studio Konnekt 48";
driver = "DICE";
},
{
vendorid = 0x000166;
modelid = 0x00000023;
vendorname = "TC Electronic";
modelname = "Konnekt Live";
driver = "DICE";
},
{
vendorid = 0x000166;
modelid = 0x00000024;
vendorname = "TC Electronic";
modelname = "Desktop Konnekt 6";
driver = "DICE";
},
{
vendorid = 0x000166;
modelid = 0x00000027;
vendorname = "TC Electronic";
modelname = "ImpactTwin";
driver = "DICE";
},
{
vendorid = 0x000595;
modelid = 0x00000001;
vendorname = "Alesis";
modelname = "io|14";
driver = "DICE";
},
{
# The MultiMix-16 and MultiMix-12 share the same vendor/model IDs.
# Thanks to Fourer Dominique for the information about the MultiMix-12.
vendorid = 0x000595;
modelid = 0x00000000;
vendorname = "Alesis";
modelname = "MultiMix-12 / MultiMix-16 FireWire";
driver = "DICE";
},
{ # Studiolive 16.4.2, provided by Johan Landman
vendorid = 0x000a92;
modelid = 0x00000010;
vendorname = "PreSonus";
modelname = "STUDIOLIVE_1642";
driver = "DICE";
xmit_transfer_delay = 4;
},
{ # Studiolive 16.0.2, provided by Kim Tore Jensen
vendorid = 0x000a92;
modelid = 0x00000013;
vendorname = "PreSonus";
modelname = "STUDIOLIVE_1602";
driver = "DICE";
},
{
vendorid = 0x00130e;
modelid = 0x00000005;
vendorname = "Focusrite";
modelname = "Saffire PRO 40";
driver = "DICE";
mixer = "Saffire_Dice";
},
{
vendorid = 0x00130e;
modelid = 0x00000007;
vendorname = "Focusrite";
modelname = "Saffire PRO 24";
driver = "DICE";
mixer = "Saffire_Dice";
},
{
vendorid = 0x00130e;
modelid = 0x00000008;
vendorname = "Focusrite";
modelname = "Saffire PRO 24 DSP";
driver = "DICE";
mixer = "Saffire_Dice";
},
{
vendorid = 0x00130e;
modelid = 0x00000009;
vendorname = "Focusrite";
modelname = "Saffire PRO 14";
driver = "DICE";
mixer = "Saffire_Dice";
},
{
vendorid = 0x00130e;
modelid = 0x00000012;
vendorname = "Focusrite";
modelname = "Saffire PRO 26";
driver = "DICE";
mixer = "Saffire_Dice";
},
{
# A new version of the Pro 40 has been released, described in the
# ConfigROM as SAFFIRE_PRO_40_1. Thanks to Mathieu Picot for the info.
vendorid = 0x00130e;
modelid = 0x000000DE;
vendorname = "Focusrite";
modelname = "Saffire PRO 40-1";
driver = "DICE";
mixer = "Saffire_Dice";
},
{
# Casimir Westerholm has a "SAFFIRE_PRO_40_1" interface which somewhat
# unexpectedly uses a different model ID to that which has been seen by
# others. Thanks to Casimir for the information.
vendorid = 0x00130e;
modelid = 0x00000013;
vendorname = "Focusrite";
modelname = "Saffire PRO 40-1";
driver = "DICE";
mixer = "Saffire_Dice";
},
{
vendorid = 0x001C6A;
modelid = 0x00000001;
vendorname = "Weiss Engineering Ltd.";
modelname = "ADC 2";
driver = "DICE";
},
{
vendorid = 0x001C6A;
modelid = 0x00000002;
vendorname = "Weiss Engineering Ltd.";
modelname = "Vesta";
driver = "DICE";
},
{
vendorid = 0x001C6A;
modelid = 0x00000003;
vendorname = "Weiss Engineering Ltd.";
modelname = "Minerva";
driver = "DICE";
},
{
vendorid = 0x001C6A;
modelid = 0x00000004;
vendorname = "Weiss Engineering Ltd.";
modelname = "AFI 1";
driver = "DICE";
},
{
vendorid = 0x001C6A;
modelid = 0x00000005;
vendorname = "Weiss Engineering Ltd.";
modelname = "TAG DAC1";
driver = "DICE";
},
{
vendorid = 0x001C6A;
modelid = 0x00000006;
vendorname = "Weiss Engineering Ltd.";
modelname = "INT 202";
driver = "DICE";
},
{
vendorid = 0x001C6A;
modelid = 0x00000007;
vendorname = "Weiss Engineering Ltd.";
modelname = "DAC 202";
driver = "DICE";
},
{ # Added by david@wwns.com
vendorid = 0x001c2d;
modelid = 0x00000001;
vendorname = "FlexRadio_Systems";
modelname = "Flex-5000";
driver = "DICE";
xmit_max_cycles_early_transmit = 4;
},
{ # Phonic HelixBoard 24 Universal (PHHB24U), provided by Steffen Klein
vendorid = 0x001496;
modelid = 0x000000;
vendorname = "Phonic";
modelname = "HB 24U";
driver = "BEBOB";
xmit_max_cycles_early_transmit = 4;
},
{
vendorid = 0x0000A0DE;
modelid = 0x0010000B;
vendorname = "Yamaha";
modelname = "GO44";
driver = "BEBOB";
mixer = "YamahaGo";
},
{ # Yamaha GO46, provided by Luis Pablo Gasparotto
vendorid = 0x0000A0DE;
modelid = 0x0010000C;
vendorname = "Yamaha";
modelname = "GO46";
driver = "BEBOB";
mixer = "YamahaGo";
xmit_max_cycles_early_transmit = 4;
},
{ # DnR - Axum_FireWire_IO_card_16x16
vendorid = 0x00000F64;
modelid = 0x00000003;
vendorname = "DnR";
modelname = "Axum_FireWire_IO_card_16x16";
driver = "DICE";
},
{ # Lexicon Onix-FW810S, provided by gerradblock
vendorid = 0x00000FD7;
modelid = 0x00000001;
vendorname = "Lexicon";
modelname = "I-ONIX_FW810S";
driver = "DICE";
mixer = "Generic_Dice_EAP";
},
{ # Avid Mbox 2 Pro, information provided by Yves Grenier via the ffado-user
# mailing list.
# Note: as of Oct 2014 FFADO requires that the device be initialised
# under another operating system so routing and clock settings are
# correct. When this is done and the device is transferred to Linux
# without power cycling it, FFADO can stream audio to/from it. The
# initialisation details need to be sorted before FFADO can claim to
# properly support this device.
vendorid = 0x0000A07E;
modelid = 0x000000A9;
vendorname = "Digidesign";
modelname = "Mbox 2 Pro";
driver = "BEBOB";
# A device-specific mixer needs to be written, there being no generic
# bebob mixer modules.
},
{ # Avid Mbox Pro, information provided by Niels Dettenbach.
# Note: this entry is for future reference only. FFADO does NOT have a
# driver for this device: as of March 2013 no Avid/Digidesign interfaces
# are supported or usable with FFADO.
vendorid = 0x0000A07E;
modelid = 0x00000004;
vendorname = "Avid";
modelname = "Mbox 3 Pro";
},
{ # Allen and Heath Zed R16. Information from Brendan Pike.
vendorid = 0x000004C4;
modelid = 0x00000000;
vendorname = "Allen and Heath";
modelname = "Zed R16";
driver = "DICE";
mixer = "Generic_Dice_EAP";
},
{ # Midas Venice F32. Information from Jano Svitok.
vendorid = 0x0010C73F;
modelid = 0x00000001;
vendorname = "Midas";
modelname = "Venice F32";
driver = "DICE";
mixer = "Generic_Dice_EAP";
},
{ # ICON FireXon. Information from Philippe Ploquin.
vendorid = 0x00001A9E;
modelid = 0x00000001;
vendorname = "ICON";
modelname = "FireXon";
driver = "BEBOB";
# A device-specific mixer needs to be written, there being no generic
# bebob mixer modules.
}
);
libffado-2.4.7/src/ 0000755 0001750 0000144 00000000000 14340644631 013456 5 ustar jwoithe users libffado-2.4.7/src/ffadodevice.h 0000644 0001750 0000144 00000037056 14340644323 016077 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef FFADODEVICE_H
#define FFADODEVICE_H
#include "libutil/OptionContainer.h"
#include "libutil/PosixMutex.h"
#include "libcontrol/BasicElements.h"
#include "libieee1394/vendor_model_ids.h"
#include
#include
#include
// Prefer shared_ptr over auto_ptr if it is available
#if __cplusplus >= 201103L
#define ffado_smartptr std::shared_ptr
#else
#define ffado_smartptr std::auto_ptr
#endif
class DeviceManager;
class ConfigRom;
class Ieee1394Service;
namespace Streaming {
class StreamProcessor;
}
namespace Control {
class Container;
}
/*!
@brief Base class for device support
This class should be subclassed to implement ffado support
for a specific device.
*/
class FFADODevice
: public Util::OptionContainer,
public Control::Container
{
public:
FFADODevice( DeviceManager&, ffado_smartptr< ConfigRom >( configRom ) );
virtual ~FFADODevice();
/**
* @brief Compares the GUID of two FFADODevices
*
* This function compares the GUID of two FFADODevices and returns true
* if the GUID of a is larger than the GUID of b . This is intended to be
* used with the STL sort() algorithm.
*
* Note that GUID's are converted to integers for this.
*
* @param a pointer to first FFADODevice
* @param b pointer to second FFADODevice
*
* @returns true if the GUID of a is larger than the GUID of b .
*/
static bool compareGUID( FFADODevice *a, FFADODevice *b );
/// Returns the 1394 service of the FFADO device
virtual Ieee1394Service& get1394Service();
/// Returns the ConfigRom object of the device node.
virtual ConfigRom& getConfigRom() const;
/**
* @brief Called by DeviceManager to load device model from cache.
*
* This function is called before discover in order to speed up
* system initializing.
*
* @returns true if device was cached and successfully loaded from cache
*/
virtual bool loadFromCache();
/**
* @brief Called by DeviceManager to allow device driver to save a cache version
* of the current configuration.
*
* @returns true if caching was successful. False doesn't mean an error just,
* the driver was unable to store the configuration
*/
virtual bool saveCache();
/**
* @brief Called by DeviceManager to check whether a device requires rediscovery
*
* This function is called to figure out if the device has to be rediscovered
* e.g. after a bus reset where the device internal structure changed.
*
* @returns true if device requires rediscovery
*/
virtual bool needsRediscovery();
/**
* @brief This is called by the DeviceManager to create an instance of the device
*
* This function enables the FFADODevice to return a subclass of itself should that
* be needed. If we don't do this we'd need to know about the subclasses in the
* devicemanager, whilst now we don't.
*
* The function should return an instance of either the class itself or a subclass
* of itself.
*
* This should be overridden in any subclass.
*
* @return a new instance of the AvDevice type, NULL when unsuccessful
*/
static FFADODevice * createDevice( ffado_smartptr( x ));
/**
* @brief This is called by the DeviceManager to discover & configure the device
*
* @return true if the device was discovered successfully
*/
virtual bool discover() = 0;
/**
* @brief Set the samping frequency
* @param samplingFrequency
* @return true if successful
*/
virtual bool setSamplingFrequency( int samplingFrequency ) = 0;
/**
* @brief get the samplingfrequency as an integer
* @return the sampling frequency as integer
*/
virtual int getSamplingFrequency( ) = 0;
/**
* @brief Some devices require to update part of their internal configuration on samplerate change
* Most do not, so set default to false
* @param oldSamplingFrequency : to be compared to the actual sampling frequency of the device
* note: next, it is thus assumed that the device was actually set to some new sampling frequency
* (while the client did not yet update its view of the device).
* In some future, it might very well appear that restricting to this single argument is
* unsufficient for some devices, so feel free to adapt accordingly.
*
* @return true if changes have been performed
*/
virtual bool onSamplerateChange( int oldSamplingFrequency ) { return false; }
/**
* @brief get the supported sampling frequencies
* @return a vector containing the supported sampling frequencies
*/
virtual std::vector getSupportedSamplingFrequencies( ) = 0;
/**
* @brief sync state enum
*/
enum eSyncState {
eSS_Unknown=0,
eSS_Locked=1,
eSS_Unlocked=2,
};
/**
* @brief gets the devices current synchronization state
* @return the device's sync state
*/
virtual enum eSyncState getSyncState( );
/**
* @brief clock source types
*/
enum eClockSourceType {
eCT_Invalid, ///> invalid entry (e.g. on error)
eCT_Auto, ///> automatically select clock source
eCT_Internal, ///> internal sync (unspecified)
eCT_1394Bus, ///> Sync on the 1394 bus clock (e.g. CSP)
eCT_SytMatch, ///> SYT match on incoming audio stream
eCT_SytStream, ///> SYT match on incoming sync stream
eCT_WordClock, ///> SYT on WordClock input
eCT_SPDIF, ///> SYT on SPDIF input
eCT_ADAT, ///> SYT on ADAT input
eCT_TDIF, ///> SYT on TDIF input
eCT_AES, ///> SYT on AES input
eCT_SMPTE, ///> SMPTE clock
};
/**
* @brief convert the clock source type to a C string
* @return a C string describing the clock source type
*/
static const char *ClockSourceTypeToString(enum eClockSourceType);
/**
* @brief Clock source identification struct
*/
class ClockSource {
public:
ClockSource()
: type( eCT_Invalid )
, id( 0 )
, valid( false )
, active( false )
, locked( true )
, slipping( false )
, description( "" )
{};
/// indicates the type of the clock source (e.g. eCT_ADAT)
enum eClockSourceType type;
/// indicated the id of the clock source (e.g. id=1 => clocksource is ADAT_1)
unsigned int id;
/// is the clock source valid (i.e. can be selected) at this moment?
bool valid;
/// is the clock source active at this moment?
bool active;
/// is the clock source locked?
bool locked;
/// is the clock source slipping?
bool slipping;
/// description of the clock struct (optional)
std::string description;
bool operator==(const ClockSource& x) {
return (type == x.type) && (id == x.id);
}
};
typedef std::vector< ClockSource > ClockSourceVector;
typedef std::vector< ClockSource >::iterator ClockSourceVectorIterator;
/**
* @brief Get the clocksources supported by this device
*
* This function returns a vector of ClockSource structures that contains
* one entry for every clock source supported by the device.
*
* @returns a vector of ClockSource structures
*/
virtual ClockSourceVector getSupportedClockSources() = 0;
/**
* @brief Sets the active clock source of this device
*
* This function sets the clock source of the device.
*
* @returns true upon success. false upon failure.
*/
virtual bool setActiveClockSource(ClockSource) = 0;
/**
* @brief Returns the active clock source of this device
*
* This function returns the active clock source of the device.
*
* @returns the active ClockSource
*/
virtual ClockSource getActiveClockSource() = 0;
/**
* @brief stream states
*/
enum eStreamingState {
eSS_Idle = 0, ///> not streaming
eSS_Sending = 1, ///> the device is sending a stream
eSS_Receiving = 2, ///> the device is receiving a stream
eSS_Both = 3, ///> the device is sending and receiving a stream
};
/**
* @brief gets the devices current synchronization state
* @return the device's sync state
*/
virtual enum eStreamingState getStreamingState();
/**
* @brief Outputs the device configuration to stderr/stdout [debug helper]
*
* This function prints out a (detailed) description of the
* device detected, and its configuration.
*/
virtual void showDevice();
/**
* @brief Lock the device
*
* This is called by the streaming layer before we start manipulating
* and/or using the device.
*
* It should implement the mechanisms provided by the device to
* make sure that no other controller claims control of the device.
*
* @return true if successful, false if not
*/
virtual bool lock() = 0;
/**
* @brief Unlock the device
*
* This is called by the streaming layer after we finish manipulating
* and/or using the device.
*
* It should implement the mechanisms provided by the device to
* give up exclusive control of the device.
*
* @return true if successful, false if not
*/
virtual bool unlock() = 0;
/**
* @brief Enable streaming on all 'started' streams
*
* Enables the ISO streaming on all streams that are 'started'
* using startStreamByIndex. This is useful to control a 'master enable'
* function on the device.
*
* @return true if successful
*/
virtual bool enableStreaming();
/**
* @brief Disable streaming on all streams
*
* Disables ISO streaming on all streams.
* This is useful to control a 'master enable'
* function on the device.
*
* @return true if successful
*/
virtual bool disableStreaming();
/**
* @brief Prepare the device
*
* This is called by the streaming layer after the configuration
* parameters (e.g. sample rate) are set, and before
* getStreamProcessor[*] functions are called.
*
* It should be used to prepare the device's streamprocessors
* based upon the device's current configuration. Normally
* the streaming layer will not change the device's configuration
* after calling this function.
*
* @return true if successful, false if not
*/
virtual bool prepare() = 0;
/**
* @brief Performs operations needed to prepare for a stream start
*
* This is called by the streaming layer just before streaming is
* started. It provides a place where reset activity can be done which
* ensures the object is ready to restart streaming even if streaming
* has been previously started and stopped.
*
* @return true if successful, false if not
*/
virtual bool resetForStreaming() { return true; }
/**
* @brief Returns the number of ISO streams implemented/used by this device
*
* Most likely this is 2 streams, i.e. one transmit stream and one
* receive stream. However there are devices that implement more, for
* example BeBoB's implement 4 streams:
* - 2 audio streams (1 xmit/1 recv)
* - 2 sync streams (1 xmit/1 recv), which are an optional sync source
* for the device.
*
* @note you have to have a StreamProcessor for every stream. I.e.
* getStreamProcessorByIndex(i) should return a valid StreamProcessor
* for i=0 to i=getStreamCount()-1
*
* @return number of streams available (both transmit and receive)
*/
virtual int getStreamCount() = 0;
/**
* @brief Returns the StreamProcessor object for the stream with index i
*
* @note a streamprocessor returned by getStreamProcessorByIndex(i)
* cannot be the same object as one returned by
* getStreamProcessorByIndex(j) if i isn't equal to j
* @note you cannot have two streamprocessors handling the same ISO
* channel (on the same port)
*
* @param i : Stream index (i has to be smaller than getStreamCount())
* @return a StreamProcessor object if successful, NULL otherwise
*/
virtual Streaming::StreamProcessor *getStreamProcessorByIndex(int i) = 0;
/**
* @brief starts the stream with index i
*
* This function is called by the streaming layer when this stream should
* be started, i.e. the device should start sending data or should be prepared to
* be ready to receive data.
*
* It returns the channel number that was assigned for this stream.
* Channel allocation should be done using the allocation functions provided by the
* Ieee1394Service object that is passed in the constructor.
*
* @param i : Stream index (i has to be smaller than getStreamCount())
* @return true if successful, false if not
*/
virtual bool startStreamByIndex(int i) = 0;
/**
* @brief stops the stream with index i
*
* @param i : Stream index (i has to be smaller than getStreamCount())
* @return true if successful, false if not
*/
virtual bool stopStreamByIndex(int i) = 0;
/**
* set verbosity level
*/
virtual void setVerboseLevel(int l);
/**
* @brief return the node id of this device
*
* @return the node id
*/
int getNodeId();
/**
* @brief return the nick name of this device
*
* @return string containing the name
*/
virtual std::string getNickname();
/**
* @brief set the nick name of this device
* @param name new nickname
* @return true if successful
*/
virtual bool setNickname(std::string name);
/**
* @brief return whether the nick name of this device can be changed
*
* @return true if the nick can be changed
*/
virtual bool canChangeNickname();
/**
* @brief handle a bus reset
*
* Called whenever a bus reset is detected. Handle everything
* that has to be done to cope with a bus reset.
*
*/
// FIXME: not virtual?
void handleBusReset();
// the Control::Container functions
virtual std::string getName();
virtual bool setName( std::string n )
{ return false; };
DeviceManager& getDeviceManager()
{return m_pDeviceManager;};
private:
ffado_smartptr m_pConfigRom;
DeviceManager& m_pDeviceManager;
Control::Container* m_genericContainer;
protected:
DECLARE_DEBUG_MODULE;
Util::PosixMutex m_DeviceMutex;
};
#endif
libffado-2.4.7/src/DeviceStringParser.cpp 0000644 0001750 0000144 00000025601 14206145246 017730 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#include "DeviceStringParser.h"
#include
#include
#include
#include
#include "libieee1394/configrom.h"
#include "libieee1394/ieee1394service.h"
IMPL_DEBUG_MODULE( DeviceStringParser, DeviceStringParser, DEBUG_LEVEL_NORMAL );
DeviceStringParser::DeviceString::DeviceString(DeviceStringParser& parent)
: m_Parent(parent)
, m_node( -1 )
, m_port( -1 )
, m_guid( 0 )
, m_String("")
, m_Type(eInvalid)
, m_debugModule( parent.m_debugModule )
{
}
DeviceStringParser::DeviceString::~DeviceString()
{
}
bool
DeviceStringParser::DeviceString::parse(std::string s)
{
m_String = s;
debugOutput(DEBUG_LEVEL_VERBOSE, "parse: %s\n", s.c_str());
std::string prefix = s.substr(0,3);
if(s.compare(0,3,"hw:")==0) {
m_Type = eBusNode;
std::string detail = s.substr(3);
std::string::size_type comma_pos = detail.find_first_of(",");
if(comma_pos == std::string::npos) {
// node is unspecified
m_node = -1;
std::string port = detail;
errno = 0;
m_port = strtol(port.c_str(), NULL, 0);
if(errno) {
m_Type = eInvalid;
m_port = -1;
m_node = -1;
debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse port\n");
return false;
}
} else {
std::string port = detail.substr(0, comma_pos);
std::string node = detail.substr(comma_pos+1);
errno = 0;
m_port = strtol(port.c_str(), NULL, 0);
if(errno) {
m_Type = eInvalid;
m_port = -1;
m_node = -1;
debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse port\n");
return false;
}
errno = 0;
m_node = strtol(node.c_str(), NULL, 0);
if(errno) {
m_Type = eInvalid;
m_port = -1;
m_node = -1;
debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse node\n");
return false;
}
}
} else if (s.compare(0,5,"guid:")==0) {
std::string detail = s.substr(5);
m_Type = eGUID;
errno = 0;
m_guid = strtoll(detail.c_str(), NULL, 0);
if(errno) {
m_Type = eInvalid;
m_guid = 0;
debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse guid\n");
return false;
}
} else {
m_Type = eInvalid;
debugOutput(DEBUG_LEVEL_VERBOSE, "invalid\n");
return false;
}
return true;
}
bool
DeviceStringParser::DeviceString::isValidString(std::string s)
{
std::string prefix = s.substr(0,3);
if(s.compare(0,3,"hw:")==0) {
std::string detail = s.substr(3);
std::string::size_type comma_pos = detail.find_first_of(",");
if(comma_pos == std::string::npos) {
std::string port = detail;
errno = 0;
strtol(port.c_str(), NULL, 0);
if(errno) {
return false;
}
} else {
std::string port = detail.substr(0, comma_pos);
std::string node = detail.substr(comma_pos+1);
errno = 0;
strtol(port.c_str(), NULL, 0);
if(errno) {
return false;
}
errno = 0;
strtol(node.c_str(), NULL, 0);
if(errno) {
return false;
}
}
} else if (s.compare(0,5,"guid:")==0) {
std::string detail = s.substr(5);
errno = 0;
strtoll(detail.c_str(), NULL, 0);
if(errno) {
return false;
}
} else {
return false;
}
return true;
}
bool
DeviceStringParser::DeviceString::match(ConfigRom& configRom)
{
debugOutput(DEBUG_LEVEL_VERBOSE, "match %p (%s)\n", &configRom, configRom.getGuidString().c_str());
bool match;
switch(m_Type) {
case eBusNode:
if(m_port < 0) {
debugWarning("Need at least a port spec\n");
return false;
}
match = configRom.get1394Service().getPort() == m_port;
if(m_node >= 0) {
match &= ((configRom.getNodeId() & 0x3F) == m_node);
}
if(match) {
debugOutput(DEBUG_LEVEL_VERBOSE, "(eBusNode) device matches device string %s\n", m_String.c_str());
}
return match;
case eGUID:
//GUID should not be 0
match = m_guid && (m_guid == configRom.getGuid());
if(match) {
debugOutput(DEBUG_LEVEL_VERBOSE, "(eGUID) device matches device string %s\n", m_String.c_str());
}
return match;
case eInvalid:
default:
debugError("invalid DeviceString type (%d)\n", m_Type);
return false;
}
return false;
}
bool
DeviceStringParser::DeviceString::operator==(const DeviceString& x)
{
bool retval;
switch(m_Type) {
case eBusNode:
retval = (m_port == x.m_port) && (m_node == x.m_node);
debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "eBusNode %d,%d == %d,%d? %d\n",
m_port, m_node, x.m_port, x.m_node, retval);
return retval;
case eGUID:
retval = m_guid && (m_guid == x.m_guid);
debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "eGUID 0x%016" PRIX64 " == 0x%016" PRIX64 "? %d\n",
m_guid, x.m_guid, retval);
return retval;
case eInvalid:
debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "eInvalid \n");
default:
return false;
}
}
void
DeviceStringParser::DeviceString::show()
{
debugOutput(DEBUG_LEVEL_INFO, "string: %s\n", m_String.c_str());
switch(m_Type) {
case eBusNode:
debugOutput(DEBUG_LEVEL_INFO, "type: eBusNode\n");
debugOutput(DEBUG_LEVEL_INFO, " Port: %d, Node: %d\n",
m_port, m_node);
break;
case eGUID:
debugOutput(DEBUG_LEVEL_INFO, "type: eGUID\n");
debugOutput(DEBUG_LEVEL_INFO, " GUID: %016" PRIX64 "\n", m_guid);
break;
case eInvalid:
default:
debugOutput(DEBUG_LEVEL_INFO, "type: eInvalid\n");
break;
}
}
// ------------------------
DeviceStringParser::DeviceStringParser()
{}
DeviceStringParser::~DeviceStringParser()
{
while(m_DeviceStrings.size()) {
DeviceString *tmp = m_DeviceStrings.at(0);
debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "removing device string: %p\n", tmp);
m_DeviceStrings.erase(m_DeviceStrings.begin());
delete tmp;
}
}
bool
DeviceStringParser::parseString(std::string s)
{
debugOutput(DEBUG_LEVEL_VERBOSE, "parse: %s\n", s.c_str());
std::string::size_type next_sep;
std::string tmp = s;
do {
debugOutput(DEBUG_LEVEL_VERBOSE, " left: %s\n", tmp.c_str());
next_sep = tmp.find_first_of(";");
std::string to_parse = tmp.substr(0, next_sep);
DeviceString *d = new DeviceString(*this);
if(d == NULL) {
debugError("failed to allocate memory for device string\n");
continue;
}
if(d->parse(to_parse)) {
addDeviceString(d);
} else {
debugWarning("Failed to parse device substring: \"%s\"\n",
to_parse.c_str());
delete d;
}
tmp = tmp.substr(next_sep+1);
} while(tmp.size() && next_sep != std::string::npos);
pruneDuplicates();
return true;
}
bool
DeviceStringParser::isValidString(std::string s)
{
debugOutput(DEBUG_LEVEL_VERBOSE, "isvalid? %s\n", s.c_str());
return DeviceString::isValidString(s);
}
bool
DeviceStringParser::match(ConfigRom& c)
{
return matchPosition(c) != -1;
}
int
DeviceStringParser::matchPosition(ConfigRom& c)
{
int pos = 0;
for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
it != m_DeviceStrings.end();
++it )
{
if((*it)->match(c)) {
return pos;
}
pos++;
}
return -1;
}
bool
DeviceStringParser::addDeviceString(DeviceString *o)
{
debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "adding device string: %p\n", o);
if (hasDeviceString(o)){
return false;
}
m_DeviceStrings.push_back(o);
return true;
}
bool
DeviceStringParser::removeDeviceString(DeviceString *o)
{
debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "removing device string: %p\n", o);
int i=findDeviceString(o);
if (i<0) {
debugOutput(DEBUG_LEVEL_VERBOSE, "not found\n");
return false;
} else {
DeviceString *tmp = m_DeviceStrings.at(i);
m_DeviceStrings.erase(m_DeviceStrings.begin()+i);
delete tmp;
return true;
}
}
bool
DeviceStringParser::hasDeviceString(DeviceString *o)
{
return (findDeviceString(o) >= 0);
}
int
DeviceStringParser::findDeviceString(DeviceString *o)
{
int i=0;
for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
it != m_DeviceStrings.end();
++it )
{
if(*it == o) {
return i;
}
i++;
}
return -1;
}
void
DeviceStringParser::pruneDuplicates()
{
DeviceStringVector duplicates;
// find duplicates
for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
it != m_DeviceStrings.end();
++it )
{
for ( DeviceStringVectorIterator it2 = it+1;
it2 != m_DeviceStrings.end();
++it2 )
{
if(**it == **it2) {
duplicates.push_back(*it2);
}
}
}
// remove duplicates
for ( DeviceStringVectorIterator it = duplicates.begin();
it != duplicates.end();
++it )
{
removeDeviceString(*it);
}
}
void
DeviceStringParser::show()
{
debugOutput(DEBUG_LEVEL_INFO, "DeviceStringParser: %p\n", this);
for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
it != m_DeviceStrings.end();
++it )
{
(*it)->show();
}
}
void
DeviceStringParser::setVerboseLevel(int i)
{
setDebugLevel(i);
}
libffado-2.4.7/src/DeviceStringParser.h 0000644 0001750 0000144 00000005062 14206145246 017374 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#ifndef __FFADO_DEVICESTRINGPARSER__
#define __FFADO_DEVICESTRINGPARSER__
#include "debugmodule/debugmodule.h"
#include
#include
#include
class ConfigRom;
class DeviceStringParser {
protected:
class DeviceString {
public:
enum eType {
eInvalid = 0,
eBusNode = 1, // old-style hw:bus,node
eGUID = 2, // GUID match
};
DeviceString(DeviceStringParser&);
~DeviceString();
bool parse(std::string s);
bool match(ConfigRom &);
std::string getString() {return m_String;};
void show();
bool operator==(const DeviceString& x);
static bool isValidString(std::string s);
private:
DeviceStringParser & m_Parent;
int m_node;
int m_port;
uint64_t m_guid;
std::string m_String;
enum eType m_Type;
DECLARE_DEBUG_MODULE_REFERENCE;
};
public:
DeviceStringParser();
virtual ~DeviceStringParser();
int countDeviceStrings() {return m_DeviceStrings.size();};
bool match(ConfigRom &);
int matchPosition(ConfigRom& c);
bool parseString(std::string s);
void show();
void setVerboseLevel(int i);
static bool isValidString(std::string s);
protected:
bool removeDeviceString(DeviceString *);
bool addDeviceString(DeviceString *);
bool hasDeviceString(DeviceString *);
private:
int findDeviceString(DeviceString *);
void pruneDuplicates();
typedef std::vector< DeviceString* > DeviceStringVector;
typedef std::vector< DeviceString* >::iterator DeviceStringVectorIterator;
DeviceStringVector m_DeviceStrings;
protected:
DECLARE_DEBUG_MODULE;
};
#endif /* __FFADO_DEVICESTRINGPARSER__ */
libffado-2.4.7/src/SConscript 0000644 0001750 0000144 00000026062 14206145246 015475 0 ustar jwoithe users #
# Copyright (C) 2007-2008 Arnold Krille
# Copyright (C) 2007-2008 Pieter Palmers
#
# This file is part of FFADO
# FFADO = Free FireWire (pro-)audio drivers for Linux
#
# FFADO is based upon FreeBoB.
#
# 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) version 3 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, see .
#
import os
Import( 'env' )
libenv = env.Clone()
libenv.MergeFlags( "-I#/ -I#/src" )
ffado_source = env.Split( '\
devicemanager.cpp \
ffado.cpp \
ffadodevice.cpp \
debugmodule/debugmodule.cpp \
DeviceStringParser.cpp \
libieee1394/ARMHandler.cpp \
libieee1394/configrom.cpp \
libieee1394/csr1212.c \
libieee1394/CycleTimerHelper.cpp \
libieee1394/ieee1394service.cpp \
libieee1394/IEC61883.cpp \
libieee1394/IsoHandlerManager.cpp \
libstreaming/StreamProcessorManager.cpp \
libstreaming/util/cip.c \
libstreaming/generic/StreamProcessor.cpp \
libstreaming/generic/Port.cpp \
libstreaming/generic/PortManager.cpp \
libutil/cmd_serialize.cpp \
libutil/DelayLockedLoop.cpp \
libutil/IpcRingBuffer.cpp \
libutil/PacketBuffer.cpp \
libutil/Configuration.cpp \
libutil/OptionContainer.cpp \
libutil/PosixMessageQueue.cpp \
libutil/PosixSharedMemory.cpp \
libutil/PosixMutex.cpp \
libutil/PosixThread.cpp \
libutil/ringbuffer.c \
libutil/StreamStatistics.cpp \
libutil/SystemTimeSource.cpp \
libutil/TimestampedBuffer.cpp \
libutil/Watchdog.cpp \
libcontrol/Element.cpp \
libcontrol/BasicElements.cpp \
libcontrol/MatrixMixer.cpp \
libcontrol/CrossbarRouter.cpp \
libcontrol/ClockSelect.cpp \
libcontrol/Nickname.cpp \
')
if env['SERIALIZE_USE_EXPAT']:
ffado_source.append('libutil/serialize_expat.cpp')
ffado_source.append('libutil/serialize_expat_xml.cpp')
else:
ffado_source.append('libutil/serialize_libxml.cpp')
bebob_source = env.Split( '\
bebob/bebob_avdevice.cpp \
bebob/bebob_avdevice_subunit.cpp \
bebob/bebob_avplug.cpp \
bebob/bebob_dl_bcd.cpp \
bebob/bebob_dl_codes.cpp \
bebob/bebob_dl_mgr.cpp \
bebob/bebob_functionblock.cpp \
bebob/bebob_mixer.cpp \
bebob/focusrite/focusrite_generic.cpp \
bebob/focusrite/focusrite_saffire.cpp \
bebob/focusrite/focusrite_saffirepro.cpp \
bebob/focusrite/focusrite_cmd.cpp \
bebob/terratec/terratec_device.cpp \
bebob/terratec/terratec_cmd.cpp \
bebob/edirol/edirol_fa101.cpp \
bebob/edirol/edirol_fa66.cpp \
bebob/esi/quatafire610.cpp \
bebob/mackie/onyxmixer.cpp \
bebob/yamaha/yamaha_cmd.cpp \
bebob/yamaha/yamaha_avdevice.cpp \
bebob/maudio/normal_avdevice.cpp \
bebob/maudio/special_avdevice.cpp \
bebob/maudio/special_mixer.cpp \
bebob/presonus/firebox_avdevice.cpp \
bebob/presonus/inspire1394_avdevice.cpp \
' )
bebob_pkgdata = env.Split( '\
bebob/maudio/refdesign.xml \
bebob/maudio/fw410.xml \
bebob/maudio/fwap.xml \
' )
genericavc_source = env.Split( '\
genericavc/avc_avdevice.cpp \
genericavc/stanton/scs.cpp \
' )
genericavc_pkgdata = env.Split( '\
' )
fireworks_source = env.Split( '\
fireworks/fireworks_device.cpp \
fireworks/fireworks_control.cpp \
fireworks/fireworks_firmware.cpp \
fireworks/efc/efc_avc_cmd.cpp \
fireworks/efc/efc_cmd.cpp \
fireworks/efc/efc_cmds_hardware.cpp \
fireworks/efc/efc_cmds_hardware_ctrl.cpp \
fireworks/efc/efc_cmds_flash.cpp \
fireworks/efc/efc_cmds_mixer.cpp \
fireworks/efc/efc_cmds_monitor.cpp \
fireworks/efc/efc_cmds_ioconfig.cpp \
fireworks/fireworks_session_block.cpp \
fireworks/audiofire/audiofire_device.cpp \
' )
fireworks_pkgdata = env.Split( '\
' )
oxford_source = env.Split( '\
oxford/oxford_device.cpp \
libstreaming/amdtp-oxford/AmdtpOxfordReceiveStreamProcessor.cpp \
' )
oxford_pkgdata = env.Split( '\
' )
motu_source = env.Split( '\
motu/motu_avdevice.cpp \
motu/motu_controls.cpp \
motu/motu_mark3_controls.cpp \
motu/motu_mixerdefs.cpp \
motu/motu_mark3_mixerdefs.cpp \
motu/motu_mixer.cpp \
libstreaming/motu/MotuPort.cpp \
libstreaming/motu/MotuPortInfo.cpp \
libstreaming/motu/MotuReceiveStreamProcessor.cpp \
libstreaming/motu/MotuTransmitStreamProcessor.cpp \
' )
dice_source = env.Split( '\
dice/dice_avdevice.cpp \
dice/dice_firmware_loader.cpp \
dice/dice_eap.cpp \
dice/focusrite/focusrite_eap.cpp \
dice/focusrite/saffire_pro40.cpp \
dice/focusrite/saffire_pro26.cpp \
dice/focusrite/saffire_pro24.cpp \
dice/focusrite/saffire_pro14.cpp \
dice/focusrite/saffire_56.cpp \
dice/maudio/profire_2626.cpp \
dice/presonus/firestudio_tube.cpp \
dice/presonus/firestudio_project.cpp \
dice/presonus/firestudio_mobile.cpp \
' )
bounce_source = env.Split( '\
bounce/bounce_avdevice.cpp \
bounce/bounce_slave_avdevice.cpp \
' )
metric_halo_source = env.Split( '\
metrichalo/mh_avdevice.cpp \
' )
rme_source = env.Split( '\
rme/rme_shm.cpp \
rme/rme_avdevice.cpp \
rme/rme_avdevice_settings.cpp \
rme/fireface_flash.cpp \
rme/fireface_hw.cpp \
rme/fireface_settings_ctrls.cpp \
libstreaming/rme/RmePort.cpp \
libstreaming/rme/RmePortInfo.cpp \
libstreaming/rme/RmeReceiveStreamProcessor.cpp \
libstreaming/rme/RmeTransmitStreamProcessor.cpp \
' )
digidesign_source = env.Split( '\
digidesign/digidesign_avdevice.cpp \
libstreaming/digidesign/DigidesignPort.cpp \
libstreaming/digidesign/DigidesignPortInfo.cpp \
libstreaming/digidesign/DigidesignReceiveStreamProcessor.cpp \
libstreaming/digidesign/DigidesignTransmitStreamProcessor.cpp \
' )
amdtp_source = env.Split( '\
libstreaming/amdtp/AmdtpPort.cpp \
libstreaming/amdtp/AmdtpPortInfo.cpp \
libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp \
libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp \
' )
libavc_source = env.Split( '\
libavc/streamformat/avc_extended_stream_format.cpp \
libavc/musicsubunit/avc_descriptor_music.cpp \
libavc/musicsubunit/avc_musicsubunit.cpp \
libavc/audiosubunit/avc_audiosubunit.cpp \
libavc/audiosubunit/avc_descriptor_audio.cpp \
libavc/audiosubunit/avc_function_block.cpp \
libavc/descriptors/avc_descriptor_cmd.cpp \
libavc/descriptors/avc_descriptor.cpp \
libavc/general/avc_extended_subunit_info.cpp \
libavc/general/avc_unit_info.cpp \
libavc/general/avc_generic.cpp \
libavc/general/avc_subunit_info.cpp \
libavc/general/avc_connect.cpp \
libavc/general/avc_signal_format.cpp \
libavc/general/avc_extended_cmd_generic.cpp \
libavc/general/avc_extended_plug_info.cpp \
libavc/general/avc_plug_info.cpp \
libavc/general/avc_unit.cpp \
libavc/general/avc_subunit.cpp \
libavc/general/avc_plug.cpp \
libavc/general/avc_vendor_dependent_cmd.cpp \
libavc/avc_definitions.cpp \
libavc/ccm/avc_signal_source.cpp \
' )
source = ffado_source
pkgdata = []
if env['ENABLE_BEBOB']:
env['ENABLE_GENERICAVC'] = True
libenv.MergeFlags( "-DENABLE_BEBOB" )
source += bebob_source
pkgdata += bebob_pkgdata
if env['ENABLE_FIREWORKS']:
env['ENABLE_GENERICAVC'] = True
libenv.MergeFlags( "-DENABLE_FIREWORKS" )
source += fireworks_source
pkgdata += fireworks_pkgdata
if env['ENABLE_OXFORD']:
env['ENABLE_GENERICAVC'] = True
libenv.MergeFlags( "-DENABLE_OXFORD" )
source += oxford_source
pkgdata += oxford_pkgdata
if env['ENABLE_MOTU']:
libenv.MergeFlags( "-DENABLE_MOTU" )
source += motu_source
if env['ENABLE_DICE']:
env['ENABLE_GENERICAVC'] = True
libenv.MergeFlags( "-DENABLE_DICE" )
source += dice_source
if env['ENABLE_METRIC_HALO']:
libenv.MergeFlags( "-DENABLE_METRIC_HALO" )
source += metric_halo_source
if env['ENABLE_RME']:
libenv.MergeFlags( "-DENABLE_RME" )
source += rme_source
if env['ENABLE_DIGIDESIGN']:
libenv.MergeFlags( "-DENABLE_DIGIDESIGN" )
source += digidesign_source
if env['ENABLE_BOUNCE']:
env['ENABLE_GENERICAVC'] = True
libenv.MergeFlags( "-DENABLE_BOUNCE" )
source += bounce_source
if env['ENABLE_GENERICAVC']:
libenv.MergeFlags( "-DENABLE_GENERICAVC" )
source += libavc_source
source += amdtp_source
source += genericavc_source
pkgdata += genericavc_pkgdata
if not env.GetOption( "clean" ):
libenv.MergeFlags( "-lrt -lpthread" )
libenv.MergeFlags( env['LIBRAW1394_FLAGS'].decode() )
libenv.MergeFlags( env['LIBIEC61883_FLAGS'].decode() )
libenv.MergeFlags( env['LIBCONFIG_FLAGS'].decode() )
if not env['SERIALIZE_USE_EXPAT']:
if 'LIBXML30_FLAGS' in env :
libenv.MergeFlags( env['LIBXML30_FLAGS'].decode() )
if not('LIBXML30_FLAGS' in env) :
libenv.MergeFlags( env['LIBXML26_FLAGS'].decode() )
else:
libenv.PrependUnique( LIBS=["expat"] )
libenv.MergeFlags( "-DSERIALIZE_USE_EXPAT" )
if env['REQUIRE_LIBAVC']:
libenv.MergeFlags( env['LIBAVC1394_FLAGS'].decode() )
libname_versioned = "libffado.so.%s" % libenv['VERSION']
libname_versioned_short = "libffado.so.%s" % libenv['VERSION'].split('.')[0]
libenv.MergeFlags( "-Wl,-soname=%s" % libname_versioned_short )
ffadolib = libenv.SharedLibrary( "ffado", source )
#libenv.Install( "$libdir", ffadolib )
installer = libenv.InstallAs ( "$libdir/%s" % libname_versioned , ffadolib )
# if stripping would be something for us
#libenv.AddPostAction(installer, [['strip', env['STRIPFLAGS'], t[0].path]])
# make the required links
libenv.NoCache( '$libdir/%s' % libname_versioned )
libenv.AddPostAction(installer, [['rm', '-f', '$libdir/libffado.so', '$libdir/%s' % libname_versioned_short],
['cd', '$libdir',
'&&','ln', '-s', libname_versioned_short, 'libffado.so',
'&&','ln', '-s', installer[0].name, libname_versioned_short,
]
])
if libenv['BUILD_STATIC_LIB']:
ffadolib_static = libenv.StaticLibrary( "ffado", source )
#
# Install the pkgdata to $sharedir
#
for data in pkgdata:
libenv.Install( "$sharedir", data )
#
# For the debugging apps
#
env2 = libenv.Clone()
env2.PrependUnique( LIBPATH=env['build_base']+"src" )
env2.PrependUnique( LIBS="ffado" )
apps = { \
"test-debugmodule" : "debugmodule/test_debugmodule.cpp", \
"test-dll" : "libutil/test-dll.cpp", \
"test-unittests-util" : "libutil/unittests.cpp", \
"test-cyclecalc" : "libieee1394/test-cyclecalc.cpp", \
}
installapps = []
for app in apps.keys():
env2.Program( target=app, source = env.Split( apps[app] ) )
if app.find( "test" ) == -1:
env2.Install( "$bindir", app )
libffado-2.4.7/src/bebob/ 0000755 0001750 0000144 00000000000 14340644626 014533 5 ustar jwoithe users libffado-2.4.7/src/bebob/bebob_avdevice.cpp 0000644 0001750 0000144 00000072535 14206145246 020165 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "config.h"
#include "devicemanager.h"
#include "bebob/bebob_avdevice.h"
#include "bebob/bebob_avdevice_subunit.h"
#include "bebob/bebob_mixer.h"
#include "bebob/focusrite/focusrite_saffire.h"
#include "bebob/focusrite/focusrite_saffirepro.h"
#include "bebob/terratec/terratec_device.h"
#include "bebob/mackie/onyxmixer.h"
#include "bebob/edirol/edirol_fa101.h"
#include "bebob/edirol/edirol_fa66.h"
#include "bebob/esi/quatafire610.h"
#include "bebob/yamaha/yamaha_avdevice.h"
#include "bebob/maudio/normal_avdevice.h"
#include "bebob/maudio/special_avdevice.h"
#include "bebob/presonus/firebox_avdevice.h"
#include "bebob/presonus/inspire1394_avdevice.h"
#include "libieee1394/configrom.h"
#include "libieee1394/ieee1394service.h"
#include "libavc/general/avc_plug_info.h"
#include "libavc/general/avc_extended_plug_info.h"
#include "libavc/general/avc_subunit_info.h"
#include "libavc/streamformat/avc_extended_stream_format.h"
#include "libutil/cmd_serialize.h"
#include "libavc/avc_definitions.h"
#include "debugmodule/debugmodule.h"
#include
#include
#include
#include
#include
#include
using namespace AVC;
namespace BeBoB {
Device::Device( DeviceManager& d, ffado_smartptr< ConfigRom >( configRom ) )
: GenericAVC::Device( d, configRom )
, m_last_discovery_config_id ( 0xFFFFFFFFFFFFFFFFLLU )
, m_Mixer ( 0 )
{
debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Device (NodeID %d)\n",
getConfigRom().getNodeId() );
}
Device::~Device()
{
destroyMixer();
}
bool
Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
{
unsigned int vendorId = configRom.getNodeVendorId();
unsigned int modelId = configRom.getModelId();
if(generic) {
/* M-Audio Special Devices don't support followed commands */
if ((vendorId == FW_VENDORID_MAUDIO) &&
((modelId == 0x00010071) || (modelId == 0x00010091)))
return true;
// try a bebob-specific command to check for the firmware
ExtendedPlugInfoCmd extPlugInfoCmd( configRom.get1394Service() );
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
configRom.getNodeId() );
extPlugInfoCmd.setPlugAddress( PlugAddress( PlugAddress::ePD_Input,
PlugAddress::ePAM_Unit,
unitPlugAddress ) );
extPlugInfoCmd.setNodeId( configRom.getNodeId() );
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
extPlugInfoCmd.setVerbose( configRom.getVerboseLevel() );
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_NoOfChannels );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
if ( !extPlugInfoCmd.fire() ) {
debugError( "Number of channels command failed\n" );
return false;
}
if((extPlugInfoCmd.getResponse() != AVCCommand::eR_Implemented)) {
// command not supported
return false;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugNrOfChns )
{
return true;
}
return false;
} else {
// check if device is in supported devices list
Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
return c.isValid(vme) && vme.driver == Util::Configuration::eD_BeBoB;
}
}
FFADODevice *
Device::createDevice(DeviceManager& d, ffado_smartptr( configRom ))
{
unsigned int vendorId = configRom->getNodeVendorId();
unsigned int modelId = configRom->getModelId();
switch (vendorId) {
case FW_VENDORID_MACKIE:
if (modelId == 0x00010065 ) {
return new Mackie::OnyxMixerDevice(d, configRom);
}
case FW_VENDORID_EDIROL:
switch (modelId) {
case 0x00010048:
return new Edirol::EdirolFa101Device(d, configRom);
case 0x00010049:
return new Edirol::EdirolFa66Device(d, configRom);
default:
return new Device(d, configRom);
}
case FW_VENDORID_ESI:
if (modelId == 0x00010064 || modelId == 0x00000210) {
return new ESI::QuataFireDevice(d, configRom);
}
break;
case FW_VENDORID_TERRATEC:
switch(modelId) {
case 0x00000003:
return new Terratec::Phase88Device(d, configRom);
default: // return a plain BeBoB device
return new Device(d, configRom);
}
case FW_VENDORID_FOCUSRITE:
switch(modelId) {
case 0x00000003:
case 0x00000006:
return new Focusrite::SaffireProDevice(d, configRom);
case 0x00000000:
return new Focusrite::SaffireDevice(d, configRom);
default: // return a plain BeBoB device
return new Device(d, configRom);
}
case FW_VENDORID_YAMAHA:
switch (modelId) {
case 0x0010000b:
case 0x0010000c:
return new Yamaha::GoDevice(d, configRom);
default: // return a plain BeBoB device
return new Device(d, configRom);
}
case FW_VENDORID_MAUDIO:
switch (modelId) {
case 0x0000000a: // Ozonic
case 0x00010046: // fw410
case 0x00010060: // Audiophile
case 0x00010062: // Solo
return new MAudio::Normal::Device(d, configRom, modelId);
case 0x00010071: // FireWire 1814
case 0x00010091: // ProjectMix I/O
return new MAudio::Special::Device(d, configRom);
default:
return new Device(d, configRom);
}
case FW_VENDORID_PRESONUS:
switch (modelId) {
case 0x00010000:
return new Presonus::Firebox::Device(d, configRom);
case 0x00010001:
return new Presonus::Inspire1394::Device(d, configRom);
default:
return new Device(d, configRom);
}
default:
return new Device(d, configRom);
}
return NULL;
}
#define BEBOB_CHECK_AND_ADD_SR(v, x) \
{ if(supportsSamplingFrequency(x)) \
v.push_back(x); }
bool
Device::discover()
{
unsigned int vendorId = getConfigRom().getNodeVendorId();
unsigned int modelId = getConfigRom().getModelId();
Util::Configuration &c = getDeviceManager().getConfiguration();
Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
if (c.isValid(vme) && vme.driver == Util::Configuration::eD_BeBoB) {
debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
vme.vendor_name.c_str(),
vme.model_name.c_str());
} else {
debugWarning("Using generic BeBoB support for unsupported device '%s %s'\n",
getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
}
if ( !Unit::discover() ) {
debugError( "Could not discover unit\n" );
return false;
}
if((getAudioSubunit( 0 ) == NULL)) {
debugError( "Unit doesn't have an Audio subunit.\n");
return false;
}
if((getMusicSubunit( 0 ) == NULL)) {
debugError( "Unit doesn't have a Music subunit.\n");
return false;
}
if(!buildMixer()) {
debugWarning("Could not build mixer\n");
}
// keep track of the config id of this discovery
m_last_discovery_config_id = getConfigurationId();
return true;
}
bool
Device::buildMixer()
{
debugOutput(DEBUG_LEVEL_VERBOSE, "Building a generic BeBoB mixer...\n");
// create a Mixer
// this removes the mixer if it already exists
// note: a mixer self-registers to it's parent
delete m_Mixer;
// create the mixer & register it
if(getAudioSubunit(0) == NULL) {
debugWarning("Could not find audio subunit, mixer not available.\n");
m_Mixer = NULL;
} else {
m_Mixer = new Mixer(*this);
}
if (m_Mixer) m_Mixer->setVerboseLevel(getDebugLevel());
return m_Mixer != NULL;
}
bool
Device::destroyMixer()
{
delete m_Mixer;
return true;
}
bool
Device::setSelectorFBValue(int id, int value) {
FunctionBlockCmd fbCmd( get1394Service(),
FunctionBlockCmd::eFBT_Selector,
id,
FunctionBlockCmd::eCA_Current );
fbCmd.setNodeId( getNodeId() );
fbCmd.setSubunitId( 0x00 );
fbCmd.setCommandType( AVCCommand::eCT_Control );
fbCmd.m_pFBSelector->m_inputFbPlugNumber = (value & 0xFF);
fbCmd.setVerboseLevel( getDebugLevel() );
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return false;
}
// if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
// Util::Cmd::CoutSerializer se;
// fbCmd.serialize( se );
// }
//
if((fbCmd.getResponse() != AVCCommand::eR_Accepted)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
}
return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
}
int
Device::getSelectorFBValue(int id) {
FunctionBlockCmd fbCmd( get1394Service(),
FunctionBlockCmd::eFBT_Selector,
id,
FunctionBlockCmd::eCA_Current );
fbCmd.setNodeId( getNodeId() );
fbCmd.setSubunitId( 0x00 );
fbCmd.setCommandType( AVCCommand::eCT_Status );
fbCmd.m_pFBSelector->m_inputFbPlugNumber = 0xFF;
fbCmd.setVerboseLevel( getDebugLevel() );
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return -1;
}
// if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
// Util::Cmd::CoutSerializer se;
// fbCmd.serialize( se );
// }
if((fbCmd.getResponse() != AVCCommand::eR_Implemented)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
}
return fbCmd.m_pFBSelector->m_inputFbPlugNumber;
}
bool
Device::setFeatureFBVolumeCurrent(int id, int channel, int v) {
FunctionBlockCmd fbCmd( get1394Service(),
FunctionBlockCmd::eFBT_Feature,
id,
FunctionBlockCmd::eCA_Current );
fbCmd.setNodeId( getNodeId() );
fbCmd.setSubunitId( 0x00 );
fbCmd.setCommandType( AVCCommand::eCT_Control );
fbCmd.m_pFBFeature->m_audioChannelNumber = channel;
fbCmd.m_pFBFeature->m_controlSelector = FunctionBlockFeature::eCSE_Feature_Volume;
AVC::FunctionBlockFeatureVolume vl;
fbCmd.m_pFBFeature->m_pVolume = vl.clone();
fbCmd.m_pFBFeature->m_pVolume->m_volume = v;
fbCmd.setVerboseLevel( getDebugLevel() );
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return false;
}
// if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
// Util::Cmd::CoutSerializer se;
// fbCmd.serialize( se );
// }
if((fbCmd.getResponse() != AVCCommand::eR_Accepted)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
}
return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
}
int
Device::getFeatureFBVolumeValue(int id, int channel, FunctionBlockCmd::EControlAttribute controlAttribute)
{
FunctionBlockCmd fbCmd( get1394Service(),
FunctionBlockCmd::eFBT_Feature,
id,
controlAttribute);
fbCmd.setNodeId( getNodeId() );
fbCmd.setSubunitId( 0x00 );
fbCmd.setCommandType( AVCCommand::eCT_Status );
fbCmd.m_pFBFeature->m_audioChannelNumber = channel;
fbCmd.m_pFBFeature->m_controlSelector = FunctionBlockFeature::eCSE_Feature_Volume;
AVC::FunctionBlockFeatureVolume vl;
fbCmd.m_pFBFeature->m_pVolume = vl.clone();
fbCmd.m_pFBFeature->m_pVolume->m_volume = 0;
fbCmd.setVerboseLevel( getDebugLevel() );
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return 0;
}
// if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
// Util::Cmd::CoutSerializer se;
// fbCmd.serialize( se );
// }
if((fbCmd.getResponse() != AVCCommand::eR_Implemented)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
}
int16_t volume=(int16_t)(fbCmd.m_pFBFeature->m_pVolume->m_volume);
return volume;
}
int
Device::getFeatureFBVolumeMinimum(int id, int channel)
{
return getFeatureFBVolumeValue(id, channel, AVC::FunctionBlockCmd::eCA_Minimum);
}
int
Device::getFeatureFBVolumeMaximum(int id, int channel)
{
return getFeatureFBVolumeValue(id, channel, AVC::FunctionBlockCmd::eCA_Maximum);
}
int
Device::getFeatureFBVolumeCurrent(int id, int channel)
{
return getFeatureFBVolumeValue(id, channel, AVC::FunctionBlockCmd::eCA_Current);
}
bool
Device::setFeatureFBLRBalanceCurrent(int id, int channel, int v) {
FunctionBlockCmd fbCmd( get1394Service(),
FunctionBlockCmd::eFBT_Feature,
id,
FunctionBlockCmd::eCA_Current );
fbCmd.setNodeId( getNodeId() );
fbCmd.setSubunitId( 0x00 );
fbCmd.setCommandType( AVCCommand::eCT_Control );
fbCmd.m_pFBFeature->m_audioChannelNumber = channel;
fbCmd.m_pFBFeature->m_controlSelector = FunctionBlockFeature::eCSE_Feature_LRBalance;
AVC::FunctionBlockFeatureLRBalance bl;
fbCmd.m_pFBFeature->m_pLRBalance = bl.clone();
fbCmd.m_pFBFeature->m_pLRBalance->m_lrBalance = v;
fbCmd.setVerboseLevel( getDebugLevel() );
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return false;
}
// if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
// Util::Cmd::CoutSerializer se;
// fbCmd.serialize( se );
// }
if((fbCmd.getResponse() != AVCCommand::eR_Accepted)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
}
return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
}
int
Device::getFeatureFBLRBalanceValue(int id, int channel, FunctionBlockCmd::EControlAttribute controlAttribute)
{
FunctionBlockCmd fbCmd( get1394Service(),
FunctionBlockCmd::eFBT_Feature,
id,
controlAttribute);
fbCmd.setNodeId( getNodeId() );
fbCmd.setSubunitId( 0x00 );
fbCmd.setCommandType( AVCCommand::eCT_Status );
fbCmd.m_pFBFeature->m_audioChannelNumber = channel;
fbCmd.m_pFBFeature->m_controlSelector = FunctionBlockFeature::eCSE_Feature_LRBalance;
AVC::FunctionBlockFeatureLRBalance bl;
fbCmd.m_pFBFeature->m_pLRBalance = bl.clone();
fbCmd.m_pFBFeature->m_pLRBalance->m_lrBalance = 0;
fbCmd.setVerboseLevel( getDebugLevel() );
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return 0;
}
// if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
// Util::Cmd::CoutSerializer se;
// fbCmd.serialize( se );
// }
if((fbCmd.getResponse() != AVCCommand::eR_Implemented)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
}
int16_t balance=(int16_t)(fbCmd.m_pFBFeature->m_pLRBalance->m_lrBalance);
return balance;
}
int
Device::getFeatureFBLRBalanceMinimum(int id, int channel)
{
return getFeatureFBLRBalanceValue(id, channel, AVC::FunctionBlockCmd::eCA_Minimum);
}
int
Device::getFeatureFBLRBalanceMaximum(int id, int channel)
{
return getFeatureFBLRBalanceValue(id, channel, AVC::FunctionBlockCmd::eCA_Maximum);
}
int
Device::getFeatureFBLRBalanceCurrent(int id, int channel)
{
return getFeatureFBLRBalanceValue(id, channel, AVC::FunctionBlockCmd::eCA_Current);
}
bool
Device::setProcessingFBMixerSingleCurrent(int id, int iPlugNum,
int iAChNum, int oAChNum,
int setting)
{
AVC::FunctionBlockCmd fbCmd(get1394Service(),
AVC::FunctionBlockCmd::eFBT_Processing,
id,
AVC::FunctionBlockCmd::eCA_Current);
fbCmd.setNodeId(getNodeId());
fbCmd.setSubunitId(0x00);
fbCmd.setCommandType(AVCCommand::eCT_Control);
fbCmd.setVerboseLevel( getDebugLevel() );
AVC::FunctionBlockProcessing *fbp = fbCmd.m_pFBProcessing;
fbp->m_selectorLength = 0x04;
fbp->m_fbInputPlugNumber = iPlugNum;
fbp->m_inputAudioChannelNumber = iAChNum;
fbp->m_outputAudioChannelNumber = oAChNum;
// mixer object is not generated automatically
fbp->m_pMixer = new AVC::FunctionBlockProcessingMixer;
fbp->m_pMixer->m_mixerSetting = setting;
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return false;
}
if((fbCmd.getResponse() != AVCCommand::eR_Accepted)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Accepted\n");
}
return (fbCmd.getResponse() == AVCCommand::eR_Accepted);
}
int
Device::getProcessingFBMixerSingleCurrent(int id, int iPlugNum,
int iAChNum, int oAChNum)
{
AVC::FunctionBlockCmd fbCmd(get1394Service(),
AVC::FunctionBlockCmd::eFBT_Processing,
id,
AVC::FunctionBlockCmd::eCA_Current);
fbCmd.setNodeId(getNodeId());
fbCmd.setSubunitId(0x00);
fbCmd.setCommandType(AVCCommand::eCT_Status);
fbCmd.setVerboseLevel( getDebugLevel() );
AVC::FunctionBlockProcessing *fbp = fbCmd.m_pFBProcessing;
fbp->m_selectorLength = 0x04;
fbp->m_fbInputPlugNumber = iPlugNum;
fbp->m_inputAudioChannelNumber = iAChNum;
fbp->m_outputAudioChannelNumber = oAChNum;
// mixer object is not generated automatically
fbp->m_pMixer = new AVC::FunctionBlockProcessingMixer;
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return 0;
}
if( (fbCmd.getResponse() != AVCCommand::eR_Implemented) ) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
}
int16_t setting = (int16_t)(fbp->m_pMixer->m_mixerSetting);
return setting;
}
void
Device::showDevice()
{
debugOutput(DEBUG_LEVEL_NORMAL, "Device is a BeBoB device\n");
GenericAVC::Device::showDevice();
flushDebugOutput();
}
void
Device::setVerboseLevel(int l)
{
if (m_Mixer) m_Mixer->setVerboseLevel( l );
GenericAVC::Device::setVerboseLevel( l );
debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
}
AVC::Subunit*
Device::createSubunit(AVC::Unit& unit,
AVC::ESubunitType type,
AVC::subunit_t id )
{
AVC::Subunit* s=NULL;
switch (type) {
case eST_Audio:
s=new BeBoB::SubunitAudio(unit, id );
break;
case eST_Music:
s=new BeBoB::SubunitMusic(unit, id );
break;
default:
s=NULL;
break;
}
if(s) s->setVerboseLevel(getDebugLevel());
return s;
}
AVC::Plug *
Device::createPlug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId,
int globalId )
{
Plug *p= new BeBoB::Plug( unit,
subunit,
functionBlockType,
functionBlockId,
plugAddressType,
plugDirection,
plugId,
globalId );
if (p) p->setVerboseLevel(getDebugLevel());
return p;
}
bool
Device::propagatePlugInfo() {
// we don't have to propagate since we discover things
// another way
debugOutput(DEBUG_LEVEL_VERBOSE, "Skip plug info propagation\n");
return true;
}
uint8_t
Device::getConfigurationIdSampleRate()
{
ExtendedStreamFormatCmd extStreamFormatCmd( get1394Service() );
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 0 );
extStreamFormatCmd.setPlugAddress( PlugAddress( PlugAddress::ePD_Input,
PlugAddress::ePAM_Unit,
unitPlugAddress ) );
extStreamFormatCmd.setNodeId( getNodeId() );
extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
extStreamFormatCmd.setVerbose( getDebugLevel() );
if ( !extStreamFormatCmd.fire() ) {
debugError( "Stream format command failed\n" );
return 0;
}
FormatInformation* formatInfo =
extStreamFormatCmd.getFormatInformation();
FormatInformationStreamsCompound* compoundStream
= dynamic_cast< FormatInformationStreamsCompound* > (
formatInfo->m_streams );
if ( compoundStream ) {
debugOutput(DEBUG_LEVEL_VERBOSE, "Sample rate 0x%02x\n",
compoundStream->m_samplingFrequency );
return compoundStream->m_samplingFrequency;
}
debugError( "Could not retrieve sample rate\n" );
return 0;
}
uint8_t
Device::getConfigurationIdNumberOfChannel( PlugAddress::EPlugDirection ePlugDirection )
{
ExtendedPlugInfoCmd extPlugInfoCmd( get1394Service() );
UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
0 );
extPlugInfoCmd.setPlugAddress( PlugAddress( ePlugDirection,
PlugAddress::ePAM_Unit,
unitPlugAddress ) );
extPlugInfoCmd.setNodeId( getNodeId() );
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
extPlugInfoCmd.setVerbose( getDebugLevel() );
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_NoOfChannels );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
if ( !extPlugInfoCmd.fire() ) {
debugError( "Number of channels command failed\n" );
return 0;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugNrOfChns )
{
debugOutput(DEBUG_LEVEL_VERBOSE, "Number of channels 0x%02x\n",
infoType->m_plugNrOfChns->m_nrOfChannels );
return infoType->m_plugNrOfChns->m_nrOfChannels;
}
debugError( "Could not retrieve number of channels\n" );
return 0;
}
uint16_t
Device::getConfigurationIdSyncMode()
{
SignalSourceCmd signalSourceCmd( get1394Service() );
SignalUnitAddress signalUnitAddr;
signalUnitAddr.m_plugId = 0x01;
signalSourceCmd.setSignalDestination( signalUnitAddr );
signalSourceCmd.setNodeId( getNodeId() );
signalSourceCmd.setSubunitType( eST_Unit );
signalSourceCmd.setSubunitId( 0xff );
signalSourceCmd.setVerbose( getDebugLevel() );
signalSourceCmd.setCommandType( AVCCommand::eCT_Status );
if ( !signalSourceCmd.fire() ) {
debugError( "Signal source command failed\n" );
return 0;
}
SignalAddress* pSyncPlugSignalAddress = signalSourceCmd.getSignalSource();
SignalSubunitAddress* pSyncPlugSubunitAddress
= dynamic_cast( pSyncPlugSignalAddress );
if ( pSyncPlugSubunitAddress ) {
debugOutput(DEBUG_LEVEL_VERBOSE, "Sync mode 0x%02x\n",
( pSyncPlugSubunitAddress->m_subunitType << 3
| pSyncPlugSubunitAddress->m_subunitId ) << 8
| pSyncPlugSubunitAddress->m_plugId );
return ( pSyncPlugSubunitAddress->m_subunitType << 3
| pSyncPlugSubunitAddress->m_subunitId ) << 8
| pSyncPlugSubunitAddress->m_plugId;
}
SignalUnitAddress* pSyncPlugUnitAddress
= dynamic_cast( pSyncPlugSignalAddress );
if ( pSyncPlugUnitAddress ) {
debugOutput(DEBUG_LEVEL_VERBOSE, "Sync mode 0x%02x\n",
0xff << 8 | pSyncPlugUnitAddress->m_plugId );
return ( 0xff << 8 | pSyncPlugUnitAddress->m_plugId );
}
debugError( "Could not retrieve sync mode\n" );
return 0;
}
bool
Device::needsRediscovery()
{
// require rediscovery if the config id differs from the one saved
// in the previous discovery
return getConfigurationId() != m_last_discovery_config_id;
}
uint64_t
Device::getConfigurationId()
{
// create a unique configuration id.
uint64_t id = 0;
id = getConfigurationIdSampleRate();
id |= getConfigurationIdNumberOfChannel( PlugAddress::ePD_Input ) << 8;
id |= getConfigurationIdNumberOfChannel( PlugAddress::ePD_Output ) << 16;
id |= ((uint64_t)getConfigurationIdSyncMode()) << 24;
return id;
}
bool
Device::serialize( std::string basePath,
Util::IOSerialize& ser ) const
{
bool result;
result = GenericAVC::Device::serialize( basePath, ser );
return result;
}
bool
Device::deserialize( std::string basePath,
Util::IODeserialize& deser )
{
bool result;
result = GenericAVC::Device::deserialize( basePath, deser );
return result;
}
std::string
Device::getCachePath()
{
std::string cachePath;
char* pCachePath;
string path = CACHEDIR;
if ( path.size() && path[0] == '~' ) {
path.erase( 0, 1 ); // remove ~
path.insert( 0, getenv( "HOME" ) ); // prepend the home path
}
if ( asprintf( &pCachePath, "%s/cache/", path.c_str() ) < 0 ) {
debugError( "Could not create path string for cache pool (trying '/var/cache/libffado' instead)\n" );
cachePath = "/var/cache/libffado/";
} else {
cachePath = pCachePath;
free( pCachePath );
}
return cachePath;
}
bool
Device::loadFromCache()
{
std::string sDevicePath = getCachePath() + getConfigRom().getGuidString();
char* configId;
asprintf(&configId, "%016" PRIx64 "", getConfigurationId() );
if ( !configId ) {
debugError( "could not create id string\n" );
return false;
}
std::string sFileName = sDevicePath + "/" + configId + ".xml";
free( configId );
debugOutput( DEBUG_LEVEL_NORMAL, "filename %s\n", sFileName.c_str() );
struct stat buf;
if ( stat( sFileName.c_str(), &buf ) != 0 ) {
debugOutput( DEBUG_LEVEL_NORMAL, "\"%s\" does not exist\n", sFileName.c_str() );
return false;
} else {
if ( !S_ISREG( buf.st_mode ) ) {
debugOutput( DEBUG_LEVEL_NORMAL, "\"%s\" is not a regular file\n", sFileName.c_str() );
return false;
}
}
Util::XMLDeserialize deser( sFileName, getDebugLevel() );
if (!deser.isValid()) {
debugOutput( DEBUG_LEVEL_NORMAL, "cache not valid: %s\n",
sFileName.c_str() );
return false;
}
bool result = deserialize( "", deser );
if ( result ) {
debugOutput( DEBUG_LEVEL_NORMAL, "could create valid bebob driver from %s\n",
sFileName.c_str() );
}
if(result) {
buildMixer();
}
return result;
}
bool
Device::saveCache()
{
// the path looks like this:
// PATH_TO_CACHE + GUID + CONFIGURATION_ID
string tmp_path = getCachePath() + getConfigRom().getGuidString();
// the following piece should do something like
// 'mkdir -p some/path/with/some/dirs/which/do/not/exist'
vector tokens;
tokenize( tmp_path, tokens, "/" );
string path;
for ( vector::const_iterator it = tokens.begin();
it != tokens.end();
++it )
{
path += "/" + *it;
struct stat buf;
if ( stat( path.c_str(), &buf ) == 0 ) {
if ( !S_ISDIR( buf.st_mode ) ) {
debugError( "\"%s\" is not a directory\n", path.c_str() );
return false;
}
} else {
if ( mkdir( path.c_str(), S_IRWXU | S_IRWXG ) != 0 ) {
debugError( "Could not create \"%s\" directory\n", path.c_str() );
return false;
}
}
}
// come up with an unique file name for the current settings
char* configId;
asprintf(&configId, "%016" PRIx64 "", BeBoB::Device::getConfigurationId() );
if ( !configId ) {
debugError( "Could not create id string\n" );
return false;
}
string filename = path + "/" + configId + ".xml";
free( configId );
debugOutput( DEBUG_LEVEL_NORMAL, "filename %s\n", filename.c_str() );
Util::XMLSerialize ser( filename );
return serialize( "", ser );
}
} // end of namespace
libffado-2.4.7/src/bebob/bebob_avdevice.h 0000644 0001750 0000144 00000011603 14206145246 017617 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_DEVICE_H
#define BEBOB_DEVICE_H
#include
#include "debugmodule/debugmodule.h"
#include "libieee1394/configrom.h"
#include "libieee1394/ieee1394service.h"
#include "libavc/avc_definitions.h"
#include "libavc/general/avc_extended_cmd_generic.h"
#include "libavc/general/avc_unit.h"
#include "libavc/general/avc_subunit.h"
#include "libavc/general/avc_plug.h"
#include "libavc/audiosubunit/avc_function_block.h"
#include "bebob/bebob_avplug.h"
#include "bebob/bebob_avdevice_subunit.h"
#include "bebob/bebob_mixer.h"
#include "libstreaming/amdtp/AmdtpReceiveStreamProcessor.h"
#include "libstreaming/amdtp/AmdtpTransmitStreamProcessor.h"
#include "libstreaming/amdtp/AmdtpPort.h"
#include "libstreaming/amdtp/AmdtpPortInfo.h"
#include "libutil/serialize.h"
#include "genericavc/avc_avdevice.h"
#include "ffadodevice.h"
#include
#include
namespace BeBoB {
class Device : public GenericAVC::Device {
public:
Device( DeviceManager& d, ffado_smartptr( configRom ));
virtual ~Device();
static bool probe( Util::Configuration&, ConfigRom& configRom, bool generic = false );
virtual bool loadFromCache();
virtual bool saveCache();
virtual bool discover();
static FFADODevice * createDevice( DeviceManager& d, ffado_smartptr( configRom ));
virtual AVC::Subunit* createSubunit(AVC::Unit& unit,
AVC::ESubunitType type,
AVC::subunit_t id );
virtual AVC::Plug *createPlug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId,
int globalId = -1 );
virtual int getSelectorFBValue(int id);
virtual bool setSelectorFBValue(int id, int v);
virtual int getFeatureFBVolumeMinimum(int id, int channel);
virtual int getFeatureFBVolumeMaximum(int id, int channel);
virtual int getFeatureFBVolumeCurrent(int id, int channel);
virtual bool setFeatureFBVolumeCurrent(int id, int channel, int v);
virtual int getFeatureFBLRBalanceMinimum(int id, int channel);
virtual int getFeatureFBLRBalanceMaximum(int id, int channel);
virtual int getFeatureFBLRBalanceCurrent(int id, int channel);
virtual bool setFeatureFBLRBalanceCurrent(int id, int channel, int v);
virtual bool setProcessingFBMixerSingleCurrent(int id, int iPlugNum,
int iAChNum, int oAChNum,
int setting);
virtual int getProcessingFBMixerSingleCurrent(int id, int iPlugNum,
int iAChNum, int oAChNum);
virtual void showDevice();
virtual void setVerboseLevel(int l);
protected:
virtual bool propagatePlugInfo();
virtual bool buildMixer();
virtual bool destroyMixer();
virtual int getFeatureFBVolumeValue(int id, int channel, AVC::FunctionBlockCmd::EControlAttribute controlAttribute);
virtual int getFeatureFBLRBalanceValue(int id, int channel, AVC::FunctionBlockCmd::EControlAttribute controlAttribute);
public:
virtual bool serialize( std::string basePath, Util::IOSerialize& ser ) const;
virtual bool deserialize( std::string basePath, Util::IODeserialize& deser );
virtual uint64_t getConfigurationId();
virtual bool needsRediscovery();
std::string getCachePath();
protected:
virtual uint8_t getConfigurationIdSampleRate();
virtual uint8_t getConfigurationIdNumberOfChannel( AVC::PlugAddress::EPlugDirection ePlugDirection );
virtual uint16_t getConfigurationIdSyncMode();
std::vector m_supported_frequencies;
uint64_t m_last_discovery_config_id;
protected:
Mixer* m_Mixer;
};
}
#endif
libffado-2.4.7/src/bebob/bebob_avdevice_subunit.cpp 0000644 0001750 0000144 00000034361 14206145246 021731 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "bebob/bebob_functionblock.h"
#include "bebob/bebob_avdevice_subunit.h"
#include "bebob/bebob_avdevice.h"
#include "bebob/bebob_avplug.h"
#include "libieee1394/configrom.h"
#include "libavc/general/avc_plug_info.h"
#include "libavc/streamformat/avc_extended_stream_format.h"
#include "libutil/cmd_serialize.h"
#include
using namespace AVC;
//////////////////////////
BeBoB::SubunitAudio::SubunitAudio( AVC::Unit& avDevice,
subunit_t id )
: AVC::SubunitAudio( avDevice, id )
{
}
BeBoB::SubunitAudio::SubunitAudio()
: AVC::SubunitAudio()
{
}
BeBoB::SubunitAudio::~SubunitAudio()
{
for ( FunctionBlockVector::iterator it = m_functions.begin();
it != m_functions.end();
++it )
{
delete *it;
}
}
AVC::Plug *
BeBoB::SubunitAudio::createPlug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId )
{
return new BeBoB::Plug( unit,
subunit,
functionBlockType,
functionBlockId,
plugAddressType,
plugDirection,
plugId );
}
bool
BeBoB::SubunitAudio::discover()
{
debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName());
// discover the AV/C generic part
if ( !AVC::SubunitAudio::discover() ) {
return false;
}
// do the remaining BeBoB audio subunit discovery
if ( !discoverFunctionBlocks() ) {
debugError( "function block discovering failed\n" );
return false;
}
return true;
}
bool
BeBoB::SubunitAudio::discoverConnections()
{
debugOutput(DEBUG_LEVEL_NORMAL, "Discovering connections...\n");
if ( !Subunit::discoverConnections() ) {
return false;
}
for ( FunctionBlockVector::iterator it = m_functions.begin();
it != m_functions.end();
++it )
{
FunctionBlock* function = *it;
if ( !function->discoverConnections() ) {
debugError( "functionblock connection discovering failed ('%s')\n",
function->getName() );
return false;
}
}
return true;
}
const char*
BeBoB::SubunitAudio::getName()
{
return "BeBoB::AudioSubunit";
}
bool
BeBoB::SubunitAudio::discoverFunctionBlocks()
{
debugOutput( DEBUG_LEVEL_NORMAL,
"Discovering function blocks...\n");
if ( !discoverFunctionBlocksDo(
ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector) )
{
debugError( "Could not discover function block selector\n" );
return false;
}
if ( !discoverFunctionBlocksDo(
ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature) )
{
debugError( "Could not discover function block feature\n" );
return false;
}
if ( !discoverFunctionBlocksDo(
ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing) )
{
debugError( "Could not discover function block processing\n" );
return false;
}
if ( !discoverFunctionBlocksDo(
ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec) )
{
debugError( "Could not discover function block codec\n" );
return false;
}
// print a function block list
#ifdef DEBUG
if ((int)getDebugLevel() >= DEBUG_LEVEL_NORMAL) {
for ( FunctionBlockVector::iterator it = m_functions.begin();
it != m_functions.end();
++it )
{
debugOutput(DEBUG_LEVEL_NORMAL, "%20s FB, type 0x%X, id=%d\n",
(*it)->getName(),
(*it)->getType(),
(*it)->getId());
}
}
#endif
return true;
}
bool
BeBoB::SubunitAudio::discoverFunctionBlocksDo(
ExtendedSubunitInfoCmd::EFunctionBlockType fbType )
{
int page = 0;
bool cmdSuccess = false;
bool finished = false;
do {
ExtendedSubunitInfoCmd
extSubunitInfoCmd( m_unit->get1394Service() );
extSubunitInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() );
extSubunitInfoCmd.setCommandType( AVCCommand::eCT_Status );
extSubunitInfoCmd.setSubunitId( getSubunitId() );
extSubunitInfoCmd.setSubunitType( getSubunitType() );
extSubunitInfoCmd.setVerbose( (int)getDebugLevel() );
extSubunitInfoCmd.m_fbType = fbType;
extSubunitInfoCmd.m_page = page;
cmdSuccess = extSubunitInfoCmd.fire();
if ( cmdSuccess
&& ( extSubunitInfoCmd.getResponse()
== AVCCommand::eR_Implemented ) )
{
for ( ExtendedSubunitInfoPageDataVector::iterator it =
extSubunitInfoCmd.m_infoPageDatas.begin();
cmdSuccess
&& ( it != extSubunitInfoCmd.m_infoPageDatas.end() );
++it )
{
cmdSuccess = createFunctionBlock( fbType, **it );
}
if ( ( extSubunitInfoCmd.m_infoPageDatas.size() != 0 )
&& ( extSubunitInfoCmd.m_infoPageDatas.size() == 5 ) )
{
page++;
} else {
finished = true;
}
} else {
finished = true;
}
} while ( cmdSuccess && !finished );
return cmdSuccess;
}
bool
BeBoB::SubunitAudio::createFunctionBlock(
ExtendedSubunitInfoCmd::EFunctionBlockType fbType,
ExtendedSubunitInfoPageData& data )
{
FunctionBlock::ESpecialPurpose purpose
= convertSpecialPurpose( data.m_functionBlockSpecialPupose );
FunctionBlock* fb = 0;
switch ( fbType ) {
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector:
{
fb = new FunctionBlockSelector( *this,
data.m_functionBlockId,
purpose,
data.m_noOfInputPlugs,
data.m_noOfOutputPlugs,
(int)getDebugLevel() );
}
break;
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature:
{
fb = new FunctionBlockFeature( *this,
data.m_functionBlockId,
purpose,
data.m_noOfInputPlugs,
data.m_noOfOutputPlugs,
(int)getDebugLevel() );
}
break;
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing:
{
switch ( data.m_functionBlockType ) {
case ExtendedSubunitInfoCmd::ePT_EnhancedMixer:
{
fb = new FunctionBlockEnhancedMixer( *this,
data.m_functionBlockId,
purpose,
data.m_noOfInputPlugs,
data.m_noOfOutputPlugs,
(int)getDebugLevel() );
}
break;
case ExtendedSubunitInfoCmd::ePT_Mixer:
case ExtendedSubunitInfoCmd::ePT_Generic:
case ExtendedSubunitInfoCmd::ePT_UpDown:
case ExtendedSubunitInfoCmd::ePT_DolbyProLogic:
case ExtendedSubunitInfoCmd::ePT_3DStereoExtender:
case ExtendedSubunitInfoCmd::ePT_Reverberation:
case ExtendedSubunitInfoCmd::ePT_Chorus:
case ExtendedSubunitInfoCmd::ePT_DynamicRangeCompression:
default:
/* It is no use to add a dummy FunctionBlockProcessing because
then the function type is not set in FunctionBlockProcessing.
When we try to discover the plugs attached to this function block
it will fail. It's better just to skip them. */
debugOutput( DEBUG_LEVEL_NORMAL, "Found a processing subfunction (type %d) which is not supported. "
"It will be ignored.\n",
data.m_functionBlockType);
return true;
}
}
break;
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec:
{
/* It is no use to add a dummy FunctionBlockProcessing because
then the function type is not set in FunctionBlockProcessing.
When we try to discover the plugs attached to this function block
it will fail. It's better just to skip them. */
debugOutput( DEBUG_LEVEL_NORMAL, "Found a codec subfunction (type %d) which is not supported. "
"It will be ignored.\n",
data.m_functionBlockType);
return true;
}
break;
default:
debugError( "Unhandled function block type found\n" );
return false;
}
if ( !fb ) {
debugError( "Could create function block\n" );
return false;
}
if ( !fb->discover() ) {
debugError( "Could not discover function block %s\n",
fb->getName() );
delete fb;
return false;
}
m_functions.push_back( fb );
return true;
}
BeBoB::FunctionBlock::ESpecialPurpose
BeBoB::SubunitAudio::convertSpecialPurpose(
function_block_special_purpose_t specialPurpose )
{
FunctionBlock::ESpecialPurpose p;
switch ( specialPurpose ) {
case ExtendedSubunitInfoPageData::eSP_InputGain:
p = FunctionBlock::eSP_InputGain;
break;
case ExtendedSubunitInfoPageData::eSP_OutputVolume:
p = FunctionBlock::eSP_OutputVolume;
break;
default:
p = FunctionBlock::eSP_NoSpecialPurpose;
}
return p;
}
bool
BeBoB::SubunitAudio::serializeChild( std::string basePath,
Util::IOSerialize& ser ) const
{
bool result = true;
int i = 0;
for ( FunctionBlockVector::const_iterator it = m_functions.begin();
it != m_functions.end();
++it )
{
FunctionBlock* pFB = *it;
std::ostringstream strstrm;
strstrm << basePath << "FunctionBlock" << i << "/";
result &= pFB->serialize( strstrm.str() , ser );
i++;
}
return result;
}
bool
BeBoB::SubunitAudio::deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AVC::Unit& avDevice )
{
int i = 0;
bool bFinished = false;
do {
std::ostringstream strstrm;
strstrm << basePath << "FunctionBlock" << i << "/";
FunctionBlock* pFB = FunctionBlock::deserialize( strstrm.str(),
deser,
avDevice,
*this );
if ( pFB ) {
m_functions.push_back( pFB );
i++;
} else {
bFinished = true;
}
} while ( !bFinished );
return true;
}
bool
BeBoB::SubunitAudio::deserializeUpdateChild( std::string basePath,
Util::IODeserialize& deser )
{
bool result = true;
int i = 0;
for ( FunctionBlockVector::iterator it = m_functions.begin();
it != m_functions.end();
++it )
{
std::ostringstream strstrm;
strstrm << basePath << "FunctionBlock" << i << "/";
result &= (*it)->deserializeUpdate( basePath, deser );
i++;
}
return result;
}
////////////////////////////////////////////
BeBoB::SubunitMusic::SubunitMusic( AVC::Unit& avDevice,
subunit_t id )
: AVC::SubunitMusic( avDevice, id )
{
}
BeBoB::SubunitMusic::SubunitMusic()
: AVC::SubunitMusic()
{
}
BeBoB::SubunitMusic::~SubunitMusic()
{
}
AVC::Plug *
BeBoB::SubunitMusic::createPlug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId )
{
return new BeBoB::Plug( unit,
subunit,
functionBlockType,
functionBlockId,
plugAddressType,
plugDirection,
plugId );
}
bool
BeBoB::SubunitMusic::discover()
{
debugOutput(DEBUG_LEVEL_NORMAL, "Discovering %s...\n", getName());
// discover the AV/C generic part
if ( !AVC::SubunitMusic::discover() ) {
return false;
}
// do the remaining BeBoB music subunit discovery
// which is nothing
return true;
}
const char*
BeBoB::SubunitMusic::getName()
{
return "BeBoB::MusicSubunit";
}
bool
BeBoB::SubunitMusic::serializeChild( std::string basePath,
Util::IOSerialize& ser ) const
{
return true;
}
bool
BeBoB::SubunitMusic::deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AVC::Unit& avDevice )
{
return true;
}
bool
BeBoB::SubunitMusic::deserializeUpdateChild( std::string basePath,
Util::IODeserialize& deser )
{
return true;
}
libffado-2.4.7/src/bebob/bebob_avdevice_subunit.h 0000644 0001750 0000144 00000010407 14206145246 021371 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_AVDEVICESUBUNIT_H
#define BEBOB_AVDEVICESUBUNIT_H
#include "bebob/bebob_avplug.h"
#include "bebob/bebob_functionblock.h"
#include "debugmodule/debugmodule.h"
#include "libavc/general/avc_extended_subunit_info.h"
#include "libavc/avc_definitions.h"
#include "libavc/general/avc_generic.h"
#include
#include "libavc/general/avc_subunit.h"
#include "libavc/musicsubunit/avc_musicsubunit.h"
#include "libavc/audiosubunit/avc_audiosubunit.h"
#include "libavc/general/avc_plug.h"
namespace BeBoB {
/////////////////////////////
class SubunitAudio : public AVC::SubunitAudio
{
public:
SubunitAudio( AVC::Unit& avDevice,
AVC::subunit_t id );
SubunitAudio();
virtual ~SubunitAudio();
virtual bool discover();
virtual bool discoverConnections();
virtual AVC::Plug *createPlug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId );
virtual const char* getName();
virtual FunctionBlockVector getFunctionBlocks() { return m_functions; };
protected:
bool discoverFunctionBlocks();
bool discoverFunctionBlocksDo(
AVC::ExtendedSubunitInfoCmd::EFunctionBlockType fbType );
bool createFunctionBlock(
AVC::ExtendedSubunitInfoCmd::EFunctionBlockType fbType,
AVC::ExtendedSubunitInfoPageData& data );
FunctionBlock::ESpecialPurpose convertSpecialPurpose(
AVC::function_block_special_purpose_t specialPurpose );
virtual bool serializeChild( std::string basePath,
Util::IOSerialize& ser ) const;
virtual bool deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AVC::Unit& unit );
virtual bool deserializeUpdateChild( std::string basePath,
Util::IODeserialize& deser );
protected:
FunctionBlockVector m_functions;
};
/////////////////////////////
class SubunitMusic : public AVC::SubunitMusic
{
public:
SubunitMusic( AVC::Unit& avDevice,
AVC::subunit_t id );
SubunitMusic();
virtual ~SubunitMusic();
virtual bool discover();
virtual AVC::Plug *createPlug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId );
virtual const char* getName();
protected:
virtual bool serializeChild( std::string basePath,
Util::IOSerialize& ser ) const;
virtual bool deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AVC::Unit& unit );
virtual bool deserializeUpdateChild( std::string basePath,
Util::IODeserialize& deser );
};
}
#endif
libffado-2.4.7/src/bebob/bebob_avplug.cpp 0000644 0001750 0000144 00000055507 14206145246 017675 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "bebob/bebob_avplug.h"
#include "bebob/bebob_avdevice.h"
#include "libieee1394/configrom.h"
#include "libieee1394/ieee1394service.h"
#include "libutil/cmd_serialize.h"
#include
using namespace AVC;
namespace BeBoB {
Plug::Plug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId )
: AVC::Plug( unit,
subunit,
functionBlockType,
functionBlockId,
plugAddressType,
plugDirection,
plugId )
{
debugOutput( DEBUG_LEVEL_VERBOSE,
"nodeId = %d, subunitType = %d, "
"subunitId = %d, functionBlockType = %d, "
"functionBlockId = %d, addressType = %d, "
"direction = %d, id = %d\n",
unit->getConfigRom().getNodeId(),
getSubunitType(),
getSubunitId(),
functionBlockType,
functionBlockId,
plugAddressType,
plugDirection,
plugId );
}
Plug::Plug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId,
int globalId )
: AVC::Plug( unit,
subunit,
functionBlockType,
functionBlockId,
plugAddressType,
plugDirection,
plugId,
globalId )
{
debugOutput( DEBUG_LEVEL_VERBOSE,
"nodeId = %d, subunitType = %d, "
"subunitId = %d, functionBlockType = %d, "
"functionBlockId = %d, addressType = %d, "
"direction = %d, id = %d\n",
unit->getConfigRom().getNodeId(),
getSubunitType(),
getSubunitId(),
functionBlockType,
functionBlockId,
plugAddressType,
plugDirection,
plugId );
}
Plug::Plug( const Plug& rhs )
: AVC::Plug( rhs )
{
}
Plug::Plug()
: AVC::Plug()
{
}
Plug::~Plug()
{
}
bool
Plug::discover()
{
if ( !discoverPlugType() ) {
debugError( "discover: Could not discover plug type (%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
if ( !discoverName() ) {
debugError( "Could not discover name (%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
if ( !discoverNoOfChannels() ) {
debugError( "Could not discover number of channels "
"(%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
if ( !discoverChannelPosition() ) {
debugError( "Could not discover channel positions "
"(%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
if ( !discoverChannelName() ) {
debugError( "Could not discover channel name "
"(%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
if ( !discoverClusterInfo() ) {
debugError( "Could not discover channel name "
"(%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
if ( !discoverStreamFormat() ) {
debugError( "Could not discover stream format "
"(%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
if ( !discoverSupportedStreamFormats() ) {
debugError( "Could not discover supported stream formats "
"(%d,%d,%d,%d,%d)\n",
m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
return false;
}
return m_unit->getPlugManager().addPlug( *this );
}
bool
Plug::discoverConnections()
{
return discoverConnectionsInput() && discoverConnectionsOutput();
}
bool
Plug::discoverPlugType()
{
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_PlugType );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
if ( !extPlugInfoCmd.fire() ) {
debugError( "plug type command failed\n" );
return false;
}
m_infoPlugType = eAPT_Unknown;
if ( extPlugInfoCmd.getResponse() == AVCCommand::eR_Implemented ) {
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugType )
{
plug_type_t plugType = infoType->m_plugType->m_plugType;
debugOutput( DEBUG_LEVEL_VERBOSE,
"plug %d is of type %d (%s)\n",
m_id,
plugType,
extendedPlugInfoPlugTypeToString( plugType ) );
switch ( plugType ) {
case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_IsoStream:
m_infoPlugType = eAPT_IsoStream;
break;
case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_AsyncStream:
m_infoPlugType = eAPT_AsyncStream;
break;
case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Midi:
m_infoPlugType = eAPT_Midi;
break;
case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Sync:
m_infoPlugType = eAPT_Sync;
break;
case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Analog:
m_infoPlugType = eAPT_Analog;
break;
case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Digital:
m_infoPlugType = eAPT_Digital;
break;
default:
m_infoPlugType = eAPT_Unknown;
}
}
} else {
debugError( "Plug does not implement extended plug info plug "
"type info command\n" );
return false;
}
return true;
}
bool
Plug::discoverName()
{
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_PlugName );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
if ( !extPlugInfoCmd.fire() ) {
debugError( "name command failed\n" );
return false;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugName )
{
std::string name =
infoType->m_plugName->m_name;
debugOutput( DEBUG_LEVEL_VERBOSE,
"plug %d has name '%s'\n",
m_id,
name.c_str() );
m_name = name;
}
return true;
}
bool
Plug::discoverNoOfChannels()
{
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
//extPlugInfoCmd.setVerbose( true );
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_NoOfChannels );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
if ( !extPlugInfoCmd.fire() ) {
debugError( "number of channels command failed\n" );
return false;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugNrOfChns )
{
nr_of_channels_t nrOfChannels
= infoType->m_plugNrOfChns->m_nrOfChannels;
debugOutput( DEBUG_LEVEL_VERBOSE,
"plug %d has %d channels\n",
m_id,
nrOfChannels );
m_nrOfChannels = nrOfChannels;
}
return true;
}
bool
Plug::discoverChannelPosition()
{
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_ChannelPosition );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
if ( !extPlugInfoCmd.fire() ) {
debugError( "channel position command failed\n" );
return false;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugChannelPosition )
{
if ( !copyClusterInfo( *( infoType->m_plugChannelPosition ) ) ) {
debugError( "Could not copy channel position "
"information\n" );
return false;
}
debugOutput( DEBUG_LEVEL_VERBOSE,
"plug %d: channel position information "
"retrieved\n",
m_id );
debugOutputClusterInfos( DEBUG_LEVEL_VERBOSE );
}
return true;
}
bool
Plug::copyClusterInfo(ExtendedPlugInfoPlugChannelPositionSpecificData&
channelPositionData )
{
int index = 1;
for ( ExtendedPlugInfoPlugChannelPositionSpecificData::ClusterInfoVector::const_iterator it
= channelPositionData.m_clusterInfos.begin();
it != channelPositionData.m_clusterInfos.end();
++it )
{
const ExtendedPlugInfoPlugChannelPositionSpecificData::ClusterInfo*
extPlugSpClusterInfo = &( *it );
ClusterInfo clusterInfo;
clusterInfo.m_nrOfChannels = extPlugSpClusterInfo->m_nrOfChannels;
clusterInfo.m_index = index;
index++;
for ( ExtendedPlugInfoPlugChannelPositionSpecificData::ChannelInfoVector::const_iterator cit
= extPlugSpClusterInfo->m_channelInfos.begin();
cit != extPlugSpClusterInfo->m_channelInfos.end();
++cit )
{
const ExtendedPlugInfoPlugChannelPositionSpecificData::ChannelInfo*
extPlugSpChannelInfo = &( *cit );
ChannelInfo channelInfo;
channelInfo.m_streamPosition =
extPlugSpChannelInfo->m_streamPosition-1;
// FIXME: this can only become a mess with the two meanings
// of the location parameter. the audio style meaning
// starts from 1, the midi style meaning from 0
// lucky for us we recalculate this for the midi channels
// and don't use this value.
channelInfo.m_location =
extPlugSpChannelInfo->m_location;
clusterInfo.m_channelInfos.push_back( channelInfo );
}
m_clusterInfos.push_back( clusterInfo );
}
return true;
}
bool
Plug::discoverChannelName()
{
for ( ClusterInfoVector::iterator clit = m_clusterInfos.begin();
clit != m_clusterInfos.end();
++clit )
{
ClusterInfo* clitInfo = &*clit;
for ( ChannelInfoVector::iterator pit = clitInfo->m_channelInfos.begin();
pit != clitInfo->m_channelInfos.end();
++pit )
{
ChannelInfo* channelInfo = &*pit;
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_ChannelName );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
ExtendedPlugInfoInfoType* infoType =
extPlugInfoCmd.getInfoType();
if ( infoType ) {
infoType->m_plugChannelName->m_streamPosition =
channelInfo->m_streamPosition + 1;
}
if ( !extPlugInfoCmd.fire() ) {
debugError( "channel name command failed\n" );
return false;
}
infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugChannelName )
{
debugOutput( DEBUG_LEVEL_VERBOSE,
"plug %d stream "
"position %d: channel name = %s\n",
m_id,
channelInfo->m_streamPosition,
infoType->m_plugChannelName->m_plugChannelName.c_str() );
channelInfo->m_name =
infoType->m_plugChannelName->m_plugChannelName;
}
}
}
return true;
}
bool
Plug::discoverClusterInfo()
{
if ( m_infoPlugType == eAPT_Sync )
{
// If the plug is of type sync it is either a normal 2 channel
// stream (not compound stream) or it is a compound stream
// with exactly one cluster. This depends on the
// extended stream format command version which is used.
// We are not interested in this plug so we skip it.
debugOutput( DEBUG_LEVEL_VERBOSE,
"%s plug %d is of type sync -> skip\n",
getName(),
m_id );
return true;
}
for ( ClusterInfoVector::iterator clit = m_clusterInfos.begin();
clit != m_clusterInfos.end();
++clit )
{
ClusterInfo* clusterInfo = &*clit;
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_ClusterInfo );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
extPlugInfoCmd.getInfoType()->m_plugClusterInfo->m_clusterIndex =
clusterInfo->m_index;
if ( !extPlugInfoCmd.fire() ) {
debugError( "cluster info command failed\n" );
return false;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugClusterInfo )
{
debugOutput( DEBUG_LEVEL_VERBOSE,
"%s plug %d: cluster index = %d, "
"portType %s, cluster name = %s\n",
getName(),
m_id,
infoType->m_plugClusterInfo->m_clusterIndex,
extendedPlugInfoClusterInfoPortTypeToString(
infoType->m_plugClusterInfo->m_portType ),
infoType->m_plugClusterInfo->m_clusterName.c_str() );
clusterInfo->m_portType = infoType->m_plugClusterInfo->m_portType;
clusterInfo->m_name = infoType->m_plugClusterInfo->m_clusterName;
}
}
return true;
}
bool
Plug::discoverConnectionsInput()
{
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_PlugInput );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
if ( !extPlugInfoCmd.fire() ) {
debugError( "plug type command failed\n" );
return false;
}
if ( extPlugInfoCmd.getResponse() == AVCCommand::eR_Rejected ) {
// Plugs does not like to be asked about connections
debugOutput( DEBUG_LEVEL_VERBOSE, "Plug '%s' rejects "
"connections command\n",
getName() );
return true;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugInput )
{
PlugAddressSpecificData* plugAddress
= infoType->m_plugInput->m_plugAddress;
if ( plugAddress->m_addressMode ==
PlugAddressSpecificData::ePAM_Undefined )
{
// This plug has no input connection
return true;
}
if ( !discoverConnectionsFromSpecificData( eAPD_Input,
plugAddress,
m_inputConnections ) )
{
debugWarning( "Could not discover connections for plug '%s'\n",
getName() );
}
} else {
debugError( "no valid info type for plug '%s'\n", getName() );
return false;
}
return true;
}
bool
Plug::discoverConnectionsOutput()
{
ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
ExtendedPlugInfoInfoType::eIT_PlugOutput );
extendedPlugInfoInfoType.initialize();
extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
extPlugInfoCmd.setVerbose( getDebugLevel() );
if ( !extPlugInfoCmd.fire() ) {
debugError( "plug type command failed\n" );
return false;
}
if ( extPlugInfoCmd.getResponse() == AVCCommand::eR_Rejected ) {
// Plugs does not like to be asked about connections
debugOutput( DEBUG_LEVEL_VERBOSE, "Plug '%s' rejects "
"connections command\n",
getName() );
return true;
}
ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
if ( infoType
&& infoType->m_plugOutput )
{
if ( infoType->m_plugOutput->m_nrOfOutputPlugs
!= infoType->m_plugOutput->m_outputPlugAddresses.size() )
{
debugError( "number of output plugs (%d) disagree with "
"number of elements in plug address vector (%zd)\n",
infoType->m_plugOutput->m_nrOfOutputPlugs,
infoType->m_plugOutput->m_outputPlugAddresses.size());
}
if ( infoType->m_plugOutput->m_nrOfOutputPlugs == 0 ) {
// This plug has no output connections
return true;
}
for ( unsigned int i = 0;
i < infoType->m_plugOutput->m_outputPlugAddresses.size();
++i )
{
PlugAddressSpecificData* plugAddress
= infoType->m_plugOutput->m_outputPlugAddresses[i];
if ( !discoverConnectionsFromSpecificData( eAPD_Output,
plugAddress,
m_outputConnections ) )
{
debugWarning( "Could not discover connections for "
"plug '%s'\n", getName() );
}
}
} else {
debugError( "no valid info type for plug '%s'\n", getName() );
return false;
}
return true;
}
ExtendedPlugInfoCmd
Plug::setPlugAddrToPlugInfoCmd()
{
ExtendedPlugInfoCmd extPlugInfoCmd( m_unit->get1394Service() );
switch( getSubunitType() ) {
case eST_Unit:
{
UnitPlugAddress::EPlugType ePlugType =
UnitPlugAddress::ePT_Unknown;
switch ( m_addressType ) {
case eAPA_PCR:
ePlugType = UnitPlugAddress::ePT_PCR;
break;
case eAPA_ExternalPlug:
ePlugType = UnitPlugAddress::ePT_ExternalPlug;
break;
case eAPA_AsynchronousPlug:
ePlugType = UnitPlugAddress::ePT_AsynchronousPlug;
break;
default:
ePlugType = UnitPlugAddress::ePT_Unknown;
}
UnitPlugAddress unitPlugAddress( ePlugType,
m_id );
extPlugInfoCmd.setPlugAddress(
PlugAddress( convertPlugDirection( getPlugDirection() ),
PlugAddress::ePAM_Unit,
unitPlugAddress ) );
}
break;
case eST_Music:
case eST_Audio:
{
switch( m_addressType ) {
case eAPA_SubunitPlug:
{
SubunitPlugAddress subunitPlugAddress( m_id );
extPlugInfoCmd.setPlugAddress(
PlugAddress(
convertPlugDirection( getPlugDirection() ),
PlugAddress::ePAM_Subunit,
subunitPlugAddress ) );
}
break;
case eAPA_FunctionBlockPlug:
{
FunctionBlockPlugAddress functionBlockPlugAddress(
m_functionBlockType,
m_functionBlockId,
m_id );
extPlugInfoCmd.setPlugAddress(
PlugAddress(
convertPlugDirection( getPlugDirection() ),
PlugAddress::ePAM_FunctionBlock,
functionBlockPlugAddress ) );
}
break;
default:
extPlugInfoCmd.setPlugAddress(PlugAddress());
}
}
break;
default:
debugError( "Unknown subunit type\n" );
}
extPlugInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() );
extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
extPlugInfoCmd.setSubunitId( getSubunitId() );
extPlugInfoCmd.setSubunitType( getSubunitType() );
return extPlugInfoCmd;
}
}
libffado-2.4.7/src/bebob/bebob_avplug.h 0000644 0001750 0000144 00000005252 14206145246 017332 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_AVPLUG_H
#define BEBOB_AVPLUG_H
#include "libavc/ccm/avc_signal_source.h"
#include "libavc/streamformat/avc_extended_stream_format.h"
#include "libavc/general/avc_extended_plug_info.h"
#include "libavc/general/avc_extended_cmd_generic.h"
#include "libavc/avc_definitions.h"
#include "libavc/general/avc_generic.h"
#include "libavc/general/avc_plug.h"
#include "libutil/serialize.h"
#include "debugmodule/debugmodule.h"
class Ieee1394Service;
class ConfigRom;
namespace BeBoB {
class AvDevice;
class Plug : public AVC::Plug {
public:
// \todo This constructors sucks. too many parameters. fix it.
Plug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId );
Plug( AVC::Unit* unit,
AVC::Subunit* subunit,
AVC::function_block_type_t functionBlockType,
AVC::function_block_type_t functionBlockId,
AVC::Plug::EPlugAddressType plugAddressType,
AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugId,
int globalId );
Plug( const Plug& rhs );
virtual ~Plug();
bool discover();
bool discoverConnections();
public:
protected:
Plug();
bool discoverPlugType();
bool discoverName();
bool discoverNoOfChannels();
bool discoverChannelPosition();
bool discoverChannelName();
bool discoverClusterInfo();
bool discoverConnectionsInput();
bool discoverConnectionsOutput();
private:
bool copyClusterInfo(AVC::ExtendedPlugInfoPlugChannelPositionSpecificData&
channelPositionData );
AVC::ExtendedPlugInfoCmd setPlugAddrToPlugInfoCmd();
};
}
#endif // BEBOB_AVPLUG_H
libffado-2.4.7/src/bebob/bebob_dl_bcd.cpp 0000644 0001750 0000144 00000023021 14206145246 017570 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "bebob_dl_bcd.h"
#include
namespace BeBoB {
enum {
BCDMagic = 0x446f4362,
};
// XXX not very nice tool box function?
std::string makeString( fb_octlet_t v )
{
std::string s;
for ( unsigned int i=0; i ( &v )[i];
}
return s;
}
std::string makeDate( fb_octlet_t v )
{
std::string s;
char* vc = reinterpret_cast ( &v );
s += vc[6];
s += vc[7];
s += '.';
s += vc[4];
s += vc[5];
s += '.';
s += vc[0];
s += vc[1];
s += vc[2];
s += vc[3];
return s;
}
std::string makeTime( fb_octlet_t v )
{
std::string s;
char* vc = reinterpret_cast( &v );
s += vc[0];
s += vc[1];
s += ':';
s += vc[2];
s += vc[3];
s += ':';
s += vc[4];
s += vc[5];
s += vc[6];
s += vc[7];
return s;
}
enum {
BCDFileVersionOffset = 0x28,
V0HeaderCRCOffset = 0x2c,
V0HeaderSize = 0x60,
V1HeaderCRC0ffset = 0x2c,
V1HeaderSize = 0x70,
};
IMPL_DEBUG_MODULE( BCD, BCD, DEBUG_LEVEL_NORMAL );
};
BeBoB::BCD::BCD( std::string filename )
: m_file( 0 )
, m_filename( filename )
, m_bcd_version( -1 )
, m_softwareDate( 0 )
, m_softwareTime( 0 )
, m_softwareId( 0 )
, m_softwareVersion( 0 )
, m_hardwareId( 0 )
, m_vendorOUI( 0 )
, m_imageBaseAddress( 0 )
, m_imageLength( 0 )
, m_imageOffset( 0 )
, m_imageCRC( 0 )
, m_cneLength( 0 )
, m_cneOffset( 0 )
, m_cneCRC( 0 )
{
initCRC32Table();
}
BeBoB::BCD::~BCD()
{
if ( m_file ) {
fclose( m_file );
}
}
bool
BeBoB::BCD::parse()
{
using namespace std;
m_file = fopen( m_filename.c_str(), "r" );
if ( !m_file ) {
debugError( "parse: Could not open file '%s'\n",
m_filename.c_str() );
return false;
}
fb_quadlet_t identifier;
size_t bytes_read = fread( &identifier, 1, sizeof( identifier ), m_file );
if ( bytes_read != sizeof( identifier ) ) {
debugError( "parse: 4 bytes read failed at position 0\n" );
return false;
}
if ( identifier != BCDMagic ) {
debugError( "parse: File has not BCD header magic, 0x%08x expected, "
"0x%08x found\n", BCDMagic, identifier );
return false;
}
if ( fseek( m_file, BCDFileVersionOffset, SEEK_SET ) == -1 ) {
debugError( "parse: fseek failed\n" );
return false;
}
bytes_read = fread( &m_bcd_version, 1, sizeof( fb_quadlet_t ), m_file );
if ( bytes_read != sizeof( fb_quadlet_t ) ) {
debugError( "parse: %zd bytes read at position %d failed\n",
sizeof( fb_quadlet_t ),
BCDFileVersionOffset );
return false;
}
unsigned int headerSize = 0;
unsigned int crcOffset = 0;
switch( m_bcd_version ) {
case 0:
headerSize = V0HeaderSize;
crcOffset = V0HeaderCRCOffset;
break;
case 1:
headerSize = V1HeaderSize;
crcOffset = V1HeaderCRC0ffset;
break;
default:
debugError( "parse: Unknown BCD file version %d found\n",
m_bcd_version );
return false;
}
if ( !checkHeaderCRC( crcOffset, headerSize ) ) {
debugError( "parse: Header CRC check failed\n" );
return false;
}
if ( !readHeaderInfo() ) {
debugError( "parse: Could not read all header info\n" );
return false;
}
return true;
}
bool
BeBoB::BCD::readHeaderInfo()
{
if ( !read( 0x08, &m_softwareDate ) ) {
return false;
}
if ( !read( 0x10, &m_softwareTime ) ) {
return false;
}
if ( !read( 0x18, &m_softwareId ) ) {
return false;
}
if ( !read( 0x1c, &m_softwareVersion ) ) {
return false;
}
if ( !read( 0x20, &m_hardwareId ) ) {
return false;
}
if ( !read( 0x24, &m_vendorOUI ) ) {
return false;
}
if ( !read( 0x30, &m_imageOffset ) ) {
return false;
}
if ( !read( 0x34, &m_imageBaseAddress ) ) {
return false;
}
if ( !read( 0x38, &m_imageLength ) ) {
return false;
}
if ( !read( 0x3c, &m_imageCRC ) ) {
return false;
}
if ( !read( 0x50, &m_cneOffset ) ) {
return false;
}
if ( !read( 0x58, &m_cneLength ) ) {
return false;
}
if ( !read( 0x5c, &m_cneCRC ) ) {
return false;
}
return true;
}
bool
BeBoB::BCD::read( int addr, fb_quadlet_t* q )
{
if ( std::fseek( m_file, addr, SEEK_SET ) == -1 ) {
debugError( "read: seek to position 0x%08x failed\n", addr );
return false;
}
size_t bytes_read = std::fread( q, 1, sizeof( *q ), m_file );
if ( bytes_read != sizeof( *q ) ) {
debugError( "read: %zd byte read failed at position 0x%08x\n",
sizeof( *q ), addr );
return false;
}
return true;
}
bool
BeBoB::BCD::read( int addr, fb_octlet_t* o )
{
if ( std::fseek( m_file, addr, SEEK_SET ) == -1 ) {
debugError( "read: seek to position 0x%08x failed\n", addr );
return false;
}
size_t bytes_read = std::fread( o, 1, sizeof( *o ), m_file );
if ( bytes_read != sizeof( *o ) ) {
debugError( "read: %zd byte read failed at position 0x%08x\n",
sizeof( *o ), addr );
return false;
}
return true;
}
bool
BeBoB::BCD::read( int addr, unsigned char* b, size_t len )
{
if ( std::fseek( m_file, addr, SEEK_SET ) == -1 ) {
debugError( "read: seek to position 0x%08x failed\n", addr );
return false;
}
size_t bytes_read = std::fread( b, 1, len, m_file );
if ( bytes_read != len ) {
debugError( "read: %zd byte read failed at position 0x%08x\n",
len, addr );
return false;
}
return true;
}
void
BeBoB::BCD::initCRC32Table()
{
unsigned long polynomial = 0x04c11db7;
for ( int i = 0; i <= 0xff; ++i ) {
crc32_table[i] = reflect( i, 8 ) << 24;
for ( int j = 0; j < 8; ++j ) {
crc32_table[i] =
(crc32_table[i] << 1)
^ (crc32_table[i] & (1 << 31) ? polynomial : 0);
}
crc32_table[i] = reflect( crc32_table[i], 32 );
}
}
unsigned long
BeBoB::BCD::reflect( unsigned long ref, char ch )
{
unsigned long value = 0;
for ( int i = 1; i < (ch + 1); ++i ) {
if(ref & 1) {
value |= 1 << (ch - i);
}
ref >>= 1;
}
return value;
}
unsigned int
BeBoB::BCD::getCRC( unsigned char* text, size_t len )
{
unsigned long crc = 0xffffffff;
unsigned char* buffer;
buffer = text;
while ( len-- ) {
crc = (crc >> 8) ^ crc32_table[(crc & 0xff) ^ *buffer++];
}
return crc ^ 0xffffffff;
}
bool
BeBoB::BCD::checkHeaderCRC( unsigned int crcOffset, unsigned int headerSize )
{
fb_quadlet_t headerCRC;
if ( !read( crcOffset, &headerCRC ) ) {
debugError( "checkHeaderCRC: Could not read header CRC\n" );
return false;
}
const int headerLength = headerSize;
unsigned char buf[headerLength];
if ( !read( 0x00, buf, headerLength ) ) {
debugError( "checkHeaderCRC: Could not read complete header from file\n" );
return false;
}
buf[crcOffset+0] = 0x00;
buf[crcOffset+1] = 0x00;
buf[crcOffset+2] = 0x00;
buf[crcOffset+3] = 0x00;
fb_quadlet_t calcCRC = getCRC( buf, headerLength );
if ( headerCRC != calcCRC ) {
debugError( "checkHeaderCRC: CRC check failed, 0x%08x expected, "
"0x%08x calculated\n", headerCRC, calcCRC );
return false;
}
return true;
}
void
BeBoB::BCD::displayInfo()
{
using namespace std;
printf( "BCD Info\n" );
printf( "\tBCD File Version\t%d\n", m_bcd_version );
printf( "\tSoftware Date:\t\t%s, %s\n",
makeDate( m_softwareDate ).c_str(),
makeTime( m_softwareTime ).c_str() );
printf( "\tSoftware Version:\t0x%08x\n", m_softwareVersion );
printf( "\tSoftware Id:\t\t0x%08x\n", m_softwareId );
printf( "\tHardware ID:\t\t0x%08x\n", m_hardwareId );
printf( "\tVendor OUI:\t\t0x%08x\n", m_vendorOUI );
printf( "\tImage Offset:\t\t0x%08x\n", m_imageOffset );
printf( "\tImage Base Address:\t0x%08x\n", m_imageBaseAddress );
printf( "\tImage Length:\t\t0x%08x\n", m_imageLength );
printf( "\tImage CRC:\t\t0x%08x\n", m_imageCRC );
printf( "\tCNE Length:\t\t0x%08x\n", m_cneLength );
printf( "\tCNE Offset:\t\t0x%08x\n", m_cneOffset );
printf( "\tCNE CRC:\t\t0x%08x\n", m_cneCRC );
}
libffado-2.4.7/src/bebob/bebob_dl_bcd.h 0000644 0001750 0000144 00000006463 14206145246 017250 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_DL_BCD_H
#define BEBOB_DL_BCD_H
#include "fbtypes.h"
#include "debugmodule/debugmodule.h"
#include
#include
namespace BeBoB {
class BCD {
public:
BCD( std::string filename );
~BCD();
bool parse();
fb_octlet_t getSoftwareDate() const
{ return m_softwareDate; }
fb_octlet_t getSoftwareTime() const
{ return m_softwareTime; }
fb_quadlet_t getSoftwareId() const
{ return m_softwareId; }
fb_quadlet_t getSoftwareVersion() const
{ return m_softwareVersion; }
fb_quadlet_t getHardwareId() const
{ return m_hardwareId; }
fb_quadlet_t getVendorOUI() const
{ return m_vendorOUI; }
fb_quadlet_t getImageBaseAddress() const
{ return m_imageBaseAddress; }
fb_quadlet_t getImageOffset() const
{ return m_imageOffset; }
fb_quadlet_t getImageLength() const
{ return m_imageLength; }
fb_quadlet_t getImageCRC() const
{ return m_imageCRC; }
fb_quadlet_t getCnEOffset() const
{ return m_cneOffset; }
fb_quadlet_t getCnELength() const
{ return m_cneLength; }
fb_quadlet_t getCnECRC() const
{ return m_cneCRC; }
bool read( int addr, fb_quadlet_t* q );
bool read( int addr, fb_octlet_t* o );
bool read( int addr, unsigned char* b, size_t len );
void displayInfo();
protected:
unsigned long crc32_table[256];
void initCRC32Table();
unsigned long reflect(unsigned long ref, char ch);
unsigned int getCRC(unsigned char* text, size_t len);
bool checkHeaderCRC( unsigned int crcOffset,
unsigned int headerSize );
bool readHeaderInfo();
protected:
std::FILE* m_file;
std::string m_filename;
fb_quadlet_t m_bcd_version;
fb_octlet_t m_softwareDate;
fb_octlet_t m_softwareTime;
fb_quadlet_t m_softwareId;
fb_quadlet_t m_softwareVersion;
fb_quadlet_t m_hardwareId;
fb_quadlet_t m_vendorOUI;
fb_quadlet_t m_imageBaseAddress;
fb_quadlet_t m_imageLength;
fb_quadlet_t m_imageOffset;
fb_quadlet_t m_imageCRC;
fb_quadlet_t m_cneLength;
fb_quadlet_t m_cneOffset;
fb_quadlet_t m_cneCRC;
DECLARE_DEBUG_MODULE;
};
std::string makeString( fb_octlet_t v );
std::string makeDate( fb_octlet_t v );
std::string makeTime( fb_octlet_t v );
};
#endif
libffado-2.4.7/src/bebob/bebob_dl_codes.cpp 0000644 0001750 0000144 00000022507 14206145246 020145 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "bebob/bebob_dl_codes.h"
#include "bebob/bebob_dl_bcd.h"
unsigned short BeBoB::CommandCodes::m_gCommandId = 0;
BeBoB::CommandCodes::CommandCodes( fb_quadlet_t protocolVersion,
fb_byte_t commandCode,
size_t msgSize,
fb_byte_t operandSizeRequest,
fb_byte_t operandSizeRespone )
: m_commandId( m_gCommandId++ )
, m_protocolVersion( protocolVersion )
, m_commandCode( commandCode )
, m_msgSize( msgSize )
, m_operandSizeRequest( operandSizeRequest )
, m_operandSizeResponse( operandSizeRespone )
, m_resp_protocolVersion( 0 )
, m_resp_commandId( 0 )
, m_resp_commandCode( 0 )
, m_resp_operandSize( 0 )
{
}
BeBoB::CommandCodes::~CommandCodes()
{
}
bool
BeBoB::CommandCodes::serialize( Util::Cmd::IOSSerialize& se )
{
byte_t tmp;
bool result = se.write( m_protocolVersion, "CommandCodes: protocol version" );
tmp = m_commandId & 0xff;
result &= se.write( tmp, "CommandCodes: command id low" );
tmp = m_commandId >> 8;
result &= se.write( tmp, "CommandCodes: command id high" );
result &= se.write( m_commandCode, "CommandCodes: command code" );
result &= se.write( m_operandSizeRequest, "CommandCodes: request operand size" );
return result;
}
bool
BeBoB::CommandCodes::deserialize( Util::Cmd::IISDeserialize& de )
{
bool result = de.read( &m_resp_protocolVersion );
fb_byte_t tmp;
result &= de.read( &tmp );
m_resp_commandId = tmp;
result &= de.read( &tmp );
m_resp_commandId |= tmp << 8;
result &= de.read( &m_resp_commandCode );
result &= de.read( &m_resp_operandSize );
return result;
}
size_t
BeBoB::CommandCodes::getMaxSize()
{
return 2 * sizeof( fb_quadlet_t ) + m_msgSize;
}
////////////////////////////////
BeBoB::CommandCodesReset::CommandCodesReset( fb_quadlet_t protocolVersion,
EStartMode startMode )
: CommandCodes( protocolVersion, eCmdC_Reset, sizeof( m_startMode ), 1, 0 )
, m_startMode( startMode )
{
}
BeBoB::CommandCodesReset::~CommandCodesReset()
{
}
bool
BeBoB::CommandCodesReset::serialize( Util::Cmd::IOSSerialize& se )
{
bool result = CommandCodes::serialize( se );
result &= se.write( m_startMode, "CommandCodesReset: boot mode" );
return result;
}
bool
BeBoB::CommandCodesReset::deserialize( Util::Cmd::IISDeserialize& de )
{
return CommandCodes::deserialize( de );
}
////////////////////////////////
BeBoB::CommandCodesProgramGUID::CommandCodesProgramGUID(
fb_quadlet_t protocolVersion,
fb_octlet_t guid )
: CommandCodes( protocolVersion, eCmdC_ProgramGUID, sizeof( m_guid ), 2, 0 )
, m_guid( guid )
{
}
BeBoB::CommandCodesProgramGUID::~CommandCodesProgramGUID()
{
}
bool
BeBoB::CommandCodesProgramGUID::serialize( Util::Cmd::IOSSerialize& se )
{
bool result = CommandCodes::serialize( se );
fb_quadlet_t tmp = m_guid >> 32;
result &= se.write( tmp, "CommandCodesProgramGUID: GUID (high)" );
tmp = m_guid & 0xffffffff;
result &= se.write( tmp, "CommandCodesProgramGUID: GUID (low)" );
return result;
}
bool
BeBoB::CommandCodesProgramGUID::deserialize( Util::Cmd::IISDeserialize& de )
{
return CommandCodes::deserialize( de );
}
////////////////////////////////
BeBoB::CommandCodesDownloadStart::CommandCodesDownloadStart(
fb_quadlet_t protocolVersion,
EObject object )
: CommandCodes( protocolVersion, eCmdC_DownloadStart, 10*4, 10, 1 )
, m_object( object )
, m_date( 0 )
, m_time( 0 )
, m_id( 0 )
, m_version( 0 )
, m_address( 0 )
, m_length( 0 )
, m_crc( 0 )
{
}
BeBoB::CommandCodesDownloadStart::~CommandCodesDownloadStart()
{
}
bool
BeBoB::CommandCodesDownloadStart::serialize( Util::Cmd::IOSSerialize& se )
{
bool result = CommandCodes::serialize( se );
result &= se.write( m_object, "CommandCodesDownloadStart: object" );
for ( unsigned int i = 0; i < sizeof( m_date ); ++i ) {
fb_byte_t* tmp = ( fb_byte_t* )( &m_date );
result &= se.write( tmp[i], "CommandCodesDownloadStart: date" );
}
for ( unsigned int i = 0; i < sizeof( m_date ); ++i ) {
fb_byte_t* tmp = ( fb_byte_t* )( &m_time );
result &= se.write( tmp[i], "CommandCodesDownloadStart: time" );
}
result &= se.write( m_id, "CommandCodesDownloadStart: id" );
result &= se.write( m_version, "CommandCodesDownloadStart: version" );
result &= se.write( m_address, "CommandCodesDownloadStart: address" );
result &= se.write( m_length, "CommandCodesDownloadStart: length" );
result &= se.write( m_crc, "CommandCodesDownloadStart: crc" );
return result;
}
bool
BeBoB::CommandCodesDownloadStart::deserialize( Util::Cmd::IISDeserialize& de )
{
bool result = CommandCodes::deserialize( de );
result &= de.read( reinterpret_cast( &m_resp_max_block_size ) );
return result;
}
////////////////////////////////
BeBoB::CommandCodesDownloadBlock::CommandCodesDownloadBlock(
fb_quadlet_t protocolVersion )
: CommandCodes( protocolVersion,
eCmdC_DownloadBlock,
12,
3,
2 )
, m_seqNumber( 0 )
, m_address ( 0 )
, m_resp_seqNumber( 0 )
, m_resp_errorCode( 0 )
{
}
BeBoB::CommandCodesDownloadBlock::~CommandCodesDownloadBlock()
{
}
bool
BeBoB::CommandCodesDownloadBlock::serialize( Util::Cmd::IOSSerialize& se )
{
bool result = CommandCodes::serialize( se );
result &= se.write( m_seqNumber, "CommandCodesDownloadBlock: sequence number" );
result &= se.write( m_address, "CommandCodesDownloadBlock: address" );
result &= se.write( m_numBytes, "CommandCodesDownloadBlock: number of bytes" );
return result;
}
bool
BeBoB::CommandCodesDownloadBlock::deserialize( Util::Cmd::IISDeserialize& de )
{
bool result = CommandCodes::deserialize( de );
result &= de.read( &m_resp_seqNumber );
result &= de.read( &m_resp_errorCode );
return result;
}
////////////////////////////////
BeBoB::CommandCodesDownloadEnd::CommandCodesDownloadEnd(
fb_quadlet_t protocolVersion )
: CommandCodes( protocolVersion, eCmdC_DownloadEnd, 2, 0, 2 )
{
}
BeBoB::CommandCodesDownloadEnd::~CommandCodesDownloadEnd()
{
}
bool
BeBoB::CommandCodesDownloadEnd::serialize( Util::Cmd::IOSSerialize& se )
{
return CommandCodes::serialize( se );
}
bool
BeBoB::CommandCodesDownloadEnd::deserialize( Util::Cmd::IISDeserialize& de )
{
bool result = CommandCodes::deserialize( de );
result &= de.read( &m_resp_crc32 );
result &= de.read( &m_resp_valid );
return result;
}
////////////////////////////////
BeBoB::CommandCodesInitializePersParam::CommandCodesInitializePersParam(
fb_quadlet_t protocolVersion )
: CommandCodes( protocolVersion, eCmdC_InitPersParams, 0, 0, 0 )
{
}
BeBoB::CommandCodesInitializePersParam::~CommandCodesInitializePersParam()
{
}
bool
BeBoB::CommandCodesInitializePersParam::serialize( Util::Cmd::IOSSerialize& se )
{
return CommandCodes::serialize( se );
}
bool
BeBoB::CommandCodesInitializePersParam::deserialize( Util::Cmd::IISDeserialize& de )
{
return CommandCodes::deserialize( de );
}
////////////////////////////////
BeBoB::CommandCodesInitializeConfigToFactorySetting::CommandCodesInitializeConfigToFactorySetting(
fb_quadlet_t protocolVersion )
: CommandCodes( protocolVersion, eCmdC_InitConfigToFactorySetting, 0, 0, 0 )
{
}
BeBoB::CommandCodesInitializeConfigToFactorySetting::~CommandCodesInitializeConfigToFactorySetting()
{
}
bool
BeBoB::CommandCodesInitializeConfigToFactorySetting::serialize( Util::Cmd::IOSSerialize& se )
{
return CommandCodes::serialize( se );
}
bool
BeBoB::CommandCodesInitializeConfigToFactorySetting::deserialize( Util::Cmd::IISDeserialize& de )
{
return CommandCodes::deserialize( de );
}
////////////////////////////////
BeBoB::CommandCodesGo::CommandCodesGo( fb_quadlet_t protocolVersion,
EStartMode startMode )
: CommandCodes( protocolVersion, eCmdC_Go, sizeof( m_startMode ), 1, 1 )
, m_startMode( startMode )
{
}
BeBoB::CommandCodesGo::~CommandCodesGo()
{
}
bool
BeBoB::CommandCodesGo::serialize( Util::Cmd::IOSSerialize& se )
{
bool result = CommandCodes::serialize( se );
result &= se.write( m_startMode, "CommandCodesGo: start mode" );
return result;
}
bool
BeBoB::CommandCodesGo::deserialize( Util::Cmd::IISDeserialize& de )
{
bool result = CommandCodes::deserialize( de );
result &= de.read( &m_resp_validCRC );
return result;
}
libffado-2.4.7/src/bebob/bebob_dl_codes.h 0000644 0001750 0000144 00000023624 14206145246 017613 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_DL_CODES_H
#define BEBOB_DL_CODES_H
#include "fbtypes.h"
#include "libutil/cmd_serialize.h"
namespace BeBoB {
enum EBootloaderProtocolVersion {
eBPV_Unknown = 0,
eBPV_V1 = 1,
eBPV_V2 = 2,
eBPV_V3 = 3,
};
enum EBootloaderCommandCodes {
eCmdC_Halt = 0x01,
eCmdC_Reset = 0x02,
eCmdC_ReadImageCRC = 0x03,
eCmdC_DownloadStart = 0x04,
eCmdC_DownloadBlock = 0x05,
eCmdC_DownloadEnd = 0x06,
eCmdC_SwitchTo1394Shell = 0x07,
eCmdC_ReadShellChars = 0x08,
eCmdC_WriteShellChars = 0x09,
eCmdC_ProgramGUID = 0x0a,
eCmdC_ProgramMAC = 0x0b,
eCmdC_InitPersParams = 0x0c,
eCmdC_InitConfigToFactorySetting = 0x0d,
eCmdC_SetDebugGUID = 0x0f,
eCmdC_ProgramHWIdVersion = 0x10,
eCmdC_Go = 0x11,
};
/////////////////////////
class CommandCodes {
public:
CommandCodes( fb_quadlet_t protocolVersion,
fb_byte_t commandCode,
size_t msgSize,
fb_byte_t operandSizeRequestField,
fb_byte_t operandSizeResponseField );
virtual ~CommandCodes();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
virtual size_t getMaxSize();
EBootloaderCommandCodes getCommandCode() const
{ return static_cast( m_commandCode ); }
fb_byte_t getProtocolVersion() const
{ return m_protocolVersion; }
size_t getMsgSize() const
{ return m_msgSize; }
fb_byte_t getOperandSizeRequest() const
{ return m_operandSizeRequest; }
fb_byte_t getOperandSizeResponse() const
{ return m_operandSizeResponse; }
unsigned short getCommandId() const
{ return m_commandId; }
fb_quadlet_t getRespProtocolVersion() const
{ return m_resp_protocolVersion; }
unsigned short getRespCommandId() const
{ return m_resp_commandId; }
fb_byte_t getRespCommandCode() const
{ return m_resp_commandCode; }
fb_byte_t getRespOperandSize() const
{ return m_resp_operandSize; }
fb_byte_t getRespSizeInQuadlets() const
{ return 2 + m_operandSizeResponse; }
protected:
static unsigned short m_gCommandId;
unsigned short m_commandId;
fb_quadlet_t m_protocolVersion;
fb_byte_t m_commandCode;
size_t m_msgSize;
fb_byte_t m_operandSizeRequest;
fb_byte_t m_operandSizeResponse;
fb_quadlet_t m_resp_protocolVersion;
unsigned short m_resp_commandId;
fb_byte_t m_resp_commandCode;
fb_byte_t m_resp_operandSize;
};
/////////////////////////
class CommandCodesReset : public CommandCodes {
public:
enum EStartMode {
eSM_Application = 0,
eSM_Bootloader,
eSM_Debugger,
};
CommandCodesReset( fb_quadlet_t protocolVersion, EStartMode startMode );
virtual ~CommandCodesReset();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
EStartMode getStartMode() const
{ return static_cast( m_startMode ); }
bool setStartMode( EStartMode startMode )
{ m_startMode = startMode; return true; }
private:
fb_byte_t m_startMode;
};
/////////////////////////
class CommandCodesProgramGUID : public CommandCodes {
public:
CommandCodesProgramGUID( fb_quadlet_t protocolVersion,
fb_octlet_t guid );
virtual ~CommandCodesProgramGUID();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
fb_octlet_t getGUID() const
{ return m_guid; }
bool setGUID( fb_octlet_t guid )
{ m_guid = guid; return true; }
private:
fb_octlet_t m_guid;
};
/////////////////////////
class CommandCodesDownloadStart : public CommandCodes {
public:
enum EObject {
eO_Application = 0,
eO_Config = 1,
eO_Debugger = 2,
eO_Bootloader = 3,
eO_WarpImage = 4,
eO_SerialBootCode = 5,
};
CommandCodesDownloadStart( fb_quadlet_t protocolVersion,
EObject object );
virtual ~CommandCodesDownloadStart();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
bool setDate( fb_octlet_t date )
{ m_date = date; return true; }
bool setTime( fb_octlet_t time )
{ m_time = time; return true; }
bool setId( fb_quadlet_t id )
{ m_id = id; return true; }
bool setVersion( fb_quadlet_t version )
{ m_version = version; return true; }
bool setBaseAddress( fb_quadlet_t address )
{ m_address = address; return true; }
bool setLength( fb_quadlet_t length )
{ m_length = length; return true; }
bool setCRC( fb_quadlet_t crc )
{ m_crc = crc; return true; }
int getMaxBlockSize() const
{ return m_resp_max_block_size; }
private:
fb_quadlet_t m_object;
fb_octlet_t m_date;
fb_octlet_t m_time;
fb_quadlet_t m_id;
fb_quadlet_t m_version;
fb_quadlet_t m_address;
fb_quadlet_t m_length;
fb_quadlet_t m_crc;
int m_resp_max_block_size;
};
/////////////////////////
class CommandCodesDownloadBlock : public CommandCodes {
public:
CommandCodesDownloadBlock( fb_quadlet_t protocolVersion );
virtual ~CommandCodesDownloadBlock();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
bool setSeqNumber( fb_quadlet_t seqNumber )
{ m_seqNumber = seqNumber; return true; }
bool setAddress( fb_quadlet_t address )
{ m_address = address; return true; }
bool setNumberBytes( fb_quadlet_t numByte )
{ m_numBytes = numByte; return true; }
fb_quadlet_t getRespSeqNumber() const
{ return m_resp_seqNumber; }
fb_quadlet_t getRespErrorCode() const
{ return m_resp_errorCode; }
private:
fb_quadlet_t m_seqNumber;
fb_quadlet_t m_address;
fb_quadlet_t m_numBytes;
fb_quadlet_t m_resp_seqNumber;
fb_quadlet_t m_resp_errorCode;
};
/////////////////////////
class CommandCodesDownloadEnd : public CommandCodes {
public:
CommandCodesDownloadEnd( fb_quadlet_t protocolVersion );
virtual ~CommandCodesDownloadEnd();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
fb_quadlet_t getRespCrc32() const
{ return m_resp_crc32; }
bool getRespIsValid() const
{ return m_resp_valid == 0; }
private:
quadlet_t m_resp_crc32;
quadlet_t m_resp_valid;
};
/////////////////////////
class CommandCodesInitializePersParam : public CommandCodes {
public:
CommandCodesInitializePersParam( fb_quadlet_t protocolVersion );
virtual ~CommandCodesInitializePersParam();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
};
/////////////////////////
class CommandCodesInitializeConfigToFactorySetting : public CommandCodes {
public:
CommandCodesInitializeConfigToFactorySetting(
fb_quadlet_t protocolVersion );
virtual ~CommandCodesInitializeConfigToFactorySetting();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
};
/////////////////////////
class CommandCodesGo : public CommandCodes {
public:
enum EStartMode {
eSM_Application = 0,
eSM_Debugger = 2,
};
CommandCodesGo( fb_quadlet_t protocolVersion, EStartMode startMode );
virtual ~CommandCodesGo();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
EStartMode getStartMode() const
{ return static_cast( m_startMode ); }
bool setStartMode( EStartMode startMode )
{ m_startMode = startMode; return true; }
fb_quadlet_t getRespIsValidCRC() const
{ return m_resp_validCRC; }
private:
fb_quadlet_t m_startMode;
fb_quadlet_t m_resp_validCRC;
};
};
#endif
libffado-2.4.7/src/bebob/bebob_dl_mgr.cpp 0000644 0001750 0000144 00000054527 14206145246 017644 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "bebob_dl_mgr.h"
#include "bebob_dl_codes.h"
#include "bebob_dl_bcd.h"
#include "libieee1394/configrom.h"
#include "libieee1394/ieee1394service.h"
#include "libutil/cmd_serialize.h"
#include "libutil/Time.h"
#include "libutil/ByteSwap.h"
#include "ffadodevice.h"
#include
#include
#include
#include
namespace BeBoB {
enum {
AddrRegInfo = 0xffffc8020000ULL,
AddrRegReq = 0xffffc8021000ULL,
AddrRegReqBuf = 0xffffc8021040ULL,
AddrRegResp = 0xffffc8029000ULL,
AddrRegRespBuf = 0xffffc8029040ULL,
};
enum {
RegInfoManufactorIdOffset = 0x00,
RegInfoProtocolVersionOffset = 0x08,
RegInfoBootloaderVersionOffset = 0x0c,
RegInfoGUID = 0x10,
RegInfoHardwareModelId = 0x18,
RegInfoHardwareRevision = 0x1c,
RegInfoSoftwareDate = 0x20,
RegInfoSoftwareTime = 0x28,
RegInfoSoftwareId = 0x30,
RegInfoSoftwareVersion = 0x34,
RegInfoBaseAddress = 0x38,
RegInfoMaxImageLen = 0x3c,
RegInfoBootloaderDate = 0x40,
RegInfoBootloaderTime = 0x48,
RegInfoDebuggerDate = 0x50,
RegInfoDebuggerTime = 0x58,
RegInfoDebuggerId = 0x60,
RegInfoDebuggerVersion = 0x64
};
enum {
MaxRetries = 10,
};
IMPL_DEBUG_MODULE( BootloaderManager, BootloaderManager, DEBUG_LEVEL_NORMAL );
}
BeBoB::BootloaderManager::BootloaderManager(Ieee1394Service& ieee1349service,
fb_nodeid_t nodeId )
: m_ieee1394service( &ieee1349service )
, m_protocolVersion( eBPV_Unknown )
, m_isAppRunning( false )
, m_forceEnabled( false )
, m_bStartBootloader( true )
{
memset( &m_cachedInfoRegs, 0, sizeof( m_cachedInfoRegs ) );
m_configRom = new ConfigRom( *m_ieee1394service, nodeId );
// XXX throw exception if initialize fails!
m_configRom->initialize();
if ( !cacheInfoRegisters() ) {
debugError( "BootloaderManager: could not cache info registers\n" );
}
switch( m_cachedInfoRegs.m_protocolVersion ) {
case 1:
m_protocolVersion = eBPV_V1;
break;
case 3:
m_protocolVersion = eBPV_V3;
break;
default:
// exception?
break;
}
pthread_mutex_init( &m_mutex, 0 );
pthread_cond_init( &m_cond, 0 );
m_functor = new MemberFunctor0< BeBoB::BootloaderManager*,
void (BeBoB::BootloaderManager::*)() >
( this, &BeBoB::BootloaderManager::busresetHandler, false );
m_ieee1394service->addBusResetHandler( m_functor );
}
BeBoB::BootloaderManager::~BootloaderManager()
{
m_ieee1394service->remBusResetHandler( m_functor );
delete( m_functor );
delete m_configRom;
pthread_cond_destroy( &m_cond );
pthread_mutex_destroy( &m_mutex );
}
bool
BeBoB::BootloaderManager::cacheInfoRegisters()
{
if ( !m_configRom->updatedNodeId() ) {
debugError( "cacheInfoRegisters: did not find device anymore\n" );
return false;
}
if ( !m_ieee1394service->read(
0xffc0 | m_configRom->getNodeId(),
AddrRegInfo,
sizeof( m_cachedInfoRegs )/4,
reinterpret_cast( &m_cachedInfoRegs ) ) )
{
return false;
}
if ( m_cachedInfoRegs.m_bootloaderVersion != 0x0 ) {
m_isAppRunning = false;
} else {
m_isAppRunning = true;
}
m_cachedInfoRegs.m_guid = ( m_cachedInfoRegs.m_guid >> 32 )
| ( m_cachedInfoRegs.m_guid << 32 );
return true;
}
bool
BeBoB::BootloaderManager::cacheInfoRegisters( int retries )
{
for ( int i = 0; i < retries; ++i ) {
if ( cacheInfoRegisters() ) {
return true;
}
sleep( 1 );
printf(".");
fflush(stdout);
}
return false;
}
std::string
BeBoB::BootloaderManager::getSoftwareDate()
{
return makeDate( m_cachedInfoRegs.m_softwareDate );
}
std::string
BeBoB::BootloaderManager::getSoftwareTime()
{
return makeDate( m_cachedInfoRegs.m_softwareTime );
}
void
BeBoB::BootloaderManager::printInfoRegisters()
{
using namespace std;
if ( !cacheInfoRegisters() ) {
debugError( "Could not read info registers\n" );
return;
}
printf( "Info Registers\n" );
printf( "\tManufactors Id:\t\t%s\n",
makeString( m_cachedInfoRegs.m_manId ).c_str() );
printf( "\tProtocol Version:\t0x%08x\n",
m_cachedInfoRegs.m_protocolVersion );
printf( "\tBootloader Version:\t0x%08x\n",
m_cachedInfoRegs.m_bootloaderVersion );
printf( "\tGUID:\t\t\t0x%08x%08x\n",
( unsigned int )( m_cachedInfoRegs.m_guid >> 32 ),
( unsigned int )( m_cachedInfoRegs.m_guid & 0xffffffff ) );
printf( "\tHardware Model ID:\t0x%08x\n",
m_cachedInfoRegs.m_hardwareModelId );
printf( "\tHardware Revision:\t0x%08x\n",
m_cachedInfoRegs.m_hardwareRevision );
if ( m_cachedInfoRegs.m_softwareDate
&& m_cachedInfoRegs.m_softwareTime )
{
printf( "\tSoftware Date:\t\t%s, %s\n",
makeDate( m_cachedInfoRegs.m_softwareDate ).c_str(),
makeTime( m_cachedInfoRegs.m_softwareTime ).c_str() );
}
printf( "\tSoftware Id:\t\t0x%08x\n", m_cachedInfoRegs.m_softwareId );
printf( "\tSoftware Version:\t0x%08x\n",
m_cachedInfoRegs.m_softwareVersion );
printf( "\tBase Address:\t\t0x%08x\n", m_cachedInfoRegs.m_baseAddress );
printf( "\tMax. Image Len:\t\t0x%08x\n", m_cachedInfoRegs.m_maxImageLen );
if ( m_cachedInfoRegs.m_bootloaderDate
&& m_cachedInfoRegs.m_bootloaderTime )
{
printf( "\tBootloader Date:\t%s, %s\n",
makeDate( m_cachedInfoRegs.m_bootloaderDate ).c_str(),
makeTime( m_cachedInfoRegs.m_bootloaderTime ).c_str() );
}
if ( m_cachedInfoRegs.m_debuggerDate
&& m_cachedInfoRegs.m_debuggerTime )
{
printf( "\tDebugger Date:\t\t%s, %s\n",
makeDate( m_cachedInfoRegs.m_debuggerDate ).c_str(),
makeTime( m_cachedInfoRegs.m_debuggerTime ).c_str() );
}
printf( "\tDebugger Id:\t\t0x%08x\n", m_cachedInfoRegs.m_debuggerId );
printf( "\tDebugger Version:\t0x%08x\n",
m_cachedInfoRegs.m_debuggerVersion );
}
bool
BeBoB::BootloaderManager::downloadFirmware( std::string filename )
{
using namespace std;
printf( "parse BCD file\n" );
ffado_smartptr bcd = ffado_smartptr( new BCD( filename ) );
if ( !bcd.get() ) {
debugError( "downloadFirmware: Could not open or parse BCD '%s'\n",
filename.c_str() );
return false;
}
if ( !bcd->parse() ) {
debugError( "downloadFirmware: BCD parsing failed\n" );
return false;
}
printf( "check firmware device compatibility... " );
if ( !m_forceEnabled ) {
if ( !checkDeviceCompatibility( *bcd ) ) {
printf( "failed.\n" );
return false;
}
printf( "ok\n" );
} else {
printf( "forced\n" );
}
if ( m_bStartBootloader ) {
printf( "prepare for download (start bootloader)\n" );
if ( !startBootloaderCmd() ) {
debugError( "downloadFirmware: Could not start bootloader\n" );
return false;
}
}
printf( "start downloading protocol for application image\n" );
if ( !downloadObject( *bcd, eOT_Application ) ) {
debugError( "downloadFirmware: Firmware download failed\n" );
return false;
}
printf( "start downloading protocol for CnE\n" );
if ( !downloadObject( *bcd, eOT_CnE ) ) {
debugError( "downloadFirmware: CnE download failed\n" );
return false;
}
printf( "setting CnE to factory default settings\n" );
if ( !initializeConfigToFactorySettingCmd() ) {
debugError( "downloadFirmware: Could not reinitalize CnE\n" );
return false;
}
printf( "start application\n" );
if ( !startApplicationCmd() ) {
debugError( "downloadFirmware: Could not restart application\n" );
return false;
}
return true;
}
bool
BeBoB::BootloaderManager::downloadCnE( std::string filename )
{
using namespace std;
printf( "parse BCD file\n" );
ffado_smartptr bcd = ffado_smartptr( new BCD( filename ) );
if ( !bcd.get() ) {
debugError( "downloadCnE: Could not open or parse BCD '%s'\n",
filename.c_str() );
return false;
}
if ( !bcd->parse() ) {
debugError( "downloadCnE: BCD parsing failed\n" );
return false;
}
printf( "check firmware device compatibility... " );
if ( !m_forceEnabled ) {
if ( !checkDeviceCompatibility( *bcd ) ) {
printf( "failed.\n" );
return false;
}
printf( "ok\n" );
} else {
printf( "forced\n" );
}
if ( m_bStartBootloader ) {
printf( "prepare for download (start bootloader)\n" );
if ( !startBootloaderCmd() ) {
debugError( "downloadCnE: Could not start bootloader\n" );
return false;
}
}
printf( "start downloading protocol for CnE\n" );
if ( !downloadObject( *bcd, eOT_CnE ) ) {
debugError( "downloadCnE: CnE download failed\n" );
return false;
}
printf( "setting CnE to factory default settings\n" );
if ( !initializeConfigToFactorySettingCmd() ) {
debugError( "downloadFirmware: Could not reinitalize CnE\n" );
return false;
}
printf( "start application\n" );
if ( !startApplicationCmd() ) {
debugError( "downloadCnE: Could not restart application\n" );
return false;
}
return true;
}
bool
BeBoB::BootloaderManager::downloadObject( BCD& bcd, EObjectType eObject )
{
using namespace std;
CommandCodesDownloadStart::EObject eCCDSObject;
fb_quadlet_t baseAddress;
fb_quadlet_t imageLength;
fb_quadlet_t crc;
fb_quadlet_t offset;
switch ( eObject ) {
case eOT_Application:
eCCDSObject = CommandCodesDownloadStart::eO_Application;
baseAddress = bcd.getImageBaseAddress();
imageLength = bcd.getImageLength();
crc = bcd.getImageCRC();
offset = bcd.getImageOffset();
break;
case eOT_CnE:
eCCDSObject = CommandCodesDownloadStart::eO_Config;
baseAddress = 0;
imageLength = bcd.getCnELength();
crc = bcd.getCnECRC();
offset = bcd.getCnEOffset();
break;
default:
return false;
}
CommandCodesDownloadStart ccDStart ( m_protocolVersion, eCCDSObject );
ccDStart.setDate( bcd.getSoftwareDate() );
ccDStart.setTime( bcd.getSoftwareTime() );
ccDStart.setId( bcd.getSoftwareId() );
ccDStart.setVersion( bcd.getSoftwareVersion() );
ccDStart.setBaseAddress( baseAddress );
ccDStart.setLength( imageLength );
ccDStart.setCRC( crc );
if ( !writeRequest( ccDStart ) ) {
debugError( "downloadObject: start command write request failed\n" );
return false;
}
// bootloader erases the flash, have to wait until is ready
// to answer our next request
printf( "wait until flash erasing has terminated\n" );
int cnt = 30;
while(cnt--) {
sleep( 1 );
printf(".");
fflush(stdout);
}
printf("\n");
if ( !readResponse( ccDStart ) ) {
debugError( "downloadObject: (start) command read request failed\n" );
return false;
}
if ( ccDStart.getMaxBlockSize() < 0 ) {
debugError( "downloadObject: (start) command reported error %d\n",
ccDStart.getMaxBlockSize() );
return false;
}
unsigned int maxBlockSize = m_configRom->getAsyMaxPayload();
unsigned int i = 0;
fb_quadlet_t address = 0;
bool result = true;
int totalBytes = imageLength;
int downloadedBytes = 0;
while ( imageLength > 0 ) {
unsigned int blockSize = imageLength > maxBlockSize ?
maxBlockSize : imageLength;
fb_byte_t block[blockSize];
if ( !bcd.read( offset, block, blockSize ) ) {
result = false;
break;
}
if ( !get1394Serivce()->write(
0xffc0 | getConfigRom()->getNodeId(),
AddrRegReqBuf,
( blockSize + 3 ) / 4,
reinterpret_cast( block ) ) )
{
debugError( "downloadObject: Could not write to node %d\n",
getConfigRom()->getNodeId() );
return false;
}
CommandCodesDownloadBlock ccBlock( m_protocolVersion );
ccBlock.setSeqNumber( i );
ccBlock.setAddress( baseAddress + address );
ccBlock.setNumberBytes( blockSize );
if ( !writeRequest( ccBlock ) ) {
debugError( "downloadObject: (block) write request failed\n" );
result = false;
break;
}
SleepRelativeUsec( 100 );
if ( !readResponse( ccBlock ) ) {
debugError( "downloadObject: (block) read request failed\n" );
result = false;
break;
}
if ( i != ccBlock.getRespSeqNumber() ) {
debugError( "downloadObject: (block) wrong sequence number "
"reported. %d expected, %d reported\n",
i, ccBlock.getRespSeqNumber() );
result = false;
break;
}
if ( ccBlock.getRespErrorCode() != 0 ) {
debugError( "downloadObject: (block) failed download with "
"error code 0x%08x\n", ccBlock.getRespErrorCode() );
result = false;
break;
}
downloadedBytes += blockSize;
if ( ( i % 100 ) == 0 ) {
printf( "%10d/%d bytes downloaded\r",
downloadedBytes, totalBytes );
fflush(stdout);
}
imageLength -= blockSize;
address += blockSize;
offset += blockSize;
i++;
}
printf( "%10d/%d bytes downloaded\n",
downloadedBytes, totalBytes );
if ( !result ) {
debugError( "downloadObject: seqNumber = %d, "
"address = 0%08x, offset = 0x%08x, "
"restImageLength = 0x%08x\n",
i, address, offset, imageLength );
}
CommandCodesDownloadEnd ccEnd( m_protocolVersion );
if ( !writeRequest( ccEnd ) ) {
debugError( "downloadObject: (end) command write failed\n" );
}
printf( "wait for transaction completion\n" );
cnt = 10;
while(cnt--) {
sleep( 1 );
printf(".");
fflush(stdout);
}
printf("\n");
if ( !readResponse( ccEnd ) ) {
debugError( "downloadObject: (end) command read failed\n" );
}
if ( result ) {
if ( ccEnd.getRespIsValid() ) {
if ( ccEnd.getRespCrc32() == crc ) {
debugOutput( DebugModule::eDL_Normal,
"downloadObject: CRC match\n" );
} else {
debugError( "downloadObject: CRC mismatch. 0x%08x expected, "
"0x%08x reported",
crc, ccEnd.getRespCrc32() );
result = false;
}
} else {
debugError( "downloadObject: (end) object is not valid\n" );
result = false;
}
}
printf( "download protocol successfully completed\n" );
return result;
}
bool
BeBoB::BootloaderManager::programGUID( fb_octlet_t guid )
{
if ( m_bStartBootloader ) {
if ( !startBootloaderCmd() ) {
debugError( "programGUID: Could not start bootloader\n" );
return false;
}
}
if ( !programGUIDCmd( guid ) ) {
debugError( "programGUID: Could not program guid\n" );
return false;
}
if ( !startApplicationCmd() ) {
debugError( "Could not restart application\n");
return false;
}
return true;
}
void
BeBoB::BootloaderManager::busresetHandler()
{
pthread_cond_signal( &m_cond );
}
void
BeBoB::BootloaderManager::waitForBusReset()
{
struct timespec timeout;
int retcode;
// pthread_cond_timedwait() uses CLOCK_REALTIME to evaluate its
// timeout argument.
clock_gettime(CLOCK_REALTIME, &timeout);
do {
printf(".");
fflush(stdout);
timeout.tv_sec = timeout.tv_sec + 1;
retcode = pthread_cond_timedwait( &m_cond, &m_mutex, &timeout );
} while (retcode == ETIMEDOUT);
}
bool
BeBoB::BootloaderManager::writeRequest( CommandCodes& cmd )
{
unsigned char buf[ ( ( cmd.getMaxSize()+3 )/4 ) * 4 ];
memset( buf, 0, sizeof( buf ) );
Util::Cmd::BufferSerialize se( buf, sizeof( buf ) );
if ( !cmd.serialize( se ) ) {
debugError( "writeRequest: Could not serialize command code %d\n",
cmd.getCommandCode() );
return false;
}
if ( !get1394Serivce()->write(
0xffc0 | getConfigRom()->getNodeId(),
AddrRegReq,
sizeof( buf )/4,
reinterpret_cast( buf ) ) )
{
debugError( "writeRequest: Could not ARM write to node %d\n",
getConfigRom()->getNodeId() );
return false;
}
return true;
}
bool
BeBoB::BootloaderManager::readResponse( CommandCodes& writeRequestCmd )
{
const size_t buf_length = 0x40;
unsigned char raw[buf_length];
if ( !get1394Serivce()->read(
0xffc0 | getConfigRom()->getNodeId(),
AddrRegResp,
writeRequestCmd.getRespSizeInQuadlets(),
reinterpret_cast( raw ) ) )
{
return false;
}
Util::Cmd::BufferDeserialize de( raw, buf_length );
if ( !writeRequestCmd.deserialize( de ) ) {
debugError( "readResponse: deserialize failed\n" );
return false;
}
bool result =
writeRequestCmd.getProtocolVersion()
== writeRequestCmd.getRespProtocolVersion();
result &=
writeRequestCmd.getCommandId()
== writeRequestCmd.getRespCommandId();
result &=
writeRequestCmd.getCommandCode()
== writeRequestCmd.getRespCommandCode();
#ifdef DEBUG
if ( !result ) {
debugError( "readResponse: protocol version: %d expected, "
" %d reported\n",
writeRequestCmd.getProtocolVersion(),
writeRequestCmd.getRespProtocolVersion() );
debugError( "readResponse: command id: %d expected, "
" %d reported\n",
writeRequestCmd.getCommandId(),
writeRequestCmd.getRespCommandId() );
debugError( "readResponse: command code: %d expected, "
" %d reported\n",
writeRequestCmd.getCommandCode(),
writeRequestCmd.getRespCommandCode() );
}
#endif
return result;
}
bool
BeBoB::BootloaderManager::startBootloaderCmd()
{
CommandCodesReset cmd( m_protocolVersion,
CommandCodesReset::eSM_Bootloader ) ;
if ( !writeRequest( cmd ) ) {
debugError( "startBootloaderCmd: writeRequest failed\n" );
return false;
}
waitForBusReset();
if ( !cacheInfoRegisters( MaxRetries ) ) {
debugError( "startBootloaderCmd: Could not read info registers\n" );
return false;
}
// wait for bootloader finish startup sequence
// there is no way to find out when it has finished
sleep( 10 );
int cnt = 10;
while(cnt--) {
sleep( 1 );
printf(".");
fflush(stdout);
}
printf("\n");
return true;
}
bool
BeBoB::BootloaderManager::startApplicationCmd()
{
CommandCodesGo cmd( m_protocolVersion,
CommandCodesGo::eSM_Application ) ;
if ( !writeRequest( cmd ) ) {
debugError( "startApplicationCmd: writeRequest failed\n" );
return false;
}
return true;
}
bool
BeBoB::BootloaderManager::programGUIDCmd( fb_octlet_t guid )
{
CommandCodesProgramGUID cmd( m_protocolVersion, guid );
if ( !writeRequest( cmd ) ) {
debugError( "programGUIDCmd: writeRequest failed\n" );
return false;
}
sleep( 1 );
return true;
}
bool
BeBoB::BootloaderManager::initializePersParamCmd()
{
CommandCodesInitializePersParam cmd( m_protocolVersion );
if ( !writeRequest( cmd ) ) {
debugError( "initializePersParamCmd: writeRequest failed\n" );
return false;
}
sleep( 1 );
return true;
}
bool
BeBoB::BootloaderManager::initializeConfigToFactorySettingCmd()
{
CommandCodesInitializeConfigToFactorySetting cmd( m_protocolVersion );
if ( !writeRequest( cmd ) ) {
debugError( "initializeConfigToFactorySettingCmd: writeRequest failed\n" );
return false;
}
sleep( 5 );
int cnt = 5;
while(cnt--) {
sleep( 1 );
printf(".");
fflush(stdout);
}
printf("\n");
return true;
}
bool
BeBoB::BootloaderManager::checkDeviceCompatibility( BCD& bcd )
{
fb_quadlet_t vendorOUI = ( m_cachedInfoRegs.m_guid >> 40 );
if ( ( vendorOUI == bcd.getVendorOUI() )
&& ( m_cachedInfoRegs.m_softwareId == bcd.getSoftwareId() ) )
{
return true;
}
printf( "vendorOUI = 0x%08x\n", vendorOUI );
printf( "BCD vendorOUI = 0x%08x\n", bcd.getVendorOUI() );
printf( "software ID = 0x%08x\n", m_cachedInfoRegs.m_softwareId );
printf( "BCD software ID = 0x%08x\n", bcd.getSoftwareId() );
return false;
}
libffado-2.4.7/src/bebob/bebob_dl_mgr.h 0000644 0001750 0000144 00000007661 14206145246 017306 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_DL_MGR_H
#define BEBOB_DL_MGR_H
#include "bebob_dl_codes.h"
#include "fbtypes.h"
#include "libutil/Functors.h"
#include "debugmodule/debugmodule.h"
#include
class Ieee1394Service;
class ConfigRom;
using namespace Util;
namespace BeBoB {
class BCD;
class BootloaderManager {
public:
BootloaderManager( Ieee1394Service& ieee1349service,
fb_nodeid_t nodeId );
~BootloaderManager();
const ConfigRom* const getConfigRom() const
{ return m_configRom; }
void printInfoRegisters();
bool downloadFirmware( std::string filename );
bool downloadCnE( std::string filename );
bool programGUID( octlet_t guid );
void busresetHandler();
Ieee1394Service* get1394Serivce() const
{ return m_ieee1394service; }
bool setForceOperations( bool enabled )
{ m_forceEnabled = enabled; return true; }
bool setStartBootloader( bool bStartBootloader )
{ m_bStartBootloader = bStartBootloader; return true; }
int getSoftwareVersion() {return m_cachedInfoRegs.m_softwareVersion;};
std::string getSoftwareDate();
std::string getSoftwareTime();
protected:
enum EObjectType {
eOT_Application,
eOT_CnE
};
void waitForBusReset();
bool writeRequest( CommandCodes& cmd );
bool readResponse( CommandCodes& writeRequestCmd );
bool downloadObject( BCD& bcd, EObjectType eObject );
bool programGUIDCmd( octlet_t guid );
bool startBootloaderCmd();
bool startApplicationCmd();
bool initializePersParamCmd();
bool initializeConfigToFactorySettingCmd();
bool checkDeviceCompatibility( BCD& bcd );
private:
bool cacheInfoRegisters();
bool cacheInfoRegisters( int retries );
struct info_register_t {
fb_octlet_t m_manId;
fb_quadlet_t m_protocolVersion;
fb_quadlet_t m_bootloaderVersion;
fb_octlet_t m_guid;
fb_quadlet_t m_hardwareModelId;
fb_quadlet_t m_hardwareRevision;
fb_octlet_t m_softwareDate;
fb_octlet_t m_softwareTime;
fb_quadlet_t m_softwareId;
fb_quadlet_t m_softwareVersion;
fb_quadlet_t m_baseAddress;
fb_quadlet_t m_maxImageLen;
fb_octlet_t m_bootloaderDate;
fb_octlet_t m_bootloaderTime;
fb_octlet_t m_debuggerDate;
fb_octlet_t m_debuggerTime;
fb_quadlet_t m_debuggerId;
fb_quadlet_t m_debuggerVersion;
};
Ieee1394Service* m_ieee1394service;
ConfigRom* m_configRom;
EBootloaderProtocolVersion m_protocolVersion;
bool m_isAppRunning;
info_register_t m_cachedInfoRegs;
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
Functor* m_functor;
bool m_forceEnabled;
bool m_bStartBootloader;
DECLARE_DEBUG_MODULE;
};
}
#endif
libffado-2.4.7/src/bebob/bebob_functionblock.cpp 0000644 0001750 0000144 00000035045 14206145246 021232 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "bebob/bebob_functionblock.h"
#include "bebob/bebob_avdevice_subunit.h"
#include "bebob/bebob_avdevice.h"
#include "libieee1394/configrom.h"
#include "libutil/cmd_serialize.h"
using namespace AVC;
namespace BeBoB {
IMPL_DEBUG_MODULE( FunctionBlock, FunctionBlock, DEBUG_LEVEL_NORMAL );
FunctionBlock::FunctionBlock(
AVC::Subunit& subunit,
function_block_type_t type,
function_block_type_t subtype,
function_block_id_t id,
ESpecialPurpose purpose,
no_of_input_plugs_t nrOfInputPlugs,
no_of_output_plugs_t nrOfOutputPlugs,
int verbose )
: m_subunit( &subunit )
, m_type( type )
, m_subtype( subtype )
, m_id( id )
, m_purpose( purpose )
, m_nrOfInputPlugs( nrOfInputPlugs )
, m_nrOfOutputPlugs( nrOfOutputPlugs )
, m_verbose( verbose )
{
setDebugLevel( verbose );
}
FunctionBlock::FunctionBlock( const FunctionBlock& rhs )
: m_subunit( rhs.m_subunit )
, m_type( rhs.m_type )
, m_subtype( rhs.m_subtype )
, m_id( rhs.m_id )
, m_purpose( rhs.m_purpose )
, m_nrOfInputPlugs( rhs.m_nrOfInputPlugs )
, m_nrOfOutputPlugs( rhs.m_nrOfOutputPlugs )
, m_verbose( rhs.m_verbose )
{
}
FunctionBlock::FunctionBlock()
{
}
FunctionBlock::~FunctionBlock()
{
for ( PlugVector::iterator it = m_plugs.begin();
it != m_plugs.end();
++it )
{
delete *it;
}
}
bool
FunctionBlock::discover()
{
debugOutput( DEBUG_LEVEL_NORMAL,
"discover function block %s (nr of input plugs = %d, "
"nr of output plugs = %d)\n",
getName(),
m_nrOfInputPlugs,
m_nrOfOutputPlugs );
if ( !discoverPlugs( AVC::Plug::eAPD_Input, m_nrOfInputPlugs ) ) {
debugError( "Could not discover input plug for '%s'\n",
getName() );
return false;
}
if ( !discoverPlugs( AVC::Plug::eAPD_Output, m_nrOfOutputPlugs ) ) {
debugError( "Could not discover output plugs for '%s'\n",
getName() );
return false;
}
return true;
}
bool
FunctionBlock::discoverPlugs( AVC::Plug::EPlugDirection plugDirection,
plug_id_t plugMaxId )
{
for ( int plugId = 0; plugId < plugMaxId; ++plugId ) {
AVC::Plug* plug = new BeBoB::Plug(
&m_subunit->getUnit(),
m_subunit,
m_type,
m_id,
AVC::Plug::eAPA_FunctionBlockPlug,
plugDirection,
plugId);
if ( !plug || !plug->discover() ) {
debugError( "plug discovering failed for plug %d\n",
plugId );
delete plug;
return false;
}
debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
plug->getName() );
m_plugs.push_back( plug );
}
return true;
}
bool
FunctionBlock::discoverConnections()
{
debugOutput( DEBUG_LEVEL_VERBOSE,
"discover connections function block %s\n",
getName() );
for ( PlugVector::iterator it = m_plugs.begin();
it != m_plugs.end();
++it )
{
BeBoB::Plug* plug = dynamic_cast(*it);
if(!plug) {
debugError("BUG: not a bebob plug\n");
return false;
}
if ( !plug->discoverConnections() ) {
debugError( "Could not discover plug connections\n" );
return false;
}
}
return true;
}
bool
FunctionBlock::serialize( std::string basePath, Util::IOSerialize& ser ) const
{
bool result;
result = ser.write( basePath + "m_type", m_type );
result &= ser.write( basePath + "m_subtype", m_subtype );
result &= ser.write( basePath + "m_id", m_id );
result &= ser.write( basePath + "m_purpose", m_purpose );
result &= ser.write( basePath + "m_nrOfInputPlugs", m_nrOfInputPlugs );
result &= ser.write( basePath + "m_nrOfOutputPlugs", m_nrOfOutputPlugs );
result &= serializePlugVector( basePath + "m_plugs", ser, m_plugs );
return result;
}
FunctionBlock*
FunctionBlock::deserialize( std::string basePath,
Util::IODeserialize& deser,
AVC::Unit& unit,
AVC::Subunit& subunit )
{
bool result;
function_block_type_t type;
function_block_type_t subtype;
FunctionBlock* pFB = 0;
if ( !deser.isExisting( basePath + "m_type" ) ) {
return 0;
}
result = deser.read( basePath + "m_type", type );
result &= deser.read( basePath + "m_subtype", subtype );
if ( !result ) {
return 0;
}
switch ( type ) {
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitSelector:
pFB = new FunctionBlockSelector;
break;
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitFeature:
pFB = new FunctionBlockFeature;
break;
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitProcessing:
if ( subtype == ExtendedSubunitInfoCmd::ePT_EnhancedMixer ) {
pFB = new FunctionBlockEnhancedMixer;
} else {
pFB = new FunctionBlockProcessing;
}
break;
case ExtendedSubunitInfoCmd::eFBT_AudioSubunitCodec:
pFB = new FunctionBlockCodec;
break;
default:
pFB = 0;
}
if ( !pFB ) {
return 0;
}
pFB->m_subunit = &subunit;
pFB->m_type = type;
pFB->m_subtype = subtype;
result &= deser.read( basePath + "m_id", pFB->m_id );
result &= deser.read( basePath + "m_purpose", pFB->m_purpose );
result &= deser.read( basePath + "m_nrOfInputPlugs", pFB->m_nrOfInputPlugs );
result &= deser.read( basePath + "m_nrOfOutputPlugs", pFB->m_nrOfOutputPlugs );
if ( !result ) {
delete pFB;
return 0;
}
return pFB;
}
bool
FunctionBlock::deserializeUpdate( std::string basePath,
Util::IODeserialize& deser )
{
bool result;
result = deserializePlugVector( basePath + "m_plugs", deser,
m_subunit->getUnit().getPlugManager(), m_plugs );
return result;
}
///////////////////////
FunctionBlockSelector::FunctionBlockSelector(
AVC::Subunit& subunit,
function_block_id_t id,
ESpecialPurpose purpose,
no_of_input_plugs_t nrOfInputPlugs,
no_of_output_plugs_t nrOfOutputPlugs,
int verbose )
: FunctionBlock( subunit,
eFBT_AudioSubunitSelector,
0,
id,
purpose,
nrOfInputPlugs,
nrOfOutputPlugs,
verbose )
{
}
FunctionBlockSelector::FunctionBlockSelector(
const FunctionBlockSelector& rhs )
: FunctionBlock( rhs )
{
}
FunctionBlockSelector::FunctionBlockSelector()
: FunctionBlock()
{
}
FunctionBlockSelector::~FunctionBlockSelector()
{
}
const char*
FunctionBlockSelector::getName()
{
return "Selector";
}
bool
FunctionBlockSelector::serializeChild( std::string basePath,
Util::IOSerialize& ser ) const
{
return true;
}
bool
FunctionBlockSelector::deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& unit )
{
return true;
}
///////////////////////
FunctionBlockFeature::FunctionBlockFeature(
AVC::Subunit& subunit,
function_block_id_t id,
ESpecialPurpose purpose,
no_of_input_plugs_t nrOfInputPlugs,
no_of_output_plugs_t nrOfOutputPlugs,
int verbose )
: FunctionBlock( subunit,
eFBT_AudioSubunitFeature,
0,
id,
purpose,
nrOfInputPlugs,
nrOfOutputPlugs,
verbose )
{
}
FunctionBlockFeature::FunctionBlockFeature(
const FunctionBlockFeature& rhs )
: FunctionBlock( rhs )
{
}
FunctionBlockFeature::FunctionBlockFeature()
: FunctionBlock()
{
}
FunctionBlockFeature::~FunctionBlockFeature()
{
}
const char*
FunctionBlockFeature::getName()
{
return "Feature";
}
bool
FunctionBlockFeature::serializeChild( std::string basePath,
Util::IOSerialize& ser ) const
{
return true;
}
bool
FunctionBlockFeature::deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& unit )
{
return true;
}
///////////////////////
FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer(
AVC::Subunit& subunit,
function_block_id_t id,
ESpecialPurpose purpose,
no_of_input_plugs_t nrOfInputPlugs,
no_of_output_plugs_t nrOfOutputPlugs,
int verbose )
: FunctionBlock( subunit,
eFBT_AudioSubunitProcessing,
ExtendedSubunitInfoCmd::ePT_EnhancedMixer,
id,
purpose,
nrOfInputPlugs,
nrOfOutputPlugs,
verbose )
{
}
FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer(
const FunctionBlockEnhancedMixer& rhs )
: FunctionBlock( rhs )
{
}
FunctionBlockEnhancedMixer::FunctionBlockEnhancedMixer()
: FunctionBlock()
{
}
FunctionBlockEnhancedMixer::~FunctionBlockEnhancedMixer()
{
}
bool
FunctionBlockEnhancedMixer::discover()
{
if (!FunctionBlock::discover())
return false;
/*
* Disable discovering of enhanced mixer because all
* device out there do not use, and all implementations
* are buggy. So there is no point to use it.
* All 'mixer' functions are implemented with selector function blocks
*/
AVC::FunctionBlockCmd fbCmd( m_subunit->getUnit().get1394Service(),
FunctionBlockCmd::eFBT_Processing,
m_id,
FunctionBlockCmd::eCA_Current);
fbCmd.setNodeId( m_subunit->getUnit().getConfigRom().getNodeId() );
fbCmd.setSubunitId( 0x00 );
fbCmd.setCommandType( AVCCommand::eCT_Status );
// fbCmd.setVerboseLevel( DEBUG_LEVEL_VERY_VERBOSE );
// Ok, this enhanced mixer setting here is just a hack, we need
// a sane way to set processing features (read pointer management)
AVC::FunctionBlockProcessingEnhancedMixer em;
delete fbCmd.m_pFBProcessing->m_pMixer;
fbCmd.m_pFBProcessing->m_pMixer = 0;
fbCmd.m_pFBProcessing->m_pEnhancedMixer = em.clone();
fbCmd.m_pFBProcessing->m_inputAudioChannelNumber = 0xff;
fbCmd.m_pFBProcessing->m_outputAudioChannelNumber = 0xff;
if ( !fbCmd.fire() ) {
debugError( "cmd failed\n" );
return false;
}
// if ( getDebugLevel() >= DEBUG_LEVEL_NORMAL ) {
// Util::Cmd::CoutSerializer se;
// fbCmd.serialize( se );
// }
if((fbCmd.getResponse() != AVCCommand::eR_Implemented)) {
debugWarning("fbCmd.getResponse() != AVCCommand::eR_Implemented\n");
}
return true;
}
const char*
FunctionBlockEnhancedMixer::getName()
{
return "EnhancedMixer";
}
bool
FunctionBlockEnhancedMixer::serializeChild( std::string basePath,
Util::IOSerialize& ser ) const
{
return true;
}
bool
FunctionBlockEnhancedMixer::deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& unit )
{
return true;
}
///////////////////////
FunctionBlockProcessing::FunctionBlockProcessing(
AVC::Subunit& subunit,
function_block_id_t id,
ESpecialPurpose purpose,
no_of_input_plugs_t nrOfInputPlugs,
no_of_output_plugs_t nrOfOutputPlugs,
int verbose )
: FunctionBlock( subunit,
eFBT_AudioSubunitProcessing,
0,
id,
purpose,
nrOfInputPlugs,
nrOfOutputPlugs,
verbose )
{
}
FunctionBlockProcessing::FunctionBlockProcessing(
const FunctionBlockProcessing& rhs )
: FunctionBlock( rhs )
{
}
FunctionBlockProcessing::FunctionBlockProcessing()
: FunctionBlock()
{
}
FunctionBlockProcessing::~FunctionBlockProcessing()
{
}
const char*
FunctionBlockProcessing::getName()
{
return "Dummy Processing";
}
bool
FunctionBlockProcessing::serializeChild( std::string basePath,
Util::IOSerialize& ser ) const
{
return true;
}
bool
FunctionBlockProcessing::deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& unit )
{
return true;
}
///////////////////////
FunctionBlockCodec::FunctionBlockCodec(
AVC::Subunit& subunit,
function_block_id_t id,
ESpecialPurpose purpose,
no_of_input_plugs_t nrOfInputPlugs,
no_of_output_plugs_t nrOfOutputPlugs,
int verbose )
: FunctionBlock( subunit,
eFBT_AudioSubunitCodec,
0,
id,
purpose,
nrOfInputPlugs,
nrOfOutputPlugs,
verbose )
{
}
FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs )
: FunctionBlock( rhs )
{
}
FunctionBlockCodec::FunctionBlockCodec()
: FunctionBlock()
{
}
FunctionBlockCodec::~FunctionBlockCodec()
{
}
const char*
FunctionBlockCodec::getName()
{
return "Dummy Codec";
}
bool
FunctionBlockCodec::serializeChild( std::string basePath,
Util::IOSerialize& ser ) const
{
return true;
}
bool
FunctionBlockCodec::deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& unit )
{
return true;
}
}
libffado-2.4.7/src/bebob/bebob_functionblock.h 0000644 0001750 0000144 00000021162 14206145246 020672 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_FUNCTION_BLOCK_H
#define BEBOB_FUNCTION_BLOCK_H
#include "bebob/bebob_avplug.h"
#include "libavc/avc_definitions.h"
#include "debugmodule/debugmodule.h"
#include
namespace AVC {
class Subunit;
}
namespace BeBoB {
class FunctionBlock {
public:
enum EFunctionBlockType {
eFBT_AllFunctionBlockType = 0xff,
eFBT_AudioSubunitSelector = 0x80,
eFBT_AudioSubunitFeature = 0x81,
eFBT_AudioSubunitProcessing = 0x82,
eFBT_AudioSubunitCodec = 0x83,
};
enum ESpecialPurpose {
eSP_InputGain,
eSP_OutputVolume,
eSP_NoSpecialPurpose
};
FunctionBlock( AVC::Subunit& subunit,
AVC::function_block_type_t type,
AVC::function_block_type_t subtype,
AVC::function_block_id_t id,
ESpecialPurpose purpose,
AVC::no_of_input_plugs_t nrOfInputPlugs,
AVC::no_of_output_plugs_t nrOfOutputPlugs,
int verbose );
FunctionBlock( const FunctionBlock& rhs );
FunctionBlock();
virtual ~FunctionBlock();
virtual bool discover();
virtual bool discoverConnections();
virtual const char* getName() = 0;
AVC::function_block_type_t getType() {return m_type;};
AVC::function_block_type_t getSubtype() {return m_subtype;};
AVC::function_block_id_t getId() {return m_id;};
AVC::no_of_input_plugs_t getNrOfInputPlugs() {return m_nrOfInputPlugs;};
AVC::no_of_output_plugs_t getNrOfOutputPlugs() {return m_nrOfOutputPlugs;};
bool serialize( std::string basePath, Util::IOSerialize& ser ) const;
static FunctionBlock* deserialize( std::string basePath,
Util::IODeserialize& deser,
AVC::Unit& unit,
AVC::Subunit& subunit );
bool deserializeUpdate( std::string basePath,
Util::IODeserialize& deser );
protected:
bool discoverPlugs( AVC::Plug::EPlugDirection plugDirection,
AVC::plug_id_t plugMaxId );
protected:
AVC::Subunit* m_subunit;
AVC::function_block_type_t m_type;
AVC::function_block_type_t m_subtype;
AVC::function_block_id_t m_id;
ESpecialPurpose m_purpose;
AVC::no_of_input_plugs_t m_nrOfInputPlugs;
AVC::no_of_output_plugs_t m_nrOfOutputPlugs;
int m_verbose;
AVC::PlugVector m_plugs;
DECLARE_DEBUG_MODULE;
};
typedef std::vector FunctionBlockVector;
/////////////////////////////////////
/////////////////////////////////////
class FunctionBlockSelector: public FunctionBlock
{
public:
FunctionBlockSelector(AVC::Subunit& subunit,
AVC::function_block_id_t id,
ESpecialPurpose purpose,
AVC::no_of_input_plugs_t nrOfInputPlugs,
AVC::no_of_output_plugs_t nrOfOutputPlugs,
int verbose);
FunctionBlockSelector( const FunctionBlockSelector& rhs );
FunctionBlockSelector();
virtual ~FunctionBlockSelector();
virtual const char* getName();
protected:
virtual bool serializeChild( std::string basePath,
Util::IOSerialize& ser ) const;
virtual bool deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& avDevice );
};
/////////////////////////////////////
class FunctionBlockFeature: public FunctionBlock
{
public:
FunctionBlockFeature(AVC::Subunit& subunit,
AVC::function_block_id_t id,
ESpecialPurpose purpose,
AVC::no_of_input_plugs_t nrOfInputPlugs,
AVC::no_of_output_plugs_t nrOfOutputPlugs,
int verbose);
FunctionBlockFeature( const FunctionBlockFeature& rhs );
FunctionBlockFeature();
virtual ~FunctionBlockFeature();
virtual const char* getName();
// FIXME: this is not pretty!
enum EControlSelectorEncoding {
eCSE_Feature_Unknown = 0x00,
eCSE_Feature_Mute = 0x01,
eCSE_Feature_Volume = 0x02,
eCSE_Feature_LRBalance = 0x03,
eCSE_Feature_FRBalance = 0x04,
eCSE_Feature_Bass = 0x05,
eCSE_Feature_Mid = 0x06,
eCSE_Feature_Treble = 0x07,
eCSE_Feature_GEQ = 0x08,
eCSE_Feature_AGC = 0x09,
eCSE_Feature_Delay = 0x0a,
eCSE_Feature_BassBoost = 0x0b,
eCSE_Feature_Loudness = 0x0c,
};
protected:
virtual bool serializeChild( std::string basePath,
Util::IOSerialize& ser ) const;
virtual bool deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& avDevice );
};
/////////////////////////////////////
class FunctionBlockEnhancedMixer: public FunctionBlock
{
public:
FunctionBlockEnhancedMixer( AVC::Subunit& subunit,
AVC::function_block_id_t id,
ESpecialPurpose purpose,
AVC::no_of_input_plugs_t nrOfInputPlugs,
AVC::no_of_output_plugs_t nrOfOutputPlugs,
int verbose );
FunctionBlockEnhancedMixer();
FunctionBlockEnhancedMixer( const FunctionBlockEnhancedMixer& rhs );
virtual ~FunctionBlockEnhancedMixer();
virtual bool discover();
virtual const char* getName();
protected:
virtual bool serializeChild( std::string basePath,
Util::IOSerialize& ser ) const;
virtual bool deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& avDevice );
};
/////////////////////////////////////
class FunctionBlockProcessing: public FunctionBlock
{
public:
FunctionBlockProcessing( AVC::Subunit& subunit,
AVC::function_block_id_t id,
ESpecialPurpose purpose,
AVC::no_of_input_plugs_t nrOfInputPlugs,
AVC::no_of_output_plugs_t nrOfOutputPlugs,
int verbose );
FunctionBlockProcessing( const FunctionBlockProcessing& rhs );
FunctionBlockProcessing();
virtual ~FunctionBlockProcessing();
virtual const char* getName();
protected:
virtual bool serializeChild( std::string basePath,
Util::IOSerialize& ser ) const;
virtual bool deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& avDevice );
};
/////////////////////////////////////
class FunctionBlockCodec: public FunctionBlock
{
public:
FunctionBlockCodec(AVC::Subunit& subunit,
AVC::function_block_id_t id,
ESpecialPurpose purpose,
AVC::no_of_input_plugs_t nrOfInputPlugs,
AVC::no_of_output_plugs_t nrOfOutputPlugs,
int verbose);
FunctionBlockCodec( const FunctionBlockCodec& rhs );
FunctionBlockCodec();
virtual ~FunctionBlockCodec();
virtual const char* getName();
protected:
virtual bool serializeChild( std::string basePath,
Util::IOSerialize& ser ) const;
virtual bool deserializeChild( std::string basePath,
Util::IODeserialize& deser,
AvDevice& avDevice );
};
}
#endif
libffado-2.4.7/src/bebob/bebob_mixer.cpp 0000644 0001750 0000144 00000030410 14206145246 017505 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "bebob/bebob_mixer.h"
#include "bebob/bebob_avdevice.h"
#include "bebob/bebob_avdevice_subunit.h"
#include "libavc/audiosubunit/avc_function_block.h"
#include "libutil/cmd_serialize.h"
#include "libcontrol/BasicElements.h"
#include "libieee1394/ieee1394service.h"
#include "libieee1394/configrom.h"
#include
#include
#include
#include
using namespace AVC;
namespace BeBoB {
template
bool from_string(T& t,
const std::string& s,
std::ios_base& (*f)(std::ios_base&))
{
std::istringstream iss(s);
return !(iss >> f >> t).fail();
}
IMPL_DEBUG_MODULE( Mixer, Mixer, DEBUG_LEVEL_NORMAL );
Mixer::Mixer(Device &d)
: Control::Container(&d)
, m_device(d)
{
addElementForAllFunctionBlocks();
if (!d.addElement(this)) {
debugWarning("Could not add myself to Control::Container\n");
}
}
Mixer::~Mixer() {
debugOutput(DEBUG_LEVEL_VERBOSE,"Unregistering from Control::Container...\n");
if (!m_device.deleteElement(this)) {
debugWarning("Could not delete myself from Control::Container\n");
}
// delete all our elements since we should have created
// them ourselves.
for ( Control::ElementVectorIterator it = m_Children.begin();
it != m_Children.end();
++it )
{
debugOutput(DEBUG_LEVEL_VERBOSE,"deleting %s...\n", (*it)->getName().c_str());
delete *it;
}
}
bool
Mixer::deleteElement(Element *e)
{
if (Control::Container::deleteElement(e)) {
delete e;
return true;
} else return false;
}
bool
Mixer::clearElements() {
// delete all our elements since we should have created
// them ourselves.
for ( Control::ElementVectorIterator it = m_Children.begin();
it != m_Children.end();
++it )
{
delete *it;
}
m_Children.clear();
return true;
}
template
bool
Mixer::addElementForFunctionBlock(FBType& b)
{
Control::Element *e = new MixerType(*this, b);
if (!e) {
debugError("Control element creation failed\n");
return false;
}
e->setVerboseLevel(getDebugLevel());
return Control::Container::addElement(e);
}
bool
Mixer::addElementForAllFunctionBlocks() {
debugOutput(DEBUG_LEVEL_VERBOSE,"Adding elements for functionblocks...\n");
bool retval = true;
BeBoB::SubunitAudio *asu =
dynamic_cast(m_device.getAudioSubunit(0));
if(asu == NULL) {
debugWarning("No BeBoB audio subunit found\n");
return false;
}
FunctionBlockVector functions=asu->getFunctionBlocks();
for ( FunctionBlockVector::iterator it = functions.begin();
it != functions.end();
++it )
{
FunctionBlock *pfb = *it;
FunctionBlockSelector *ps;
FunctionBlockFeature *pf;
FunctionBlockEnhancedMixer *pm;
if ((ps = dynamic_cast(pfb))) {
debugOutput( DEBUG_LEVEL_VERBOSE, "FB is a SelectorFunctionBlock\n");
retval = addElementForFunctionBlock(*ps);
} else if ((pf = dynamic_cast(pfb))) {
// We might should check if really both feature function
// blocks exists and only then announce them. The FA-101,
// FA-66 and the Ref BCO Audio5 do have both.
debugOutput( DEBUG_LEVEL_VERBOSE, "FB is a FeatureFunctionBlock\n");
retval = addElementForFunctionBlock(*pf);
retval &= addElementForFunctionBlock(*pf);
} else if ((pm = dynamic_cast(pfb))) {
// All BeBoB devices lock the mixer feature function
// block. The AV/C model for this mixer is just to
// complex and the BridgeCo guys decided to use the above
// function feature blocks (level and balance) to achive
// the same.
debugOutput( DEBUG_LEVEL_VERBOSE, "FB is a FunctionBlockEnhancedMixer\n");
retval = addElementForFunctionBlock(*pm);
}
if (!retval) {
std::ostringstream ostrm;
ostrm << (*it)->getName() << " " << (int)((*it)->getId());
debugWarning("Failed to add element for function block %s\n",
ostrm.str().c_str());
};
}
return retval;
}
// --- element implementation classes
MixerFBFeatureVolume::MixerFBFeatureVolume(Mixer& parent, FunctionBlockFeature& s)
: Control::Continuous(&parent)
, m_Parent(parent)
, m_Slave(s)
{
std::ostringstream ostrm;
ostrm << s.getName() << "_Volume_" << (int)(s.getId());
Control::Continuous::setName(ostrm.str());
ostrm.str("");
ostrm << "Label for " << s.getName() << "_Volume " << (int)(s.getId());
setLabel(ostrm.str());
ostrm.str("");
ostrm << "Description for " << s.getName() << "_Volume " << (int)(s.getId());
setDescription(ostrm.str());
}
MixerFBFeatureVolume::~MixerFBFeatureVolume()
{
}
bool
MixerFBFeatureVolume::setValue(double v)
{
return setValue(0, v);
}
bool
MixerFBFeatureVolume::setValue(int idx, double v)
{
int volume=(int)v;
debugOutput(DEBUG_LEVEL_NORMAL,"Set feature volume %d to %d...\n",
m_Slave.getId(), volume);
return m_Parent.getParent().setFeatureFBVolumeCurrent(m_Slave.getId(), idx, volume);
}
double
MixerFBFeatureVolume::getValue()
{
return getValue(0);
}
double
MixerFBFeatureVolume::getValue(int idx)
{
debugOutput(DEBUG_LEVEL_NORMAL,"Get feature volume %d...\n",
m_Slave.getId());
return m_Parent.getParent().getFeatureFBVolumeCurrent(m_Slave.getId(), idx);
}
double
MixerFBFeatureVolume::getMinimum()
{
debugOutput(DEBUG_LEVEL_NORMAL,"Get feature minimum volume %d...\n",
m_Slave.getId());
return m_Parent.getParent().getFeatureFBVolumeMinimum(m_Slave.getId(), 0);
}
double
MixerFBFeatureVolume::getMaximum()
{
debugOutput(DEBUG_LEVEL_NORMAL,"Get feature maximum volume %d...\n",
m_Slave.getId());
return m_Parent.getParent().getFeatureFBVolumeMaximum(m_Slave.getId(), 0);
}
// --- element implementation classes
MixerFBFeatureLRBalance::MixerFBFeatureLRBalance(Mixer& parent, FunctionBlockFeature& s)
: Control::Continuous(&parent)
, m_Parent(parent)
, m_Slave(s)
{
std::ostringstream ostrm;
ostrm << s.getName() << "_LRBalance_" << (int)(s.getId());
Control::Continuous::setName(ostrm.str());
ostrm.str("");
ostrm << "Label for " << s.getName() << "_LRBalance " << (int)(s.getId());
setLabel(ostrm.str());
ostrm.str("");
ostrm << "Description for " << s.getName() << "_LRBalance " << (int)(s.getId());
setDescription(ostrm.str());
}
MixerFBFeatureLRBalance::~MixerFBFeatureLRBalance()
{
}
bool
MixerFBFeatureLRBalance::setValue(double v)
{
return setValue(0, v);
}
bool
MixerFBFeatureLRBalance::setValue(int idx, double v)
{
int volume=(int)v;
debugOutput(DEBUG_LEVEL_NORMAL,"Set feature balance %d to %d...\n",
m_Slave.getId(), volume);
return m_Parent.getParent().setFeatureFBLRBalanceCurrent(m_Slave.getId(), idx, volume);
}
double
MixerFBFeatureLRBalance::getValue()
{
return getValue(0);
}
double
MixerFBFeatureLRBalance::getValue(int idx)
{
debugOutput(DEBUG_LEVEL_NORMAL,"Get feature balance %d...\n",
m_Slave.getId());
return m_Parent.getParent().getFeatureFBLRBalanceCurrent(m_Slave.getId(), idx);
}
double
MixerFBFeatureLRBalance::getMinimum()
{
debugOutput(DEBUG_LEVEL_NORMAL,"Get feature balance volume %d...\n",
m_Slave.getId());
return m_Parent.getParent().getFeatureFBLRBalanceMinimum(m_Slave.getId(), 0);
}
double
MixerFBFeatureLRBalance::getMaximum()
{
debugOutput(DEBUG_LEVEL_NORMAL,"Get feature maximum balance %d...\n",
m_Slave.getId());
return m_Parent.getParent().getFeatureFBLRBalanceMaximum(m_Slave.getId(), 0);
}
// --- element implementation classes
/*
* This function is named with 'EnhancedMixer' but current implementation is
* for 'Processing'. There is several reasons.
* There is no way to distinguish 'EnhancedMixer' from 'Processing', the
* former is an extension of 'Processing' in AV/C audio subunit command.
* The limitation of parameter of Continuous dbus interface. The ffado
* developer considered to change the type of interface but it's not
* reasonable in a point of cost/effect.
* As of Oct 2013, the FFADO developers confirm only M-Audio BeBoB devices uses
* this command to control mixer. No other devices use it. M-Audio BeBoB
* devices can be controlled by single type 'Processing' command even if
* they can be controlled by both single and multi type.
*/
EnhancedMixerFBFeature::EnhancedMixerFBFeature(Mixer& parent, FunctionBlockEnhancedMixer& s)
: Control::Continuous(&parent)
, m_Parent(parent)
, m_Slave(s)
{
std::ostringstream ostrm;
ostrm << s.getName() << "_" << (int)(s.getId());
Control::Continuous::setName(ostrm.str());
ostrm.str("");
ostrm << "Label for " << s.getName() << " " << (int)(s.getId());
setLabel(ostrm.str());
ostrm.str("");
ostrm << "Description for " << s.getName() << " " << (int)(s.getId());
setDescription(ostrm.str());
}
EnhancedMixerFBFeature::~EnhancedMixerFBFeature()
{
}
bool
EnhancedMixerFBFeature::setValue(int idx, double v)
{
int iPlugNum = (idx >> 8) & 0xF;
int iAChNum = (idx >> 4) & 0xF;
int oAChNum = (idx >> 0) & 0xF;
debugOutput(DEBUG_LEVEL_NORMAL,"Set: FBID: 0x%02X, FBPN: 0x%02X, "
"ICN: 0x%02X, OCN: 0x%02X, DATA: 0x%04X\n",
m_Slave.getId(), iPlugNum, iAChNum, oAChNum, (int)v);
return m_Parent.getParent().setProcessingFBMixerSingleCurrent(m_Slave.getId(),
iPlugNum, iAChNum, oAChNum,
(int)v);
}
double
EnhancedMixerFBFeature::getValue(int idx)
{
int iPlugNum = (idx >> 8) & 0xF;
int iAChNum = (idx >> 4) & 0xF;
int oAChNum = (idx >> 0) & 0xF;
debugOutput(DEBUG_LEVEL_NORMAL,"Set: FBID: 0x%02X, FBPN: 0x%02X, "
"ICN: 0x%02X, OCN: 0x%02X\n",
m_Slave.getId(), iPlugNum, iAChNum, oAChNum);
return m_Parent.getParent().getProcessingFBMixerSingleCurrent(m_Slave.getId(),
iPlugNum, iAChNum, oAChNum);
}
// --- element implementation classes
MixerFBSelector::MixerFBSelector(Mixer& parent, FunctionBlockSelector& s)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_Slave(s)
{
std::ostringstream ostrm;
ostrm << s.getName() << "_" << (int)(s.getId());
Control::Discrete::setName(ostrm.str());
ostrm.str("");
ostrm << "Label for " << s.getName() << " " << (int)(s.getId());
setLabel(ostrm.str());
ostrm.str("");
ostrm << "Description for " << s.getName() << " " << (int)(s.getId());
setDescription(ostrm.str());
}
MixerFBSelector::~MixerFBSelector()
{
}
bool
MixerFBSelector::setValue(int v)
{
debugOutput(DEBUG_LEVEL_NORMAL,"Set selector %d to %d...\n",
m_Slave.getId(), v);
return m_Parent.getParent().setSelectorFBValue(m_Slave.getId(), v);
}
int
MixerFBSelector::getValue()
{
debugOutput(DEBUG_LEVEL_NORMAL,"Get selector %d...\n",
m_Slave.getId());
return m_Parent.getParent().getSelectorFBValue(m_Slave.getId());
}
} // end of namespace BeBoB
libffado-2.4.7/src/bebob/bebob_mixer.h 0000644 0001750 0000144 00000007660 14206145246 017165 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef __FFAD0_BEBOB_MIXER__
#define __FFAD0_BEBOB_MIXER__
#include "src/debugmodule/debugmodule.h"
#include "libcontrol/BasicElements.h"
#include
namespace BeBoB {
class Device;
class FunctionBlock;
class FunctionBlockFeature;
class FunctionBlockSelector;
class FunctionBlockEnhancedMixer;
class Mixer
: public Control::Container
{
public:
Mixer(Device &d);
virtual ~Mixer();
virtual std::string getName()
{ return "Mixer"; };
virtual bool setName( std::string n )
{ return false; };
template bool addElementForFunctionBlock(FBType& b);
bool addElementForAllFunctionBlocks();
// manipulation of the contained elements
bool addElement(Control::Element *)
{debugWarning("not allowed"); return false;};
bool deleteElement(Control::Element *);
bool clearElements();
Device& getParent()
{return m_device;};
protected:
Device& m_device;
protected:
DECLARE_DEBUG_MODULE;
};
class MixerFBFeatureVolume
: public Control::Continuous
{
public:
MixerFBFeatureVolume(Mixer& parent, FunctionBlockFeature&);
virtual ~MixerFBFeatureVolume();
virtual bool setValue(double v);
virtual double getValue();
virtual bool setValue(int idx, double v);
virtual double getValue(int idx);
virtual double getMinimum();
virtual double getMaximum();
private:
Mixer& m_Parent;
FunctionBlockFeature& m_Slave;
};
class MixerFBFeatureLRBalance
: public Control::Continuous
{
public:
MixerFBFeatureLRBalance(Mixer& parent, FunctionBlockFeature&);
virtual ~MixerFBFeatureLRBalance();
virtual bool setValue(double v);
virtual double getValue();
virtual bool setValue(int idx, double v);
virtual double getValue(int idx);
virtual double getMinimum();
virtual double getMaximum();
private:
Mixer& m_Parent;
FunctionBlockFeature& m_Slave;
};
class EnhancedMixerFBFeature
: public Control::Continuous
{
public:
EnhancedMixerFBFeature(Mixer& parent, FunctionBlockEnhancedMixer&);
virtual ~EnhancedMixerFBFeature();
virtual bool setValue(int idx, double v);
virtual double getValue(int idx);
virtual bool setValue(double v)
{return setValue(1, v);};
virtual double getValue()
{return getValue(1);};
virtual double getMinimum() {return -32768;};
virtual double getMaximum() {return 0;};
private:
Mixer& m_Parent;
FunctionBlockEnhancedMixer& m_Slave;
};
class MixerFBSelector
: public Control::Discrete
{
public:
MixerFBSelector(Mixer& parent, FunctionBlockSelector&);
virtual ~MixerFBSelector();
virtual bool setValue(int v);
virtual int getValue();
virtual bool setValue(int idx, int v)
{return setValue(v);};
virtual int getValue(int idx)
{return getValue();};
virtual int getMinimum() {return 0;};
virtual int getMaximum() {return 0;};
private:
Mixer& m_Parent;
FunctionBlockSelector& m_Slave;
};
} // end of namespace BeBoB
#endif /* __FFAD0_BEBOB_MIXER__ */
libffado-2.4.7/src/bebob/edirol/ 0000755 0001750 0000144 00000000000 14340644626 016011 5 ustar jwoithe users libffado-2.4.7/src/bebob/edirol/edirol_fa101.cpp 0000644 0001750 0000144 00000004210 14206145246 020653 0 ustar jwoithe users /*
* Copyright (C) 2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#include "edirol_fa101.h"
namespace BeBoB {
namespace Edirol {
EdirolFa101Device::EdirolFa101Device( DeviceManager& d,
ffado_smartptr( configRom ))
: BeBoB::Device( d , configRom)
{
debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Edirol::EdirolFa101Device (NodeID %d)\n",
getConfigRom().getNodeId() );
m_fixed_clocksource.type = FFADODevice::eCT_Auto;
m_fixed_clocksource.valid = true;
m_fixed_clocksource.locked = true;
m_fixed_clocksource.id = 0;
m_fixed_clocksource.slipping = false;
m_fixed_clocksource.description = "Device Controlled";
get1394Service().setFCPResponseFiltering(true);
}
EdirolFa101Device::~EdirolFa101Device()
{
}
FFADODevice::ClockSource
EdirolFa101Device::getActiveClockSource() {
return m_fixed_clocksource;
}
bool
EdirolFa101Device::setActiveClockSource(ClockSource s) {
// can't change, hence only succeed when identical
return s.id == m_fixed_clocksource.id;
}
FFADODevice::ClockSourceVector
EdirolFa101Device::getSupportedClockSources() {
FFADODevice::ClockSourceVector r;
r.push_back(m_fixed_clocksource);
return r;
}
void
EdirolFa101Device::showDevice()
{
debugOutput(DEBUG_LEVEL_VERBOSE, "This is a BeBoB::EdirolFa101::EdirolFa101Device\n");
BeBoB::Device::showDevice();
}
}
}
libffado-2.4.7/src/bebob/edirol/edirol_fa101.h 0000644 0001750 0000144 00000002603 14206145246 020324 0 ustar jwoithe users /*
* Copyright (C) 2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_EDIROL_FA101_H
#define BEBOB_EDIROL_FA101_H
#include "bebob/bebob_avdevice.h"
namespace BeBoB {
namespace Edirol {
class EdirolFa101Device : public BeBoB::Device {
public:
EdirolFa101Device( DeviceManager& d,
ffado_smartptr( configRom ));
virtual ~EdirolFa101Device();
virtual ClockSourceVector getSupportedClockSources();
virtual bool setActiveClockSource(ClockSource);
virtual ClockSource getActiveClockSource();
virtual void showDevice();
private:
ClockSource m_fixed_clocksource;
};
}
}
#endif
libffado-2.4.7/src/bebob/edirol/edirol_fa66.cpp 0000644 0001750 0000144 00000004107 14206145246 020612 0 ustar jwoithe users /*
* Copyright (C) 2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#include "edirol_fa66.h"
namespace BeBoB {
namespace Edirol {
EdirolFa66Device::EdirolFa66Device( DeviceManager& d,
ffado_smartptr( configRom ))
: BeBoB::Device( d , configRom)
{
debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Edirol::EdirolFa66Device (NodeID %d)\n",
getConfigRom().getNodeId() );
m_fixed_clocksource.type = FFADODevice::eCT_Auto;
m_fixed_clocksource.valid = true;
m_fixed_clocksource.locked = true;
m_fixed_clocksource.id = 0;
m_fixed_clocksource.slipping = false;
m_fixed_clocksource.description = "Device Controlled";
}
EdirolFa66Device::~EdirolFa66Device()
{
}
FFADODevice::ClockSource
EdirolFa66Device::getActiveClockSource() {
return m_fixed_clocksource;
}
bool
EdirolFa66Device::setActiveClockSource(ClockSource s) {
// can't change, hence only succeed when identical
return s.id == m_fixed_clocksource.id;
}
FFADODevice::ClockSourceVector
EdirolFa66Device::getSupportedClockSources() {
FFADODevice::ClockSourceVector r;
r.push_back(m_fixed_clocksource);
return r;
}
void
EdirolFa66Device::showDevice()
{
debugOutput(DEBUG_LEVEL_VERBOSE, "This is a BeBoB::EdirolFa66::EdirolFa66Device\n");
BeBoB::Device::showDevice();
}
}
}
libffado-2.4.7/src/bebob/edirol/edirol_fa66.h 0000644 0001750 0000144 00000002576 14206145246 020267 0 ustar jwoithe users /*
* Copyright (C) 2008 by Daniel Wagner
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_EDIROL_FA66_H
#define BEBOB_EDIROL_FA66_H
#include "bebob/bebob_avdevice.h"
namespace BeBoB {
namespace Edirol {
class EdirolFa66Device : public BeBoB::Device {
public:
EdirolFa66Device( DeviceManager& d,
ffado_smartptr( configRom ));
virtual ~EdirolFa66Device();
virtual ClockSourceVector getSupportedClockSources();
virtual bool setActiveClockSource(ClockSource);
virtual ClockSource getActiveClockSource();
virtual void showDevice();
private:
ClockSource m_fixed_clocksource;
};
}
}
#endif
libffado-2.4.7/src/bebob/esi/ 0000755 0001750 0000144 00000000000 14340644626 015313 5 ustar jwoithe users libffado-2.4.7/src/bebob/esi/quatafire610.cpp 0000644 0001750 0000144 00000004077 14206145246 020232 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#include "quatafire610.h"
#include "debugmodule/debugmodule.h"
namespace BeBoB {
namespace ESI {
QuataFireDevice::QuataFireDevice( DeviceManager& d, ffado_smartptr( configRom ))
: BeBoB::Device( d, configRom)
{
m_fixed_clocksource.type = FFADODevice::eCT_Auto;
m_fixed_clocksource.valid = true;
m_fixed_clocksource.locked = true;
m_fixed_clocksource.id = 0;
m_fixed_clocksource.slipping = false;
m_fixed_clocksource.description = "Autoselect";
debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::ESI::QuataFireDevice (NodeID %d)\n",
getConfigRom().getNodeId() );
}
QuataFireDevice::~QuataFireDevice()
{
}
void
QuataFireDevice::showDevice()
{
debugOutput(DEBUG_LEVEL_VERBOSE, "This is a BeBoB::ESI::QuataFireDevice\n");
BeBoB::Device::showDevice();
}
FFADODevice::ClockSource
QuataFireDevice::getActiveClockSource() {
return m_fixed_clocksource;
}
bool
QuataFireDevice::setActiveClockSource(ClockSource s) {
// can't change, hence only succeed when identical
return s.id == m_fixed_clocksource.id;
}
FFADODevice::ClockSourceVector
QuataFireDevice::getSupportedClockSources() {
FFADODevice::ClockSourceVector r;
r.push_back(m_fixed_clocksource);
return r;
}
} // ESI
} // BeBoB
libffado-2.4.7/src/bebob/esi/quatafire610.h 0000644 0001750 0000144 00000003106 14206145246 017667 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_ESI_QUATAFIRE_DEVICE_H
#define BEBOB_ESI_QUATAFIRE_DEVICE_H
#include "bebob/bebob_avdevice.h"
namespace BeBoB {
namespace ESI {
class QuataFireDevice : public BeBoB::Device {
public:
QuataFireDevice( DeviceManager& d, ffado_smartptr( configRom ));
virtual ~QuataFireDevice();
// override these since the quatafire does not support
// setting the clock source (it automatically syncs to SPDIF)
virtual ClockSourceVector getSupportedClockSources();
virtual bool setActiveClockSource(ClockSource);
virtual ClockSource getActiveClockSource();
virtual void showDevice();
private:
ClockSource m_fixed_clocksource;
};
} // namespace BeBoB
} // namespace ESI
#endif
libffado-2.4.7/src/bebob/focusrite/ 0000755 0001750 0000144 00000000000 14340644626 016536 5 ustar jwoithe users libffado-2.4.7/src/bebob/focusrite/focusrite_cmd.cpp 0000644 0001750 0000144 00000004353 14206145246 022070 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#include "focusrite_cmd.h"
#include "libutil/ByteSwap.h"
#include
using namespace std;
using namespace AVC;
namespace BeBoB {
namespace Focusrite {
FocusriteVendorDependentCmd::FocusriteVendorDependentCmd(Ieee1394Service& ieee1394service)
: VendorDependentCmd( ieee1394service )
, m_arg1 ( 0x03 )
, m_arg2 ( 0x01 )
, m_id ( 0x00000000 )
, m_value ( 0x00000000 )
{
m_companyId=0x00130e;
}
FocusriteVendorDependentCmd::~FocusriteVendorDependentCmd()
{
}
bool
FocusriteVendorDependentCmd::serialize( Util::Cmd::IOSSerialize& se )
{
bool result=true;
result &= VendorDependentCmd::serialize( se );
result &= se.write(m_arg1,"FocusriteVendorDependentCmd arg1");
result &= se.write(m_arg2,"FocusriteVendorDependentCmd arg2");
// FIXME: this is not consistent, we should not have to care about CondSwapFromBus32 here
result &= se.write(CondSwapToBus32(m_id),"FocusriteVendorDependentCmd ID");
result &= se.write(CondSwapToBus32(m_value),"FocusriteVendorDependentCmd value");
return result;
}
bool
FocusriteVendorDependentCmd::deserialize( Util::Cmd::IISDeserialize& de )
{
bool result=true;
result &= VendorDependentCmd::deserialize( de );
result &= de.read(&m_arg1);
result &= de.read(&m_arg2);
result &= de.read(&m_id);
m_id=CondSwapFromBus32(m_id);
result &= de.read(&m_value);
m_value=CondSwapFromBus32(m_value);
return result;
}
}
}
libffado-2.4.7/src/bebob/focusrite/focusrite_cmd.h 0000644 0001750 0000144 00000003121 14206145246 021525 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB
*
* 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) version 3 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, see .
*
*/
#ifndef FOCUSRITEVENDORDEPENDENT_H
#define FOCUSRITEVENDORDEPENDENT_H
#include "libavc/general/avc_generic.h"
#include "libutil/cmd_serialize.h"
#include "libavc/general/avc_vendor_dependent_cmd.h"
namespace BeBoB {
namespace Focusrite {
class FocusriteVendorDependentCmd: public AVC::VendorDependentCmd
{
public:
FocusriteVendorDependentCmd(Ieee1394Service& ieee1394service);
virtual ~FocusriteVendorDependentCmd();
virtual bool serialize( Util::Cmd::IOSSerialize& se );
virtual bool deserialize( Util::Cmd::IISDeserialize& de );
virtual const char* getCmdName() const
{ return "FocusriteVendorDependentCmd"; }
byte_t m_arg1;
byte_t m_arg2;
quadlet_t m_id;
quadlet_t m_value;
};
}
}
#endif // FOCUSRITEVENDORDEPENDENT_H
libffado-2.4.7/src/bebob/focusrite/focusrite_generic.cpp 0000644 0001750 0000144 00000041407 14206145246 022742 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#include "focusrite_saffirepro.h"
#include "focusrite_cmd.h"
#include "libutil/ByteSwap.h"
namespace BeBoB {
namespace Focusrite {
FocusriteDevice::FocusriteDevice( DeviceManager& d, ffado_smartptr( configRom ))
: BeBoB::Device( d, configRom)
, m_cmd_time_interval( 0 )
, m_earliest_next_cmd_time( 0 )
{
debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::FocusriteDevice (NodeID %d)\n",
getConfigRom().getNodeId() );
addOption(Util::OptionContainer::Option("useAvcForParameters", false));
}
void
FocusriteDevice::showDevice()
{
debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::FocusriteDevice\n");
BeBoB::Device::showDevice();
}
void
FocusriteDevice::setVerboseLevel(int l)
{
debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
BeBoB::Device::setVerboseLevel(l);
}
bool
FocusriteDevice::setSpecificValue(uint32_t id, uint32_t v)
{
debugOutput(DEBUG_LEVEL_VERBOSE, "Writing parameter address space id 0x%08X (%u), data: 0x%08X\n",
id, id, v);
bool use_avc = false;
if(!getOption("useAvcForParameters", use_avc)) {
debugWarning("Could not retrieve useAvcForParameters parameter, defaulting to false\n");
}
// rate control
ffado_microsecs_t now = Util::SystemTimeSource::getCurrentTimeAsUsecs();
if(m_cmd_time_interval && (m_earliest_next_cmd_time > now)) {
ffado_microsecs_t wait = m_earliest_next_cmd_time - now;
debugOutput( DEBUG_LEVEL_VERBOSE, "Rate control... %" PRIu64 "\n", wait );
Util::SystemTimeSource::SleepUsecRelative(wait);
}
m_earliest_next_cmd_time = now + m_cmd_time_interval;
if (use_avc) {
return setSpecificValueAvc(id, v);
} else {
return setSpecificValueARM(id, v);
}
}
bool
FocusriteDevice::getSpecificValue(uint32_t id, uint32_t *v)
{
bool retval;
bool use_avc = false;
if(!getOption("useAvcForParameters", use_avc)) {
debugWarning("Could not retrieve useAvcForParameters parameter, defaulting to false\n");
}
// rate control
ffado_microsecs_t now = Util::SystemTimeSource::getCurrentTimeAsUsecs();
if(m_cmd_time_interval && (m_earliest_next_cmd_time > now)) {
ffado_microsecs_t wait = m_earliest_next_cmd_time - now;
debugOutput( DEBUG_LEVEL_VERBOSE, "Rate control... %" PRIu64 "\n", wait );
Util::SystemTimeSource::SleepUsecRelative(wait);
}
m_earliest_next_cmd_time = now + m_cmd_time_interval;
// execute
if (use_avc) {
retval = getSpecificValueAvc(id, v);
} else {
retval = getSpecificValueARM(id, v);
}
debugOutput(DEBUG_LEVEL_VERBOSE,"Read parameter address space id 0x%08X (%u): %08X\n", id, id, *v);
return retval;
}
// The AV/C methods to set parameters
bool
FocusriteDevice::setSpecificValueAvc(uint32_t id, uint32_t v)
{
FocusriteVendorDependentCmd cmd( get1394Service() );
cmd.setCommandType( AVC::AVCCommand::eCT_Control );
cmd.setNodeId( getConfigRom().getNodeId() );
cmd.setSubunitType( AVC::eST_Unit );
cmd.setSubunitId( 0xff );
cmd.setVerbose( getDebugLevel() );
// cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE );
cmd.m_id=id;
cmd.m_value=v;
if ( !cmd.fire() ) {
debugError( "FocusriteVendorDependentCmd info command failed\n" );
return false;
}
return true;
}
bool
FocusriteDevice::getSpecificValueAvc(uint32_t id, uint32_t *v)
{
FocusriteVendorDependentCmd cmd( get1394Service() );
cmd.setCommandType( AVC::AVCCommand::eCT_Status );
cmd.setNodeId( getConfigRom().getNodeId() );
cmd.setSubunitType( AVC::eST_Unit );
cmd.setSubunitId( 0xff );
cmd.setVerbose( getDebugLevel() );
// cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE );
cmd.m_id=id;
if ( !cmd.fire() ) {
debugError( "FocusriteVendorDependentCmd info command failed\n" );
return false;
}
*v=cmd.m_value;
return true;
}
// The ARM methods to set parameters
bool
FocusriteDevice::setSpecificValueARM(uint32_t id, uint32_t v)
{
fb_quadlet_t data = v;
debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing parameter address space id 0x%08X (%u), data: 0x%08X\n",
id, id, data);
fb_nodeaddr_t addr = FR_PARAM_SPACE_START + (id * 4);
fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
if(!get1394Service().write_quadlet( nodeId, addr, CondSwapToBus32(data) ) ) {
debugError("Could not write to node 0x%04X addr 0x%012" PRIX64 "\n", nodeId, addr);
return false;
}
return true;
}
bool
FocusriteDevice::getSpecificValueARM(uint32_t id, uint32_t *v)
{
fb_quadlet_t result;
debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading parameter address space id 0x%08X\n", id);
fb_nodeaddr_t addr = FR_PARAM_SPACE_START + (id * 4);
fb_nodeid_t nodeId = getNodeId() | 0xFFC0;
if(!get1394Service().read_quadlet( nodeId, addr, &result ) ) {
debugError("Could not read from node 0x%04X addr 0x%012" PRIX64 "\n", nodeId, addr);
return false;
}
result = CondSwapFromBus32(result);
debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Read result: 0x%08X\n", result);
*v = result;
return true;
}
int
FocusriteDevice::convertDefToSr( uint32_t def ) {
switch(def) {
case FOCUSRITE_CMD_SAMPLERATE_44K1: return 44100;
case FOCUSRITE_CMD_SAMPLERATE_48K: return 48000;
case FOCUSRITE_CMD_SAMPLERATE_88K2: return 88200;
case FOCUSRITE_CMD_SAMPLERATE_96K: return 96000;
case FOCUSRITE_CMD_SAMPLERATE_176K4: return 176400;
case FOCUSRITE_CMD_SAMPLERATE_192K: return 192000;
default:
debugWarning("Unsupported samplerate def: %08X\n", def);
return 0;
}
}
uint32_t
FocusriteDevice::convertSrToDef( int sr ) {
switch(sr) {
case 44100: return FOCUSRITE_CMD_SAMPLERATE_44K1;
case 48000: return FOCUSRITE_CMD_SAMPLERATE_48K;
case 88200: return FOCUSRITE_CMD_SAMPLERATE_88K2;
case 96000: return FOCUSRITE_CMD_SAMPLERATE_96K;
case 176400: return FOCUSRITE_CMD_SAMPLERATE_176K4;
case 192000: return FOCUSRITE_CMD_SAMPLERATE_192K;
default:
debugWarning("Unsupported samplerate: %d\n", sr);
return 0;
}
}
// --- element implementation classes
BinaryControl::BinaryControl(FocusriteDevice& parent, int id, int bit)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
, m_cmd_bit ( bit )
{}
BinaryControl::BinaryControl(FocusriteDevice& parent, int id, int bit,
std::string name, std::string label, std::string descr)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
, m_cmd_bit ( bit )
{
setName(name);
setLabel(label);
setDescription(descr);
}
bool
BinaryControl::setValue(int v)
{
uint32_t reg;
uint32_t old_reg;
if ( !m_Parent.getSpecificValue(m_cmd_id, ®) ) {
debugError( "getSpecificValue failed\n" );
return 0;
}
old_reg=reg;
if (v) {
reg |= (1< 0x%08X)\n",
m_cmd_id, v, old_reg, reg);
if ( !m_Parent.setSpecificValue(m_cmd_id, reg) ) {
debugError( "setSpecificValue failed\n" );
return false;
} else return true;
}
int
BinaryControl::getValue()
{
uint32_t reg;
if ( !m_Parent.getSpecificValue(m_cmd_id, ®) ) {
debugError( "getSpecificValue failed\n" );
return 0;
} else {
bool val= (reg & (1<0x07FFF) v=0x07FFF;
else if (v<0) v=0;
debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for id %d to %d\n",
m_cmd_id, v);
if ( !m_Parent.setSpecificValue(m_cmd_id, v) ) {
debugError( "setSpecificValue failed\n" );
return false;
} else return true;
}
int
VolumeControl::getValue()
{
uint32_t val=0;
if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
debugError( "getSpecificValue failed\n" );
return 0;
} else {
debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",
m_cmd_id, val);
return val;
}
}
MeteringControl::MeteringControl(FocusriteDevice& parent, int id)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
{}
MeteringControl::MeteringControl(FocusriteDevice& parent, int id,
std::string name, std::string label, std::string descr)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
{
setName(name);
setLabel(label);
setDescription(descr);
}
int
MeteringControl::getValue()
{
uint32_t val=0;
if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
debugError( "getSpecificValue failed\n" );
return 0;
} else {
debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",
m_cmd_id, val);
return val;
}
}
// reg control
RegisterControl::RegisterControl(FocusriteDevice& parent)
: Control::Register(&parent)
, m_Parent(parent)
{}
RegisterControl::RegisterControl(FocusriteDevice& parent,
std::string name, std::string label, std::string descr)
: Control::Register(&parent)
, m_Parent(parent)
{
setName(name);
setLabel(label);
setDescription(descr);
}
bool
RegisterControl::setValue(uint64_t addr, uint64_t v)
{
debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for addr %" PRIu64 " to %" PRIu64 "\n",
addr, v);
if ( !m_Parent.setSpecificValue(addr, v) ) {
debugError( "setSpecificValue failed\n" );
return false;
} else return true;
}
uint64_t
RegisterControl::getValue(uint64_t addr)
{
uint32_t val=0;
if ( !m_Parent.getSpecificValue(addr, &val) ) {
debugError( "getSpecificValue failed\n" );
return 0;
} else {
debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %" PRIu64 " = %u\n",
addr, val);
return val;
}
}
// low resolution volume control
VolumeControlLowRes::VolumeControlLowRes(FocusriteDevice& parent, int id, int shift)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
, m_bit_shift( shift )
{}
VolumeControlLowRes::VolumeControlLowRes(FocusriteDevice& parent, int id, int shift,
std::string name, std::string label, std::string descr)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
, m_bit_shift( shift )
{
setName(name);
setLabel(label);
setDescription(descr);
}
bool
VolumeControlLowRes::setValue(int v)
{
uint32_t reg;
uint32_t old_reg;
if (v>0xFF) v=0xFF;
else if (v<0) v=0;
if ( !m_Parent.getSpecificValue(m_cmd_id, ®) ) {
debugError( "getSpecificValue failed\n" );
return 0;
}
old_reg=reg;
reg &= ~(0xFF< 0x%08X)\n",
m_cmd_id, v, m_bit_shift, old_reg, reg);
if ( !m_Parent.setSpecificValue(m_cmd_id, reg) ) {
debugError( "setSpecificValue failed\n" );
return false;
} else return true;
}
int
VolumeControlLowRes::getValue()
{
uint32_t val, reg;
if ( !m_Parent.getSpecificValue(m_cmd_id, ®) ) {
debugError( "getSpecificValue failed\n" );
return 0;
} else {
val = (reg & 0xFF)>>m_bit_shift;
debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d: reg: 0x%08X, result=%d\n",
m_cmd_id, reg, val);
return val;
}
}
// hardware dial control
DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, int shift)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
, m_shift ( shift )
{}
DialPositionControl::DialPositionControl(FocusriteDevice& parent, int id, int shift,
std::string name, std::string label, std::string descr)
: Control::Discrete(&parent)
, m_Parent(parent)
, m_cmd_id ( id )
, m_shift ( shift )
{
setName(name);
setLabel(label);
setDescription(descr);
}
int
DialPositionControl::getValue()
{
uint32_t val=0;
if ( !m_Parent.getSpecificValue(m_cmd_id, &val) ) {
debugError( "getSpecificValue failed\n" );
return 0;
} else {
if (m_shift > 0) {
val = val >> m_shift;
} else if (m_shift < 0) {
val = val << -m_shift;
}
debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for %d = %d\n",
m_cmd_id, val);
return val;
}
}
// Saffire pro matrix mixer element
FocusriteMatrixMixer::FocusriteMatrixMixer(FocusriteDevice& p)
: Control::MatrixMixer(&p, "MatrixMixer")
, m_Parent(p)
{
}
FocusriteMatrixMixer::FocusriteMatrixMixer(FocusriteDevice& p,std::string n)
: Control::MatrixMixer(&p, n)
, m_Parent(p)
{
}
void FocusriteMatrixMixer::addSignalInfo(std::vector &target,
std::string name, std::string label, std::string descr)
{
struct sSignalInfo s;
s.name=name;
s.label=label;
s.description=descr;
target.push_back(s);
}
void FocusriteMatrixMixer::setCellInfo(int row, int col, int addr, bool valid)
{
struct sCellInfo c;
c.row=row;
c.col=col;
c.valid=valid;
c.address=addr;
m_CellInfo.at(row).at(col) = c;
}
void FocusriteMatrixMixer::show()
{
debugOutput(DEBUG_LEVEL_NORMAL, "Focusrite Matrix mixer\n");
}
std::string FocusriteMatrixMixer::getRowName( const int row )
{
debugOutput(DEBUG_LEVEL_VERBOSE, "name for row %d is %s\n",
row, m_RowInfo.at(row).name.c_str());
return m_RowInfo.at(row).name;
}
std::string FocusriteMatrixMixer::getColName( const int col )
{
debugOutput(DEBUG_LEVEL_VERBOSE, "name for col %d is %s\n",
col, m_ColInfo.at(col).name.c_str());
return m_ColInfo.at(col).name;
}
int FocusriteMatrixMixer::canWrite( const int row, const int col )
{
debugOutput(DEBUG_LEVEL_VERBOSE, "canWrite for row %d col %d is %d\n",
row, col, m_CellInfo.at(row).at(col).valid);
return m_CellInfo.at(row).at(col).valid;
}
double FocusriteMatrixMixer::setValue( const int row, const int col, const double val )
{
int32_t v = (int32_t)val;
struct sCellInfo c = m_CellInfo.at(row).at(col);
debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for id %d row %d col %d to %lf (%d)\n",
c.address, row, col, val, v);
if (v>0x07FFF) v=0x07FFF;
else if (v<0) v=0;
if ( !m_Parent.setSpecificValue(c.address, v) ) {
debugError( "setSpecificValue failed\n" );
return false;
} else return true;
}
double FocusriteMatrixMixer::getValue( const int row, const int col )
{
struct sCellInfo c=m_CellInfo.at(row).at(col);
uint32_t val=0;
if ( !m_Parent.getSpecificValue(c.address, &val) ) {
debugError( "getSpecificValue failed\n" );
return 0;
} else {
debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for id %d row %d col %d = %u\n",
c.address, row, col, val);
return val;
}
}
int FocusriteMatrixMixer::getRowCount( )
{
return m_RowInfo.size();
}
int FocusriteMatrixMixer::getColCount( )
{
return m_ColInfo.size();
}
} // Focusrite
} // BeBoB
libffado-2.4.7/src/bebob/focusrite/focusrite_generic.h 0000644 0001750 0000144 00000016606 14206145246 022412 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Daniel Wagner
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#ifndef BEBOB_FOCUSRITE_GENERIC_DEVICE_H
#define BEBOB_FOCUSRITE_GENERIC_DEVICE_H
#include "debugmodule/debugmodule.h"
#include "bebob/bebob_avdevice.h"
#include "libcontrol/BasicElements.h"
#include "libcontrol/MatrixMixer.h"
#include "libutil/SystemTimeSource.h"
#define FR_PARAM_SPACE_START 0x000100000000LL
namespace BeBoB {
namespace Focusrite {
class FocusriteDevice;
class BinaryControl
: public Control::Discrete
{
public:
BinaryControl(FocusriteDevice& parent, int id, int bit);
BinaryControl(FocusriteDevice& parent, int id, int bit,
std::string name, std::string label, std::string descr);
virtual bool setValue(int v);
virtual int getValue();
virtual bool setValue(int idx, int v)
{return setValue(v);};
virtual int getValue(int idx)
{return getValue();};
virtual int getMinimum() {return 0;};
virtual int getMaximum() {return 1;};
private:
FocusriteDevice& m_Parent;
unsigned int m_cmd_id;
unsigned int m_cmd_bit;
};
class VolumeControl
: public Control::Discrete
{
public:
VolumeControl(FocusriteDevice& parent, int id);
VolumeControl(FocusriteDevice& parent, int id,
std::string name, std::string label, std::string descr);
virtual bool setValue(int v);
virtual int getValue();
virtual bool setValue(int idx, int v)
{return setValue(v);};
virtual int getValue(int idx)
{return getValue();};
virtual int getMinimum() {return 0;};
virtual int getMaximum() {return 0x07FFF;};
private:
FocusriteDevice& m_Parent;
unsigned int m_cmd_id;
};
class MeteringControl
: public Control::Discrete
{
public:
MeteringControl(FocusriteDevice& parent, int id);
MeteringControl(FocusriteDevice& parent, int id,
std::string name, std::string label, std::string descr);
virtual bool setValue(int v) {return false;};
virtual int getValue();
virtual bool setValue(int idx, int v)
{return setValue(v);};
virtual int getValue(int idx)
{return getValue();};
virtual int getMinimum() {return 0;};
virtual int getMaximum() {return 0x07FFF;};
private:
FocusriteDevice& m_Parent;
unsigned int m_cmd_id;
};
class RegisterControl
: public Control::Register
{
public:
RegisterControl(FocusriteDevice& parent);
RegisterControl(FocusriteDevice& parent,
std::string name, std::string label, std::string descr);
virtual bool setValue(uint64_t addr, uint64_t value);
virtual uint64_t getValue(uint64_t addr);
private:
FocusriteDevice& m_Parent;
};
class VolumeControlLowRes
: public Control::Discrete
{
public:
VolumeControlLowRes(FocusriteDevice& parent, int id, int shift);
VolumeControlLowRes(FocusriteDevice& parent, int id, int shift,
std::string name, std::string label, std::string descr);
virtual bool setValue(int v);
virtual int getValue();
virtual bool setValue(int idx, int v)
{return setValue(v);};
virtual int getValue(int idx)
{return getValue();};
virtual int getMinimum() {return 0;};
virtual int getMaximum() {return 0x0FF;};
private:
FocusriteDevice& m_Parent;
unsigned int m_cmd_id;
unsigned int m_bit_shift;
};
class DialPositionControl
: public Control::Discrete
{
public:
DialPositionControl(FocusriteDevice& parent, int id, int shift);
DialPositionControl(FocusriteDevice& parent, int id, int shift,
std::string name, std::string label, std::string descr);
virtual bool setValue(int v) {return false;};
virtual int getValue();
virtual bool setValue(int idx, int v)
{return setValue(v);};
virtual int getValue(int idx)
{return getValue();};
virtual int getMinimum() {return 0;};
virtual int getMaximum() {return 0x07FFF;};
private:
FocusriteDevice& m_Parent;
unsigned int m_cmd_id;
int m_shift;
};
class FocusriteMatrixMixer : public Control::MatrixMixer
{
public:
FocusriteMatrixMixer(FocusriteDevice& parent);
FocusriteMatrixMixer(FocusriteDevice& parent, std::string n);
virtual ~FocusriteMatrixMixer() {};
virtual void show();
virtual int getRowCount( );
virtual int getColCount( );
virtual int canWrite( const int, const int );
virtual double setValue( const int, const int, const double );
virtual double getValue( const int, const int );
// full map updates are unsupported
virtual bool getCoefficientMap(int &) {return false;};
virtual bool storeCoefficientMap(int &) {return false;};
bool hasNames() const { return true; }
virtual std::string getRowName( const int );
virtual std::string getColName( const int );
bool canConnect() const { return false; }
protected:
struct sSignalInfo {
std::string name;
std::string label;
std::string description;
};
struct sCellInfo {
int row;
int col;
// indicates whether a cell can be valid, this
// doesn't mean that it is writable. Just that it can be.
bool valid;
// the address to use when manipulating this cell
int address;
};
virtual void init() = 0;
virtual void addSignalInfo(std::vector &target,
std::string name, std::string label, std::string descr);
virtual void setCellInfo(int row, int col, int addr, bool valid);
std::vector m_RowInfo;
std::vector m_ColInfo;
std::vector< std::vector > m_CellInfo;
FocusriteDevice& m_Parent;
};
class FocusriteDevice : public BeBoB::Device {
public:
FocusriteDevice(DeviceManager& d, ffado_smartptr( configRom ));
virtual ~FocusriteDevice() {};
virtual void showDevice();
virtual void setVerboseLevel(int l);
public:
bool setSpecificValue(uint32_t id, uint32_t v);
bool getSpecificValue(uint32_t id, uint32_t *v);
protected:
int convertDefToSr( uint32_t def );
uint32_t convertSrToDef( int sr );
private:
bool setSpecificValueAvc(uint32_t id, uint32_t v);
bool getSpecificValueAvc(uint32_t id, uint32_t *v);
bool setSpecificValueARM(uint32_t id, uint32_t v);
bool getSpecificValueARM(uint32_t id, uint32_t *v);
protected:
ffado_microsecs_t m_cmd_time_interval;
ffado_microsecs_t m_earliest_next_cmd_time;
};
} // namespace Focusrite
} // namespace BeBoB
#endif
libffado-2.4.7/src/bebob/focusrite/focusrite_saffire.cpp 0000644 0001750 0000144 00000102001 14206145246 022731 0 ustar jwoithe users /*
* Copyright (C) 2005-2008 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free FireWire (pro-)audio drivers for Linux
*
* FFADO is based upon FreeBoB.
*
* 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) version 3 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, see .
*
*/
#include "focusrite_saffire.h"
#include "focusrite_cmd.h"
#include "devicemanager.h"
namespace BeBoB {
namespace Focusrite {
SaffireDevice::SaffireDevice( DeviceManager& d, ffado_smartptr( configRom ))
: FocusriteDevice( d, configRom)
, m_MixerContainer( NULL )
{
debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::Focusrite::SaffireDevice (NodeID %d)\n",
getConfigRom().getNodeId() );
if(getConfigRom().getGuid() < 0x130e0100040000LL) {
m_isSaffireLE = false;
} else {
m_isSaffireLE = true;
}
// find the configured delay time for this device
Util::Configuration &config = d.getConfiguration();
int delaytime = 0;
if(config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "cmd_interval_time", delaytime)) {
m_cmd_time_interval = delaytime;
debugOutput( DEBUG_LEVEL_VERBOSE, "Setting command interval time to %" PRIu64 "\n",
m_cmd_time_interval );
} else {
m_cmd_time_interval = 10000;
debugOutput( DEBUG_LEVEL_VERBOSE, "No command interval time setting found, defaulting to %" PRIu64 "\n",
m_cmd_time_interval );
}
}
bool
SaffireDevice::buildMixer()
{
bool result=true;
debugOutput(DEBUG_LEVEL_VERBOSE, "Building a Focusrite Saffire mixer...\n");
destroyMixer();
// create the mixer object container
m_MixerContainer = new Control::Container(this, "Mixer");
if (!m_MixerContainer) {
debugError("Could not create mixer container...\n");
return false;
}
if(m_isSaffireLE) {
// create control objects for the saffire LE
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_SPDIF_TRANSPARENT, 0,
"SpdifTransparent", "S/PDIF Transparent", "S/PDIF Transparent"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_MIDITHRU, 0,
"MidiThru", "MIDI Thru", "MIDI Thru"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_SAVE_SETTINGS, 0,
"SaveSettings", "Save Settings", "Save Settings"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_HIGH_GAIN_LINE3, 0,
"HighGainLine3", "High Gain Line-in 3", "High Gain Line-in 3"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_HIGH_GAIN_LINE4, 0,
"HighGainLine4", "High Gain Line-in 4", "High Gain Line-in 4"));
// output mute controls
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_MUTE,
"Out12Mute", "Out1/2 Mute", "Output 1/2 Mute"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_MUTE,
"Out34Mute", "Out3/4 Mute", "Output 3/4 Mute"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_MUTE,
"Out56Mute", "Out5/6 Mute", "Output 5/6 Mute"));
// output front panel hw volume control
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_HWCTRL,
"Out12HwCtrl", "Out1/2 HwCtrl", "Output 1/2 Front Panel Hardware volume control"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_HWCTRL,
"Out34HwCtrl", "Out3/4 HwCtrl", "Output 3/4 Front Panel Hardware volume control"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_HWCTRL,
"Out56HwCtrl", "Out5/6 HwCtrl", "Output 5/6 Front Panel Hardware volume control"));
// dac ignore
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DACIGNORE,
"Out12DacIgnore", "Out1/2 Dac Ignore", "Output 1/2 Dac Ignore"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DACIGNORE,
"Out34DacIgnore", "Out3/4 Dac Ignore", "Output 3/4 Dac Ignore"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DACIGNORE,
"Out56DacIgnore", "Out5/6 Dac Ignore", "Output 5/6 Dac Ignore"));
// output level controls
result &= m_MixerContainer->addElement(
new VolumeControlLowRes(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DAC,
"Out12Level", "Out1/2 Level", "Output 1/2 Level"));
result &= m_MixerContainer->addElement(
new VolumeControlLowRes(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DAC,
"Out34Level", "Out3/4 Level", "Output 3/4 Level"));
result &= m_MixerContainer->addElement(
new VolumeControlLowRes(*this,
FR_SAFFIRELE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRELE_CMD_ID_BITFIELD_BIT_DAC,
"Out56Level", "Out5/6 Level", "Output 5/6 Level"));
} else {
// create control objects for the saffire
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_INPUT_SOURCE, 0,
"SpdifSwitch", "S/PDIF Switch", "S/PDIF Switch"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_MONO_MODE, 0,
"MonoMode", "Mono Mode", "Toggle Mono Mode"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_DEVICE_MODE, 0,
"DeviceMode", "Device Mode", "Toggle Device Mode"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_EXTERNAL_LOCK, 0,
"ExternalLock", "External Lock", "Has external lock?"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_AUDIO_ON_STATUS, 0,
"AudioOnStatus", "Audio On Status", "Audio On Status"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_SAVE_SETTINGS, 0,
"SaveSettings", "Save Settings", "Save Settings"));
// output mute controls
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
"Out12Mute", "Out1/2 Mute", "Output 1/2 Mute"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
"Out34Mute", "Out3/4 Mute", "Output 3/4 Mute"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
"Out56Mute", "Out5/6 Mute", "Output 5/6 Mute"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
"Out78Mute", "Out7/8 Mute", "Output 7/8 Mute"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT910, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_MUTE,
"Out910Mute", "Out9/10 Mute", "Output 9/10 Mute"));
// output front panel hw volume control
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
"Out12HwCtrl", "Out1/2 HwCtrl", "Output 1/2 Front Panel Hardware volume control"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
"Out34HwCtrl", "Out3/4 HwCtrl", "Output 3/4 Front Panel Hardware volume control"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
"Out56HwCtrl", "Out5/6 HwCtrl", "Output 5/6 Front Panel Hardware volume control"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_HWCTRL,
"Out78HwCtrl", "Out7/8 HwCtrl", "Output 7/8 Front Panel Hardware volume control"));
// output level dim
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DIM,
"Out12Dim", "Out1/2 Dim", "Output 1/2 Level Dim"));
// dac ignore
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
"Out12DacIgnore", "Out1/2 Dac Ignore", "Output 1/2 Dac Ignore"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
"Out34DacIgnore", "Out3/4 Dac Ignore", "Output 3/4 Dac Ignore"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
"Out56DacIgnore", "Out5/6 Dac Ignore", "Output 5/6 Dac Ignore"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DACIGNORE,
"Out78DacIgnore", "Out7/8 Dac Ignore", "Output 7/8 Dac Ignore"));
// output level controls
result &= m_MixerContainer->addElement(
new VolumeControlLowRes(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT12, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
"Out12Level", "Out1/2 Level", "Output 1/2 Level"));
result &= m_MixerContainer->addElement(
new VolumeControlLowRes(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT34, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
"Out34Level", "Out3/4 Level", "Output 3/4 Level"));
result &= m_MixerContainer->addElement(
new VolumeControlLowRes(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT56, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
"Out56Level", "Out5/6 Level", "Output 5/6 Level"));
result &= m_MixerContainer->addElement(
new VolumeControlLowRes(*this,
FR_SAFFIRE_CMD_ID_BITFIELD_OUT78, FR_SAFFIRE_CMD_ID_BITFIELD_BIT_DAC,
"Out78Level", "Out7/8 Level", "Output 7/8 Level"));
result &= m_MixerContainer->addElement(
new DialPositionControl(*this,
FR_SAFFIRE_CMD_ID_MONITOR_DIAL, 0,
"MonitorDial", "Monitor Dial", "Monitor Dial Value"));
// metering
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_IN1,
"MeteringIn1", "Metering Input 1", "Metering on Input 1"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_IN2,
"MeteringIn2", "Metering Input 2", "Metering on Input 2"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_IN3,
"MeteringIn3", "Metering Input 3", "Metering on Input 3"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_IN4,
"MeteringIn4", "Metering Input 4", "Metering on Input 4"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC1,
"MeteringPc1", "Metering PC 1", "Metering on PC Channel 1"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC2,
"MeteringPc2", "Metering PC 2", "Metering on PC Channel 2"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC3,
"MeteringPc3", "Metering PC 3", "Metering on PC Channel 3"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC4,
"MeteringPc4", "Metering PC 4", "Metering on PC Channel 4"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC5,
"MeteringPc5", "Metering PC 5", "Metering on PC Channel 5"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC6,
"MeteringPc6", "Metering PC 6", "Metering on PC Channel 6"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC7,
"MeteringPc7", "Metering PC 7", "Metering on PC Channel 7"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC8,
"MeteringPc8", "Metering PC 8", "Metering on PC Channel 8"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC9,
"MeteringPc9", "Metering PC 9", "Metering on PC Channel 9"));
result &= m_MixerContainer->addElement(
new MeteringControl(*this,
FR_SAFFIRE_CMD_ID_METERING_PC10,
"MeteringPc10", "Metering PC 10", "Metering on PC Channel 10"));
}
// matrix mix controls
if(m_isSaffireLE) {
result &= m_MixerContainer->addElement(
new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_LEMix48, "LEMix48"));
result &= m_MixerContainer->addElement(
new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_LEMix96, "LEMix96"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_SWAP_OUT4_OUT1_48K, 0,
"Swap41_48", "Swap41_48", "Swap41_48"));
result &= m_MixerContainer->addElement(
new BinaryControl(*this,
FR_SAFFIRELE_CMD_ID_SWAP_OUT4_OUT1_96K, 0,
"Swap41_96", "Swap41_96", "Swap41_96"));
} else {
result &= m_MixerContainer->addElement(
new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireStereoMatrixMix, "MatrixMixerStereo"));
result &= m_MixerContainer->addElement(
new SaffireMatrixMixer(*this, SaffireMatrixMixer::eMMT_SaffireMonoMatrixMix, "MatrixMixerMono"));
}
if (!result) {
debugWarning("One or more control elements could not be created.");
// clean up those that were created
destroyMixer();
return false;
}
if (!addElement(m_MixerContainer)) {
debugWarning("Could not register mixer to device\n");
// clean up
destroyMixer();
return false;
}
// add a direct register access element
if (!addElement(new RegisterControl(*this, "Register", "Register Access", "Direct register access"))) {
debugWarning("Could not create register control element.");
// clean up those that were created
destroyMixer();
return false;
}
return true;
}
bool
SaffireDevice::destroyMixer()
{
debugOutput(DEBUG_LEVEL_VERBOSE, "destroy mixer...\n");
if (m_MixerContainer == NULL) {
debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n");
return true;
}
if (!deleteElement(m_MixerContainer)) {
debugError("Mixer present but not registered to the avdevice\n");
return false;
}
// remove and delete (as in free) child control elements
m_MixerContainer->clearElements(true);
delete m_MixerContainer;
return true;
}
std::vector
SaffireDevice::getSupportedSamplingFrequencies()
{
std::vector frequencies;
frequencies.push_back(44100);
frequencies.push_back(48000);
frequencies.push_back(88200);
frequencies.push_back(96000);
return frequencies;
}
void
SaffireDevice::showDevice()
{
if(m_isSaffireLE) {
debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::SaffireDevice (Saffire LE)\n");
} else {
debugOutput(DEBUG_LEVEL_NORMAL, "This is a BeBoB::Focusrite::SaffireDevice (Saffire)\n");
}
FocusriteDevice::showDevice();
}
void
SaffireDevice::setVerboseLevel(int l)
{
debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
FocusriteDevice::setVerboseLevel(l);
}
// Saffire pro matrix mixer element
SaffireMatrixMixer::SaffireMatrixMixer(SaffireDevice& p,
enum eMatrixMixerType type)
: FocusriteMatrixMixer(p, "MatrixMixer")
, m_type(type)
{
init();
}
SaffireMatrixMixer::SaffireMatrixMixer(SaffireDevice& p,
enum eMatrixMixerType type, std::string n)
: FocusriteMatrixMixer(p, n)
, m_type(type)
{
init();
}
void SaffireMatrixMixer::init()
{
if (m_type==eMMT_SaffireStereoMatrixMix) {
m_RowInfo.clear();
addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10");
addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2");
addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4");
addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6");
addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8");
addSignalInfo(m_RowInfo, "IN12", "Input 1/2", "Hardware Inputs 1/2");
addSignalInfo(m_RowInfo, "IN34", "Input 3/4", "Hardware Inputs 3/4 (dry / S/PDIF)");
addSignalInfo(m_RowInfo, "FX", "Effect return", "Effect return");
m_ColInfo.clear();
addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10");
addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2");
addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4");
addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)");
addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)");
// init the cell matrix
#define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS 5
#define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS 8
#define FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET 0
std::vector tmp_cols( FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS );
std::vector< std::vector > tmp_all(FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS, tmp_cols);
m_CellInfo = tmp_all;
struct sCellInfo c;
c.row=-1;
c.col=-1;
c.valid=false;
c.address=0;
// all cells are valid
for (int i=0; i < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_ROWS; i++) {
for (int j=0; j < FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS; j++) {
c.row = i;
c.col = j;
c.valid = true;
c.address = FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_STEREO_MATRIXMIX_NB_COLS + c.col;
m_CellInfo.at(i).at(j) = c;
}
}
} else if (m_type==eMMT_SaffireMonoMatrixMix) {
m_RowInfo.clear();
addSignalInfo(m_RowInfo, "IN1", "Input 1", "Hardware Inputs 1");
addSignalInfo(m_RowInfo, "IN3", "Input 3", "Hardware Inputs 3");
addSignalInfo(m_RowInfo, "FX1", "Effect return 1", "Effect return 1");
addSignalInfo(m_RowInfo, "IN2", "Input 2", "Hardware Inputs 2");
addSignalInfo(m_RowInfo, "IN4", "Input 4", "Hardware Inputs 4");
addSignalInfo(m_RowInfo, "FX2", "Effect return 2", "Effect return 2");
addSignalInfo(m_RowInfo, "PC910", "PC 9/10", "PC Channel 9/10");
addSignalInfo(m_RowInfo, "PC12", "PC 1/2", "PC Channel 1/2");
addSignalInfo(m_RowInfo, "PC34", "PC 3/4", "PC Channel 3/4");
addSignalInfo(m_RowInfo, "PC56", "PC 5/6", "PC Channel 5/6");
addSignalInfo(m_RowInfo, "PC78", "PC 7/8", "PC Channel 7/8");
m_ColInfo.clear();
addSignalInfo(m_ColInfo, "OUT910", "OUT 9/10", "Output 9/10");
addSignalInfo(m_ColInfo, "OUT12", "OUT 1/2", "Output 1/2");
addSignalInfo(m_ColInfo, "OUT34", "OUT 3/4", "Output 3/4");
addSignalInfo(m_ColInfo, "OUT56", "OUT 5/6", "Output 5/6 (HP1)");
addSignalInfo(m_ColInfo, "OUT78", "OUT 7/8", "Output 7/8 (HP2)");
// init the cell matrix
#define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS 5
#define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS 11
#define FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET 0
std::vector tmp_cols( FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS );
std::vector< std::vector > tmp_all(FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS, tmp_cols);
m_CellInfo = tmp_all;
struct sCellInfo c;
c.row=-1;
c.col=-1;
c.valid=false;
c.address=0;
// all cells are valid
for (int i=0; i < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_ROWS; i++) {
for (int j=0; j < FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS; j++) {
c.row = i;
c.col = j;
c.valid = true;
c.address = FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_OFFSET + c.row * FOCUSRITE_SAFFIRE_MONO_MATRIXMIX_NB_COLS + c.col;
m_CellInfo.at(i).at(j) = c;
}
}
} else if (m_type == eMMT_LEMix48) {
addSignalInfo(m_RowInfo, "IN1", "Input 1", "Analog Input 1");
addSignalInfo(m_RowInfo, "IN2", "Input 2", "Analog Input 2");
addSignalInfo(m_RowInfo, "IN3", "Input 3", "Analog Input 3");
addSignalInfo(m_RowInfo, "IN4", "Input 4", "Analog Input 4");
addSignalInfo(m_RowInfo, "SPDIFL", "SPDIF L", "S/PDIF Left Input");
addSignalInfo(m_RowInfo, "SPDIFR", "SPDIF R", "S/PDIF Right Input");
addSignalInfo(m_RowInfo, "PC1", "PC 1", "PC Channel 1");
addSignalInfo(m_RowInfo, "PC2", "PC 2", "PC Channel 2");
addSignalInfo(m_RowInfo, "PC3", "PC 3", "PC Channel 3");
addSignalInfo(m_RowInfo, "PC4", "PC 4", "PC Channel 4");
addSignalInfo(m_RowInfo, "PC5", "PC 5", "PC Channel 5");
addSignalInfo(m_RowInfo, "PC6", "PC 6", "PC Channel 6");
addSignalInfo(m_RowInfo, "PC7", "PC 7", "PC Channel 7");
addSignalInfo(m_RowInfo, "PC8", "PC 8", "PC Channel 8");
addSignalInfo(m_ColInfo, "OUT1", "OUT 1", "Output 1");
addSignalInfo(m_ColInfo, "OUT2", "OUT 2", "Output 2");
addSignalInfo(m_ColInfo, "OUT3", "OUT 3", "Output 3");
addSignalInfo(m_ColInfo, "OUT4", "OUT 4", "Output 4");
// init the cell matrix
#define FOCUSRITE_SAFFIRELE_48KMIX_NB_COLS 4
#define FOCUSRITE_SAFFIRELE_48KMIX_NB_ROWS 14
std::vector tmp_cols( FOCUSRITE_SAFFIRELE_48KMIX_NB_COLS );
std::vector< std::vector > tmp_all(FOCUSRITE_SAFFIRELE_48KMIX_NB_ROWS,tmp_cols);
m_CellInfo = tmp_all;
struct sCellInfo c;
c.row=-1;
c.col=-1;
c.valid=false;
c.address=0;
for (int i=0;i tmp_cols( FOCUSRITE_SAFFIRELE_96KMIX_NB_COLS );
std::vector< std::vector > tmp_all(FOCUSRITE_SAFFIRELE_96KMIX_NB_ROWS,tmp_cols);
m_CellInfo = tmp_all;
struct sCellInfo c;
c.row=-1;
c.col=-1;
c.valid=false;
c.address=0;
for (int i=0;i